记一次node AES ECB解密与python解密不一致的问题

问题描述

最近发现一些node项目使用原生crypto模块加密的数据不能通过python正常解密:

const crypto = require("crypto");

function encrypt(data) {
	key = 'mysecretmysecret';
	var cipher = crypto.createCipher('aes-128-ecb', key);
	var ret = cipher.update(data, "utf8", "base64");
	ret += cipher.final("base64");
	return ret;
}
console.log(encrypt('testdata'))
// g7qc8vUMyOAmkRj2dwvCGA==

import base64
from Crypto.Cipher import AES

def decrypt(data):
    data = base64.b64decode(data)
    key = 'mysecretmysecret'
    cipher = AES.new(key.encode(), AES.MODE_ECB)
    res = cipher.decrypt(data)
    return res

print(decrypt('g7qc8vUMyOAmkRj2dwvCGA=='))
# b"!w\xd2\x04Q\x04\x84\xe9\x82\x03\x95?'\xd7\xf6\x8b"

python 解密数据完全不一样


原因分析:

经过Google大法发现,node现在 createCipher 已经被弃用,推荐使用createCipheriv

并且createCipher中使用的secret并不是AES加密所使用的key

真正的key是用openSSL的方法EVP_BytesToKey,通过MD5,并且不需要加盐生成的密匙


解决方案:

知道是什么问题就好解决了,在网上找到了EVP_BytesToKey的python实现:

def EVP_BytesToKey(key_length, iv_length, md, salt, data, count=1):
    """
    Usage:
        key, iv = EVP_BytesToKey(
            32,  # 256 bits
            Crypto.Cipher.AES.block_size,
            hashlib.sha256,
            salt,
            password.encode('utf-8'),
            )
    See:
        https://github.com/openssl/openssl/blob/6f0ac0e2f27d9240516edb9a23b7863e7ad02898/crypto/evp/evp_key.c#L74
    """
    assert data
    assert salt == b'' or len(salt) == 8

    md_buf = b''
    key = b''
    iv = b''
    # key_length = 32  # type.key_size
    # iv_length = type.block_size

    addmd = 0

    while key_length > len(key) or iv_length > len(iv):
        c = md()
        if addmd:
            c.update(md_buf)
        addmd += 1
        c.update(data)
        c.update(salt)
        md_buf = c.digest()
        for i in range(1, count):
            md_buf = md(md_buf)

        md_buf2 = md_buf

        if key_length > len(key):
            key, md_buf2 = key + md_buf2[:key_length - len(key)], md_buf2[key_length - len(key):]

        if iv_length > len(iv):
            iv, md_buf2 = iv + md_buf2[:iv_length - len(iv)], md_buf2[iv_length - len(iv):]

    return key, iv

使用方式:

secret = 'mysecretmysecret'
key, iv = EVP_BytesToKey(16, 16, hashlib.md5, b'', secret, 1)

这里的key才是AES所需要的真正的key

以上

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值