AES – 使用Crypto(node-js)encryption/使用Pycrypto(python)解密

我正在写这个问题+答案,因为我挣扎了很多(也许是因为缺乏经验),迷失在许多不同的方式使用节点或pythonencryption/解密的东西。

我想也许我的案子可以帮助未来的人。

我需要做的是:

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

我select使用AESencryption。

这是我的开始(我不会经历我试过的一切):

  • 我跟着这个页面末尾的例子

    在我的情况下给了:

    (这可能是一个非常糟糕的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') [...] 

    这工作得很好编码我的string。

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

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

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

经过更多的search,我知道节点的Crypto使用OpenSSL,而PyCrypto显然没有。 所以我看了看,发现这些页面:

  • 我怎样才能解密使用OpenSSLencryption的PyCrypto?
  • 在PyCrypto&Node.JS Crypto库中,AES是相同的
  • 还有更多…

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

答案是我和我的同事提出的(主要是我的主pipe)。

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

  • 我们需要修改给出的encryption脚本:

     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需要长16bytes, 关键是32bytes。 我们改变了createCiphercreateCipheriv

  • 回到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) 

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

更新:

正如英国诗人在回答他的评论中所写的那样,每一条信息都必须是随机的,不同的

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

除了存储你基本上不希望只encryption你的数据,但也authentication它。 在这种情况下的authentication意味着有效的消息只能由知道密钥的人生成。 一种广泛使用的authenticationscheme是HMAC 。

如果您不authentication您的消息,任何人都可以将数据提供给您的服务。 攻击者可能无法完全控制解密后的结果,但他/她可能仍然是非常危险的。 例如,如果你使用CBC(你这样做)和最常见的填充scheme(AES是分组密码,只能encryption128位数据块),攻击者可以区分填充错误和任何其他错误,那么所有的消息可以被攻击者解密 。 这被称为填充甲骨文攻击 ,太常见了。

为了防止此类攻击,您可以使用经过身份validation的encryptionscheme ,例如GCM块密码模式。

你也必须防止重播攻击 。 考虑一个银行应用程序,您传输的数据是银行转账订单。 除非任何TAN攻击者可能会logging以前的交易,并重复这个交易到您的服务一次又一次,从而转移客户原本想要的多个钱。

您是通过HTTPS传输数据的表单吗? 如果不是的话:密钥可以被攻击者窃听吗? 用户如何知道他是从你而不是其他人那里获得表格(SSL / TLS与authentication有关,因为它涉及机密性)。

可能我忘记了一些简单的CBCencryption提供的其他攻击媒介。

备择scheme

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