我尝试使用node-forge来解密由另一个应用程序加密的字符串。在解密后,我没有得到原来的字符串,所以我决定把下面的SSCCE放在一起,它加密一个字符串,解密它,然后重新加密它。我得到的结果没有意义。
- 原始字符串:
hi
(十六进制等效值为6869) - 加密的十六进制字符串:
7457
- 解密的十六进制字符串:
2b0a684b
- 重新加密的十六进制字符串:
2e5c6d1dc7cfa554
问题:
1.首先,我做错了什么?即,为什么解密的十六进制不同于原始的十六进制,为什么重新加密的十六进制不同于加密的十六进制?
- node-forge文档中的所有代码示例都得到了十六进制的解密输出。这是怎么回事?我想要返回纯文本,即'hi'。我如何请求库给予文本来代替(调用
decypher.output.toString()
会导致错误)。
1.我的最终目标是能够解密的输出:echo -n "hi" | openssl enc -aes-256-ctr -K $(echo -n redacted12345678 | openssl sha256) -iv 1111111111111111 -a -A -nosalt
使用一个javascript库。任何关于如何做到这一点的建议将非常感谢。
中学会考:
var forge = require('node-forge'); //npm install node-forge
//Inital data
var data = 'hi';
var iv = '1111111111111111';
var password = 'redacted12345678';
var md = forge.md.sha256.create();
md.update(password)
var keyHex = md.digest().toHex();
var key = Buffer.from(keyHex, 'hex').toString()
var cipher = forge.cipher.createCipher('AES-CTR', key);
cipher.start({iv: iv});
cipher.update(forge.util.createBuffer(data));
cipher.finish();
var encrypted = cipher.output.toHex()
console.log("encrypted: " + encrypted) //encrypted: 7457
var decipher = forge.cipher.createDecipher('AES-CTR', key)
decipher.start({iv: iv});
decipher.update(forge.util.createBuffer(encrypted));
decipher.finish();
var decrypted = decipher.output.toHex()
console.log("decrypted: " + decrypted) //decrypted: 2b0a684b
var recipher = forge.cipher.createCipher('AES-CTR', key);
recipher.start({iv: iv});
recipher.update(forge.util.createBuffer(decrypted));
recipher.finish();
var reencrypted = recipher.output.toHex()
console.log("reencrypted: " + reencrypted) //reencrypted: 2e5c6d1dc7cfa554
1条答案
按热度按时间5n0oy7gb1#
我重写了您尝试模仿的OpenSSL命令,如下所示:
我所做的更改是由于以下原因:
openssl sha256
命令生成的十六进制输出以(stdin)=
为前缀(至少在我的发行版上是这样),所以我只是通过xxd
运行了密码的二进制散列,以获得一个干净的十六进制字符串形式的密钥。openssl enc
命令要求IV为十六进制格式,因此我也通过xxd
运行了它。(由于AES IV需要16个字节,因此您的命令将导致IV值为111111111111111100000000000000
,我认为这不是您的目标。)执行此命令将为加密字符串生成以下base64输出:
为了复制相同的代码,我修改了JavaScript代码,如下所示:
生成匹配输出:
从本质上讲,当整个加密/解密操作使用原始字节完成,并且在处理输入或呈现输出时仅从/向十六进制、base64或UTF-8字符串转换时,一切都正常工作。