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。 我们改变了
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)
就这么简单…希望它能帮助你们中的一些人!
更新:
正如英国诗人在回答他的评论中所写的那样,每一条信息都必须是随机的,不同的
您正在构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旨在防止上述所有攻击,客户端和服务器端实现还有很长时间才能成熟。