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?
Instead of the process being blocked and waiting for I/O operations to complete, the I/O operations are delegated to the system, so that the process can execute the next piece of code. Non-blocking I/O operations provide a callback function that is called when the operation is completed.
It is an infinite while loop, calling Epoll (kqueue) “wait” or “pool”, when something interesting (callback, event, fs) happens for a Node. js; it routs that to Node. js, and exits when there is nothing to wait in Epoll. That is how asynchronous things work in Node.
js can handle multiple concurrent requests easily and why it becomes an obvious choice for the development of such applications. Node. js works asynchronously. In other words, it does not block incoming requests from clients when the operating system has one I/O intensive request.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With