【问题标题】:getting different results when encoding with python and when encoding with nodejs使用 python 编码和使用 nodejs 编码时得到不同的结果
【发布时间】:2018-05-18 14:20:07
【问题描述】:

我正在尝试使用 python 和 pycrypto 对特定字符串进行编码,并使用 nodejs 和 crypto 对相同的字符串进行编码。 对于相同的输入字符串,我在两种情况下都会得到不同的结果

python 代码:

from Crypto.Cipher import AES
from hashlib import md5
import base64


password = 'aquickbrownfoxjumpsoverthelazydog'
input = 'hello+world'

BLOCK_SIZE = 16

def pad (data):
    pad = BLOCK_SIZE - len(data) % BLOCK_SIZE
    return data + pad * chr(pad)

def unpad (padded):
    pad = ord(padded[-1])
    return padded[:-pad]

def text_encrypt(data, nonce, password):
    m = md5()
    m.update(password)
    key = m.hexdigest()
    m = md5()
    m.update(password + key)
    iv = m.hexdigest()

    data = pad(data)

    aes = AES.new(key, AES.MODE_CBC, iv[:16])

    encrypted = aes.encrypt(data)
    return base64.urlsafe_b64encode(encrypted)

output = text_encrypt(input, "", password)
print output

nodejs代码如下:

var crypto = require('crypto');

var password = 'aquickbrownfoxjumpsoverthelazydog';
var input = 'hello+world';

var encrypt = function (input, password, callback) {
    var m = crypto.createHash('md5');
    m.update(password)
    var key = m.digest('hex');

    m = crypto.createHash('md5');
    m.update(password + key)
    var iv = m.digest('hex');

    var data = new Buffer(input, 'utf8').toString('binary');

    var cipher = crypto.createCipheriv('aes-256-cbc', key, iv.slice(0,16));

    var nodev = process.version.match(/^v(\d+)\.(\d+)/);
    var encrypted;

    if( nodev[1] === '0' && parseInt(nodev[2]) < 10) {
        encrypted = cipher.update(data, 'binary') + cipher.final('binary');
    } else {
        encrypted = cipher.update(data, 'utf8', 'binary') + cipher.final('binary');
    }

    var encoded = new Buffer(encrypted, 'binary').toString('base64');

    callback(encoded);
};

encrypt(input, password, function (encoded) {
    console.log(encoded);
});

这两种情况的结果不同,但解密后它们都倾向于给出相同的正确结果。

这可能是什么问题?

【问题讨论】:

  • 如果您没有得到答案,我将有一段时间来查看您的问题,但乍一看建议 - 使用非随机 IV 是 非常非常坏主意。密钥应基于您的密码,IV 应始终是加密随机数。您可以在this answer 中看到一个演示如何执行它的 Python 示例。
  • 1.使用随机 IV,为了使其可用于解密,只需在加密数据前加上 iv,IV 不需要保密。 2. MD5 不是从密码派生加密密钥的安全方法,使用 PBKDF2(又名 Rfc2898DeriveBytes)、Argon2 或类似的密码派生函数,应该有一个迭代计数,使得派生需要大约 100 毫秒或 CPU 时间..

标签: python node.js pycrypto cryptojs


【解决方案1】:

你没有具体说明你得到了什么不同的结果,但是这两个应该产生相同的结果。我看到的唯一区别是您使用的 base64 字母表。

在 Python 中,您调用 base64.urlsafe_b64encode()standard Base64 的不同之处在于它用于 6263 的值的字符(-_ 而不是 + 和 @987654330 @)。为了得到同样的结果,要么在 Python 中返回:

return base64.b64encode(encrypted)

或者在 Node.js 中对 base64 编码的字符串进行后处理:

encoded = encoded.replace(/_/g, '/').replace(/-/g, '+');

所有这一切,正如我在评论中提到的那样,永远不要从您的密码/密钥(或任何其他确定性和不变的东西)派生 IV。使用cryptographically secure PRNG

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    • 1970-01-01
    • 2018-08-01
    相关资源
    最近更新 更多