我有一个用例,其中我们使用一个简单的NodeJS应用程序将日志数据流式传输到文件中。我们希望能够在对数据进行流式传输时对其进行加密,然后在以后根据需要使用OpenSSL或类似方法对其进行解密。
我们正在做的基本上如下:
var crypto = require('crypto'),
algorithm = 'aes256',
password = 'password';
var fs = require('fs');
var Readable = require('stream').Readable
var r = new Readable
r.push('This is a test')
r.push(null)
var encrypt = crypto.createCipher(algorithm, password);
var decrypt = crypto.createDecipher(algorithm, password)
var w = fs.createWriteStream('file.out');
//Write encrypted stream to file. Decrypt with openssl fails with 'bad magic number'
r.pipe(encrypt).pipe(w)
//Decrypt using cipher library. Decrypted text displays as expected
//r.pipe(encrypt).pipe(decrypt).pipe(w)
假设我们在读取数据时只是对数据进行加密,我假设我们可以使用开放的OpenSSL对其进行解密,例如。
openssl enc -d -aes256 -in file.out -out file.out.decrypted
但这只是给我错误
Bad magic number
任何帮助将不胜感激。
答案 0 :(得分:2)
在查看crypto.createCipher()
函数的文档时,它提到像EVP_BytesToKey()应用一样,OpenSSL openssl enc
函数用于从密码短语中获取密钥。这样看来是兼容的。
但是,同一文档没有提到应用了任何盐,并且该函数似乎也不可能将盐作为参数传递。因此,您必须将-nosalt
选项传递给openssl enc
才能使其正常工作,如下所示:
openssl enc -d -aes256 -nosalt -in file.out -out file.out.decrypted
您可以仅使用openssl enc
工具来模拟正在发生的事情,而不必担心解密端会出现问题:
您当前的情况:
$ echo -n 'This is a test' | openssl enc -aes256 -nosalt -pass pass:password | openssl enc -d -aes256 -pass pass:password
bad magic number
解密时添加-nosalt
:
$ echo -n 'This is a test' | openssl enc -aes256 -nosalt -pass pass:password | openssl enc -d -aes256 -nosalt -pass pass:password
This is a test
答案 1 :(得分:1)
默认情况下,OpenSSL加密的文件格式以8字节的“幻数”开头,即"Salted__"
的US-ASCII编码。接下来是另一个8字节的值,该值用密码进行哈希处理以得出消息的加密密钥和IV。您的NodeJS代码不是以相同的方式派生密钥或提供必要的标头,因此将无法正常工作。
OpenSSL的密钥派生算法不安全且不标准。如果您使用PBKDF2之类的 good 密钥派生算法从密码中派生密钥(或者更好的是,随机选择一个密钥),则可以将其(以十六进制编码)提供给{{1使用enc
选项的}}命令,以及使用-K
选项的IV。我没有检查您是否还需要-iv
选项来避免在这种情况下对魔术数字的抱怨。