当前位置: 首页 > 知识库问答 >
问题:

AES-加密(节点js)/解密(python)

松烨烨
2023-03-14

我写这个问题的答案是因为我挣扎了很多(可能是因为缺乏经验),迷失在许多不同的加密/解密节点或Python的方法中。

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

我需要做的是:

  • 从表单中获取数据,使用加密(node js)对其进行加密。

我选择使用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中给出一个?

    在更多的谷歌搜索之后,我了解到node的Crypto使用OpenSSL,而PyCrypto显然不使用OpenSSL。所以我研究了一下,找到了那些页面:

    • 我如何用PyCrypto解密使用OpenSSL加密的东西?
    • 是AES相同的库PyCrypto

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

    答案是我的同事和我想出的(嗯,大部分是我的同事)。

  • 共有2个答案

    令狐昌胤
    2023-03-14

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

    如果您没有对消息进行身份验证,任何人都可以向您的服务提供数据。解密后,攻击者可能无法完全控制结果,但他/她可能仍然非常危险。例如,如果您使用CBC(确实如此)和最常见的填充方案(AES是一种分组密码,只能加密128位数据块),并且攻击者可以区分填充错误和任何其他错误,则攻击者可以解密您的所有消息。这被称为填充oracle攻击,这种攻击太常见了。

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

    此外,您还必须防止重播攻击。考虑银行应用程序,您发送的数据是银行转账订单。除非出现任何TAN,否则攻击者可能会记录以前的交易,并将此交易一次又一次地重播到您的服务中,从而转移客户最初想要的金额的倍数。

    您从中获取数据的表单是否通过HTTPS传输?如果没有:密钥是否可以被攻击者窃听?用户如何知道他是从您而不是其他任何人那里得到表单的(SSL/TLS与身份验证和保密性一样重要)。

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

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

    蒙化
    2023-03-14

    所以我们从“如何解密……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字节。我们将createCipheriv更改为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必须是随机的,并且对于每一条信息都是不同的

  •  类似资料:
    • 我已经看过了AES-Encryption with Crypto(node js)/decryption with Pycrypto(python)的文章,因为我正试图做完全相反的事情,但我似乎做得不对。这是我到目前为止试过的。。。 Python加密 节点。js解密 每次我尝试运行节点时。js解密,我最终得到错误消息:

    • 我试图在节点之间建立加密通信。js和NodeMCU。经过一些努力,我能够使用node加密。js并在NodeMCU上解密。反之亦然。mscdex的答复有效。因此,我修改了节点。为了他人的利益而编写js代码。谢谢 NodeMCU代码: 节点。js工作代码: 现在再次进行NodeMCU侧测试: 什么在起作用? 节点。js加密在NodeMCU上被解密,尽管加密的字符串有点不同。 什么不起作用? NodeM

    • 我试图在Android和PHP端使用AES加密/解密数据,并累犯空答案。 首先,我在Android中生成了对称密钥: 在服务器端,我试图解密数据。我可以解密(从RSA)秘密的AES密钥,并得到它的字符串表示。在客户端(Android)和服务器端(PHP)上是一样的。但是如何使用这个字符串AES密钥来解密数据呢?我尝试了这个(PHP): PHP中的结果: 怎么啦?

    • 问题内容: 我迅速编写了一个应用程序,我需要AES加密和解密功能,我从另一个.Net解决方案中接收了加密数据,但是我找不到解决办法。 这是我的.net加密: 我需要迅速解密功能。 问题答案: 我找到了解决方案,它是一个很好的库。 跨平台256位AES加密/解密。 此项目包含在所有平台(C#,iOS,Android)上均可使用的256位AES加密的实现。关键目标之一是通过简单的实现使AES在所有平台

    • 问题内容: 我找到了在PHP中对字符串进行编码/解码的示例。起初它看起来非常好,但是不会起作用:-( 有人知道问题出在哪里吗? 结果是: 加密: 解密: 问题答案: 并且 在您的代码中未定义。查看有效的解决方案( 但不安全! ): 停! 这个例子是 不安全的! 不要使用它! **但是此代码中还有其他问题,使其变得不安全,尤其是使用ECB(这不是_加密_模式,只能在其上定义加密模式的构造块)。

    • 我在这个网站上用AES-256加密一个虚拟字符串: https://www.devglan.com/online-tools/aes-encryption-decryption 具有以下参数: null 当我尝试用OpenSSL从命令行解密它时: 我得到这个错误: