AES-加密加密加密(node-js)/解密Pycrypto(python)



我写这个问答是因为我很挣扎(可能是因为缺乏经验),在使用node或python加密/解密事物的许多不同方式中迷失了方向。

我想也许我的案子将来能帮助到人们。

我需要做的:

  • 从表单中获取数据,使用Crypto(node-js)对其进行加密
  • 在Python中传递加密数据,并使用PyCrypto对其进行解密

我选择使用AES加密。

以下是我开始的方式(我不会经历我尝试过的一切):

  • 我遵循了本页末尾的示例

    在我的案例中:

    (这可能是javascript和coffeescript之间非常糟糕的混合)

    crypto = require "crypto"
    [...]
    key = "mykeywhatever"
    cipher = crypto.createCipher('aes192', key)
    cipher.update('string i want to encode', 'binary', 'hex')
    encoded_string = cipher.final('hex')
    [...]
    

    这对我的字符串进行编码非常有效。

  • 然后,我编写了python脚本来解密这个字符串,使用PyCrypto的github页面上的自述文件:

    from Crypto.Cipher import AES
    [...]
    my_string = data_coming_from_rabbitmq
    obj = AES.new('mykeywhatever', AES.MODE_CBC)
    obj.decrypt(ciphertext)
    [...]
    

    这显然不起作用:在自述中有一个IV,但既然我在节点脚本中没有给出,为什么我要在python中给出呢?

经过更多的谷歌搜索,我了解到节点的Crypto使用OpenSSL,而PyCrypto显然没有。所以我查了一下,发现了那些页面:

  • 如何使用PyCrypto解密使用OpenSSL加密的内容
  • AES在PyCrypto&Node.JS加密
  • 还有更多

所以事情变得复杂了,没有人做同样的事情来解密数据,我迷路了,请求帮助。

答案是我和我的同事想出的(嗯,主要是我的同事)。

所以我们从"如何解密…OpenSSL"的答案开始。

  • 我们需要修改加密脚本,它给出:

    crypto = require "crypto"
    [...]
    var iv = new Buffer('asdfasdfasdfasdf')
    var key = new Buffer('asdfasdfasdfasdfasdfasdfasdfasdf')
    var cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
    cipher.update(new Buffer("mystring"));
    var enc = cipher.final('base64');
    [...]
    

    iv需要16字节长,密钥为32字节。我们将createCipher更改为createCipheriv

  • 回到python解密脚本:

    这个过程只是简单地阅读PyCrypto的文档,并与我们开始的代码进行比较。

    然后我们决定只坚持API,从头开始。它给出了:

    from base64 import b64decode
    from Crypto.Cipher import AES
    [...]
    iv = 'asdfasdfasdfasdf'
    key = 'asdfasdfasdfasdfasdfasdfasdfasdf'
    encoded = b64decode('my_encrypted_string')
    dec = AES.new(key=key, mode=AES.MODE_CBC, IV=iv)
    value = dec.decrypt(encoded)
    

就这么简单。。。希望它能帮助你们中的一些人!

更新:

正如英仙座在回答的评论中所写的那样,IV必须是随机的,并且对于每个消息都不同。

您正在构建的系统可能不安全

除了存储之外,您基本上不想只加密数据,也不想对其进行身份验证。在这种情况下,身份验证意味着只有知道密钥的人才能生成有效消息。一种广泛使用的身份验证方案是HMAC。

如果您不验证您的消息,任何人都可以将数据输入您的服务。攻击者可能无法完全控制解密后的结果,但他/她可能仍然非常危险。例如,如果您使用CBC(您这样做)和最常见的填充方案(AES是一种分组密码,只能加密128位的数据块),并且攻击者可以区分填充错误和任何其他错误,则所有消息都可以被攻击者解密。这被称为填充预言机攻击,太常见了。

为了防止此类攻击,您可以使用身份验证加密方案,例如GCM块密码模式。

此外,您还必须防范重播攻击。考虑一个银行应用程序,您传输的数据是银行转账单。除非有任何TAN,攻击者可能会记录以前的交易,并一次又一次地将此交易重播给您的服务,从而转移客户最初想要的金额的倍数。

您从中获取数据的表单是否通过HTTPS传输?如果不是:密钥会被攻击者窃听吗?用户怎么知道他是从你而不是其他人那里得到表单的(SSL/TLS既是关于身份验证的,也是关于机密性的)。

我可能忘记了CBC加密提供的其他一些攻击向量。

备选方案

防范这些攻击的最简单方法可能是通过HTTPS传输表单数据。SSL/TLS旨在防止所有上述攻击,客户端和服务器端的实现需要很长时间才能成熟。

相关内容

  • 没有找到相关文章

最新更新