首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >CryptoJS中的AES-CTR与PyCrypto兼容吗?

CryptoJS中的AES-CTR与PyCrypto兼容吗?
EN

Stack Overflow用户
提问于 2013-04-05 15:13:52
回答 3查看 1.6K关注 0票数 1

我正试图用PyCrypto库解密一些AES-CTR-256数据.密文由依赖CryptoJS库的Cryptocat多方聊天Javascript代码生成。IV方案如Cryptocat 多方协议规范所述

初始化向量(IV)由16个字节组成:随机生成的12个字节和充当计数器的4个字节,每个块递增一次。

(12个随机字节出现在4个计数器字节之前。)

下面是我的Python代码:

代码语言:javascript
复制
import struct
import base64
import Crypto.Cipher.AES

def bytestring_to_int(s):
    r = 0
    for b in s:
        r = r * 256 + ord(b)
    return r

class IVCounter(object):
    def __init__(self, prefix="", iv="\x00\x00\x00\x00"):
        self.prefix = prefix
        self.initial_value = iv

    def increment(self, b):
        if b == "\xff\xff\xff\xff":
            raise ValueError("Reached the counter limit")
        return struct.pack(">I", bytestring_to_int(b)+1)

    def __call__(self):
        self.initial_value = self.increment(self.initial_value)
        n = base64.b64decode(self.prefix) + self.initial_value
        return n

def decrypt_msg(key, msg, iv):
    k = base64.b16decode(key.upper())
    ctr = IVCounter(prefix=iv)
    aes = Crypto.Cipher.AES.new(k, Crypto.Cipher.AES.MODE_CTR, counter=ctr)
    plaintext = aes.decrypt(msg)
    return plaintext

if __name__ == "__main__":
    key = 'b1df40bc2e4a1d4e31c50574735e1c909aa3c8fda58eca09bf2681ce4d117e11'
    msg = 'LwFUZbKzuarvPR6pmXM2AiYVD2iL0/Ww2gs/9OpcMy+MWasvvzA2UEmRM8dq4loB\ndfPaYOe65JqGQMWoLOTWo1TreBd9vmPUZt72nFs='
    iv = 'gpG388l8rT02vBH4'
    plaintext = decrypt_msg(key, msg, iv)
    print plaintext

这就是如何在Javascript中做同样的事情:

  1. 安装CryptoCat扩展
  2. 运行CryptoCat
  3. 启动开发人员控制台(Chrome/Firefox中的F12)
  4. 运行以下代码行
代码语言:javascript
复制
key = 'b1df40bc2e4a1d4e31c50574735e1c909aa3c8fda58eca09bf2681ce4d117e11';
msg = 'LwFUZbKzuarvPR6pmXM2AiYVD2iL0/Ww2gs/9OpcMy+MWasvvzA2UEmRM8dq4loB\ndfPaYOe65JqGQMWoLOTWo1TreBd9vmPUZt72nFs=';
iv = 'gpG388l8rT02vBH4';
opts = {mode: CryptoJS.mode.CTR, iv: CryptoJS.enc.Base64.parse(iv), padding: CryptoJS.pad.NoPadding};
CryptoJS.AES.decrypt(msg, CryptoJS.enc.Hex.parse(key), opts).toString(CryptoJS.enc.Utf8);

预期产出:"Hello, world!ImiAq7aVLlmZDM9RfhDQgPp0CrAyZE0lyzJ6HDq4VoUmIiKUg7i2xpTSPs28USU8"。正如预期的那样,这适用于Javascript。

但是,Python代码输出的是胡言乱语。repr(明文)给出:

代码语言:javascript
复制
'\x91I\xbd\n\xd5\x11\x0fkE\xaa\x04\x81V\xc9\x16;.\xe3\xd3#\x92\x85\xd2\x99\xaf;\xc5\xafI\xac\xb6\xbdT\xf4{l\x17\xa1`\x85\x13\xf2\x8e\x844\xac1OS\xad\x9eZ<\xea\xbb6\x9dS\xd5\xbc\xfd\xc4\r\xf94Y~\xaf\xf3\xe0I\xad\xa6.\xfa\x7f\xf8U\x16\x0e\x85\x82\x8c\x8e\x04\xcb,X\x8b\xf7\xef\xb2\xc2\xe3~\xf1\x80\x08L\x8b \x9f\xaf\x0e\x0b'

我不知道为什么会这样。我确信我的IVCounter实现与JS代码使用的方案相匹配。难道没有与CryptoJS NoPadding选项等价的Python吗?我很困惑。

提前感谢您的帮助!

EN

回答 3

Stack Overflow用户

发布于 2013-04-05 15:19:38

我想你想看看为什么我不能在别人身上解密我的AES加密信息?

您使用python解密的方式需要根据这个问题的答案进行修改。

票数 0
EN

Stack Overflow用户

发布于 2013-04-16 03:24:43

下面是经过修正的Python脚本,它可以工作!

编辑:不是真的-只有前16个字节的纯文本才会被显示出来。我将进一步研究这个问题。

代码语言:javascript
复制
import struct
import base64
import Crypto.Cipher.AES

def bytestring_to_int(s):
    r = 0
    for b in s:
        r = r * 256 + ord(b)
    return r

class IVCounter(object):
    def __init__(self, prefix="", iv="\x00\x00\x00\x00"):
        self.prefix = prefix
        self.initial_value = iv
        self.first = True

    def increment(self, b):
        if b == "\xff\xff\xff\xff":
            raise ValueError("Reached the counter limit")

        if self.first:
            return struct.pack(">I", bytestring_to_int(b))
        else:
            self.first = False
            return struct.pack(">I", bytestring_to_int(b)+1)

    def __call__(self):
        self.initial_value = self.increment(self.initial_value)
        n = base64.b64decode(self.prefix) + self.initial_value
        return n

def decrypt_msg(key, msg, iv):
    k = base64.b16decode(key.upper())
    ctr = IVCounter(prefix=iv)
    aes = Crypto.Cipher.AES.new(k, Crypto.Cipher.AES.MODE_CTR, counter=ctr)
    plaintext = aes.decrypt(base64.b64decode(msg))
    return plaintext

if __name__ == "__main__":
        key = 'b1df40bc2e4a1d4e31c50574735e1c909aa3c8fda58eca09bf2681ce4d117e11'
        msg = 'LwFUZbKzuarvPR6pmXM2AiYVD2iL0/Ww2gs/9OpcMy+MWasvvzA2UEmRM8dq4loB\ndfPaYOe65JqGQMWoLOTWo1TreBd9vmPUZt72nFs='
        iv = 'gpG388l8rT02vBH4'
        print decrypt_msg(key, msg, iv)
        print "Decrypted message:", repr(decrypt_msg(key, msg, iv))
票数 0
EN

Stack Overflow用户

发布于 2013-04-17 00:20:51

我增加计数器的方式有问题。显然,正确的计数器值被应用到错误的位置。下面是一个关于这个问题的后续问题。使用Python和Javascript的AES CTR模式的奇怪问题

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15837463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档