在浏览器/CryptoJS中解密openssl AES 256 CBC [英] Decrypt openssl AES 256 CBC in browser/CryptoJS

查看:257
本文介绍了在浏览器/CryptoJS中解密openssl AES 256 CBC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在服务器上解密已用openssl加密的字符串,如下所示:

I want to decrypt a string that has been encrypted with openssl on the server like this:

openssl enc -e -aes-256-cbc -pbkdf2 -a -S 0123456789ABCDEF -A -k mypassword

请注意,仅提供盐和密码即可完成此操作,openssl应该自动处理密钥和IV.如果浏览器也解密,是否会发生这种情况,我是否太乐观了?如果可能的话,我只想使用那些加密设置或增加复杂性的最低限度来做到这一点.在浏览器中,我正在尝试使用CryptoJS解密,如下所示:

Note this is done providing only a salt and password, and openssl should handle key and IV automatically. Am I too optimistic that this can happen when the browser decrypts too? If at all possible, I want to do it with only those encryption settings, or the bare minimum of increased complexity. In the browser, I'm trying to decrypt with CryptoJS like this:

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 的调用带有错误,无法读取未定义的属性'0' crypto-js/cipher-core.js:371 .CryptoJS.AES.decrypt的文档非常薄,调用该函数时我知道要更改的任何设置似乎都给出了相同的错误.感谢任何可以发光的人!

But the call to CryptoJS.AES.decrypt errors with Cannot read property '0' of undefined, crypto-js/cipher-core.js:371. The docs for CryptoJS.AES.decrypt are quite thin, and any settings I am aware of to change when calling that func seem to give the same error. Thanks to anyone who can shine light!

推荐答案

在OpenSSL语句中,未指定迭代计数和摘要,因此使用默认值 10000 和SHA256.这很重要,因为 CryptoJS 使用不同的默认值( 1 和SHA1).

In the OpenSSL statement, the iteration count and digest are not specified, so the default values 10000 and SHA256 are used. This is relevant because CryptoJS uses different default values (1 and SHA1).

CryptoJS 对密文应用 OpenSSL 格式,即,加密的数据以 Salted __ 的ASCII编码开头,然后是盐,然后是密文.因此,Base64编码密文的开头始终以 U2FsdGVkX1 开始.

CryptoJS applies the OpenSSL format for the ciphertext, i.e. the encrypted data starts with the ASCII encoding of Salted__ followed by the salt and then the ciphertext. Therefore the beginning of the Base64 encoded ciphertext starts always with U2FsdGVkX1.

CryptoJS 使用 WordArray 数据类型,该数据类型封装了单词数组.一个单词由4个字节组成.

CryptoJS uses the WordArray data type, which encapsulates an array of words. A word consists of 4 bytes.

在解密过程中,必须首先将密文和盐分开.然后,必须使用PBKDF2确定密钥和IV.由于默认值不同,因此必须明确指定迭代计数和摘要.最终可以将其解密:

During decryption, ciphertext and salt must first be separated. Then, key and IV must be determined using PBKDF2. Due to the different default values, iteration count and digest must be specified explicitly. Finally it can be decrypted:

// 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文档中找到.

这篇关于在浏览器/CryptoJS中解密openssl AES 256 CBC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆