使用openssl从加密模块解密文件

时间:2018-07-17 15:59:06

标签: node.js openssl cryptography cryptojs

我有一个用例,其中我们使用一个简单的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

任何帮助将不胜感激。

2 个答案:

答案 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选项来避免在这种情况下对魔术数字的抱怨。