在 browser/CryptoJS 中解密 openssl AES 256 CBC
Decrypt openssl AES 256 CBC in browser/CryptoJS
我想在服务器上解密一个用openssl加密过的字符串,像这样:
openssl enc -e -aes-256-cbc -pbkdf2 -a -S 0123456789ABCDEF -A -k mypassword
请注意,这仅提供盐和密码即可完成,openssl 应自动处理密钥和 IV。当浏览器解密时也会发生这种情况,我是不是太乐观了?如果可能的话,我想只使用那些加密设置,或者增加复杂性的最低限度。在浏览器中,我正在尝试像这样使用 CryptoJS 解密:
import * as CryptoJS from 'crypto-js'
const encrypted = <ENCRYPTED_STRING_FROM_SERVER>
const password = 'mypassword'
const salt = '0123456789ABCDEF'
const key = CryptoJS.PBKDF2(password, salt) // Generate key
const bytes = CryptoJS.AES.decrypt(encrypted, key)
const decrypted = bytes.toString(CryptoJS.enc.Utf8)
console.log(decrypted)
但是 CryptoJS.AES.decrypt
的调用错误 Cannot read property '0' of undefined
、crypto-js/cipher-core.js:371
。 CryptoJS.AES.decrypt 的文档非常薄,我知道在调用该 func 时更改的任何设置似乎都会出现相同的错误。感谢任何能发光的人!
OpenSSL语句中没有指定迭代次数和摘要,所以使用默认值10000
和SHA256。这是相关的,因为 CryptoJS 使用不同的默认值(1
和 SHA1)。
CryptoJS对密文应用OpenSSL格式,即加密数据以Salted__
的ASCII编码开头,后跟通过盐然后是密文。因此Base64编码密文的开头总是以U2FsdGVkX1
.
开头
CryptoJS 使用 WordArray
数据类型,它封装了一个单词数组。一个字由4个字节组成。
解密时,首先要将密文和salt分开。然后,必须使用 PBKDF2 确定密钥和 IV。由于默认值不同,必须明确指定迭代次数和摘要。终于可以解密了:
// 1. Separate ciphertext and salt
var encrypted = "U2FsdGVkX18BI0VniavN78vlhR6fryIan0VvUrdIr+YeLkDYhO2xyA+/oVXJj/c35swVVkCqHPh9VdRbNQG6NQ=="
var encryptedWA = CryptoJS.enc.Base64.parse(encrypted);
var prefixWA = CryptoJS.lib.WordArray.create(encryptedWA.words.slice(0, 8/4)); // Salted__ prefix
var saltWA = CryptoJS.lib.WordArray.create(encryptedWA.words.slice(8/4, 16/4)); // 8 bytes salt: 0x0123456789ABCDEF
var ciphertextWA = CryptoJS.lib.WordArray.create(encryptedWA.words.slice(16/4, encryptedWA.words.length)); // ciphertext
// 2. Determine key and IV using PBKDF2
var password = 'mypassword'
var keyIvWA = CryptoJS.PBKDF2(
password,
saltWA,
{
keySize: (32+16)/4, // key and IV
iterations: 10000,
hasher: CryptoJS.algo.SHA256
}
);
var keyWA = CryptoJS.lib.WordArray.create(keyIvWA.words.slice(0, 32/4));
var ivWA = CryptoJS.lib.WordArray.create(keyIvWA.words.slice(32/4, (32+16)/4));
// 3. Decrypt
var decryptedWA = CryptoJS.AES.decrypt(
{ciphertext: ciphertextWA},
keyWA,
{iv: ivWA}
);
var decrypted = decryptedWA.toString(CryptoJS.enc.Utf8)
console.log(decrypted)
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
可以在 CryptoJS documentation 中找到更多详细信息。
在浏览器中试试这个库
https://www.npmjs.com/package/cryptojs2
可以在文档中找到更多详细信息。
我想在服务器上解密一个用openssl加密过的字符串,像这样:
openssl enc -e -aes-256-cbc -pbkdf2 -a -S 0123456789ABCDEF -A -k mypassword
请注意,这仅提供盐和密码即可完成,openssl 应自动处理密钥和 IV。当浏览器解密时也会发生这种情况,我是不是太乐观了?如果可能的话,我想只使用那些加密设置,或者增加复杂性的最低限度。在浏览器中,我正在尝试像这样使用 CryptoJS 解密:
import * as CryptoJS from 'crypto-js'
const encrypted = <ENCRYPTED_STRING_FROM_SERVER>
const password = 'mypassword'
const salt = '0123456789ABCDEF'
const key = CryptoJS.PBKDF2(password, salt) // Generate key
const bytes = CryptoJS.AES.decrypt(encrypted, key)
const decrypted = bytes.toString(CryptoJS.enc.Utf8)
console.log(decrypted)
但是 CryptoJS.AES.decrypt
的调用错误 Cannot read property '0' of undefined
、crypto-js/cipher-core.js:371
。 CryptoJS.AES.decrypt 的文档非常薄,我知道在调用该 func 时更改的任何设置似乎都会出现相同的错误。感谢任何能发光的人!
OpenSSL语句中没有指定迭代次数和摘要,所以使用默认值10000
和SHA256。这是相关的,因为 CryptoJS 使用不同的默认值(1
和 SHA1)。
CryptoJS对密文应用OpenSSL格式,即加密数据以Salted__
的ASCII编码开头,后跟通过盐然后是密文。因此Base64编码密文的开头总是以U2FsdGVkX1
.
CryptoJS 使用 WordArray
数据类型,它封装了一个单词数组。一个字由4个字节组成。
解密时,首先要将密文和salt分开。然后,必须使用 PBKDF2 确定密钥和 IV。由于默认值不同,必须明确指定迭代次数和摘要。终于可以解密了:
// 1. Separate ciphertext and salt
var encrypted = "U2FsdGVkX18BI0VniavN78vlhR6fryIan0VvUrdIr+YeLkDYhO2xyA+/oVXJj/c35swVVkCqHPh9VdRbNQG6NQ=="
var encryptedWA = CryptoJS.enc.Base64.parse(encrypted);
var prefixWA = CryptoJS.lib.WordArray.create(encryptedWA.words.slice(0, 8/4)); // Salted__ prefix
var saltWA = CryptoJS.lib.WordArray.create(encryptedWA.words.slice(8/4, 16/4)); // 8 bytes salt: 0x0123456789ABCDEF
var ciphertextWA = CryptoJS.lib.WordArray.create(encryptedWA.words.slice(16/4, encryptedWA.words.length)); // ciphertext
// 2. Determine key and IV using PBKDF2
var password = 'mypassword'
var keyIvWA = CryptoJS.PBKDF2(
password,
saltWA,
{
keySize: (32+16)/4, // key and IV
iterations: 10000,
hasher: CryptoJS.algo.SHA256
}
);
var keyWA = CryptoJS.lib.WordArray.create(keyIvWA.words.slice(0, 32/4));
var ivWA = CryptoJS.lib.WordArray.create(keyIvWA.words.slice(32/4, (32+16)/4));
// 3. Decrypt
var decryptedWA = CryptoJS.AES.decrypt(
{ciphertext: ciphertextWA},
keyWA,
{iv: ivWA}
);
var decrypted = decryptedWA.toString(CryptoJS.enc.Utf8)
console.log(decrypted)
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
可以在 CryptoJS documentation 中找到更多详细信息。
在浏览器中试试这个库 https://www.npmjs.com/package/cryptojs2 可以在文档中找到更多详细信息。