Reputation: 8541
I want to crypt an input stream and send it to another server via TCP. So far so good. Everything runs smoothly, until the connection is closed. In almost any case the needed block size of 192 bits is not met and the script crashes with wrong final block length
, although I turned auto padding on.
It seems like auto padding only works, when using the legacy interface. Am I doing something wrong here?
var net = require("net")
, crypto = require("crypto");
var credentials = { algorithm: "aes192", password: "password" }
, decipher = crypto.createDecipher(credentials.algorithm, credentials.password)
, cipher = crypto.createCipher(credentials.algorithm, credentials.password);
decipher.setAutoPadding(true);
cipher.setAutoPadding(true);
net.createServer(function(socket) {
socket.pipe(socket);
}).listen(2000);
var socket = net.connect(2000);
socket.pipe(decipher).pipe(process.stdout);
process.stdin.pipe(cipher).pipe(socket);
socket.write("Too short.");
socket.end();
In my ideal Node.js world, the (De-)Cipher Stream would automatically pad the last block, when the source stream is closed. I think this is a design flaw.
Apart from opening an issue, how can I circumvent this behaviour? Do I have to put a byte counter between Socket and (De-)Cipher Streams?
Upvotes: 10
Views: 2728
Reputation: 10171
You have set your pipes like this :
stdin | cipher | socket (loopback) | decipher | stdout
But you bypass the encryption by writing directly to the socket, using them like this :
socket (loopback) | decipher | stdout
Try with this code :
var net = require("net")
, crypto = require("crypto");
var credentials = { algorithm: "aes192", password: "password" }
, decipher = crypto.createDecipher(credentials.algorithm, credentials.password)
, cipher = crypto.createCipher(credentials.algorithm, credentials.password);
decipher.setAutoPadding(false); //set to false to keep the padding
cipher.setAutoPadding(true);
//Loopback
server = net.createServer(function(socket) {
socket.pipe(socket);
})
server.listen(2000);
var socket = net.connect(2000);
//cipher to the loopback socket, to decipher and stdout
cipher.pipe(socket).pipe(decipher).pipe(process.stdout);
//write some data
cipher.write("Too short.");
//Clean exit
cipher.end();
server.unref();
For the purpose of demonstration, I removed auto padding from the Decryptor
object so you can see the leftover padding. Piping the program in xxd (at the command line, not in node) gives me this ouput :
$ nodejs so.js | xxd
0000000: 546f 6f20 7368 6f72 742e 0606 0606 0606 Too short.......
With the 0x06
repeated 6 times.
Upvotes: 2