Skip to content
Advertisement

How to reuse the same crypto.Cipheriv instance in Pino transport transform buffer?

I’m using Pino. I’m trying to encrypt the log stream and write it to a file. One way I can achieve this is creating a pipeline where I can transform the data and encrypt its contents, like so (works fine):

JavaScript

How can I reuse the same const encrypt = crypto.createCipheriv(ALGORITHM, password, iv); instance, so not to create a new one every time? Do I gain some performance by doing this refactoring?

I tried this:

JavaScript

But I get:

JavaScript

No worries about micro-optimization, but if you can and want to point out/raise arguments, feel free to do so.

I’m using fastify’s Pino configuration, which is basically the same configuration from vanilla Pino package:

JavaScript

Advertisement

Answer

How can I reuse the same const encrypt = crypto.createCipheriv(ALGORITHM, password, iv); instance, so not to create a new one every time?

You can and should not. As you need to indicate the IV it should be clear that the function is not made for reuse, as the IV should be different for each message.

JavaScript

This is most certainly wrong. You could get away with this for CBC mode, but in CTR mode each bit/byte of plaintext is XOR’ed with the internally created key stream. So each bit/byte of plaintext / ciphertext is fully independent. This means that a prefixed IV won’t do anything when it comes to the generated ciphertext for the chunk.

Do I gain some performance by doing this refactoring?

No, that’s unlikely and unlikely to be worth the effort.

It may increase performance slightly as there is – theoretically – no second subkey derivation for AES. That is however a very lightweight operation. It could also reuse some buffers, but AES doesn’t require large buffers either.

The IV needs to be unique and therefore you should create a fresh one each run of the created cipher instance. It may be more performant for e.g. CTR mode to use some kind of sequence number instead of a random. Beware though that any collision will almost completely destroy any confidentiality that you want to achieve.

I’d strongly advice you to only retain the key between operations.

You can store a large synchronized counter as well to act as a nonce, but beware that keeping such a counter synced is quite a tricky problem. As such a nonce is generally part of a protocol, e.g. a message counter, it would still be better to supply the IV when starting encryption, i.e. as a parameter rather than a field.

All this is unnecessary for a random IV, which can simply be included with – e.g. prefixed to – the ciphertext and extracted before decryption.

Advertisement