I'm trying to use node.js' crypt module to decrypt some files that were encrypted by another program that used the openssl library in a rather non-standard library. By non-standard I mean that the number of rounds and location of the salt differs from the defaults used by openssl. So as a result I am extracting the salt first and then creating a ReadStream on the resulting description before trying to do that actual decryption.
I have two routines. The first one uses decrypt.update
and decrypt.final
to perform the decryption. I am able to decrypt files this way. The second uses pipe
to perform the decryption. When I try to use it I get this error:
The error I get when I try to run my code is:
digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
The working and failing function are below. The "binary_concat" function referenced does the equivalent of a+b
for binary strings - it took me a couple hours of debugging before I discovered that a+b
doesn't work properly!
function do_decrypt_works(infile,password,salt) {
var outfile = fs.createWriteStream("/tmp/test.out")
var text = fs.readFileSync(infile_filename).slice(8) // hack since we aren't using infile in this case
var rounds = 28
data00 = binary_concat(password,salt,"")
var hash1 = do_rounds(data00)
var hash1a = binary_concat(hash1,password,salt)
var hash2 = do_rounds(hash1a,password,salt)
var hash2a = binary_concat(hash2,password,salt)
var hash3 = do_rounds(hash2a,password,salt)
var key = binary_concat(hash1,hash2,"")
var iv = hash3
var decrypt = crypto.createDecipheriv('aes-256-cbc', key, iv)
var content = decrypt.update(text, "binary", "binary");
content += decrypt.final("binary");
}
function do_decrypt_fails(infile,password,salt) {
var outfile = fs.createWriteStream("/tmp/test.out")
var rounds = 28
data00 = binary_concat(password,salt,"")
var hash1 = do_rounds(data00)
var hash1a = binary_concat(hash1,password,salt)
var hash2 = do_rounds(hash1a,password,salt)
var hash2a = binary_concat(hash2,password,salt)
var hash3 = do_rounds(hash2a,password,salt)
var key = binary_concat(hash1,hash2,"")
var iv = hash3
var decrypt = crypto.createDecipheriv('aes-256-cbc', key, iv)
infile.pipe(decrypt).pipe(outfile)
}
According to the documentation, both createDecipher
and createDecipheriv
return an instance of class Decipher
which can be used with either of the above techniques.
Sources: