在 PyCrypto AES MODE_CTR 中包含随机数和块计数

2024-01-18

一些背景信息,您可以跳过这部分以了解实际问题

这是我在 stackoverflow 上关于这个主题的第三个问题。为了完整起见,这些是其他问题AES 与 crypt-js 和 PyCrypto https://stackoverflow.com/questions/9565017/problems-with-aes-in-crypto-js-and-pycrypto and 在 python 和 javascript 中匹配 AES 解密/加密 https://stackoverflow.com/questions/9719388/match-aes-de-encryption-in-python-and-javascript。不幸的是,我的最后一次尝试对最初的问题投了两票。问题是,即使我不知道我真正的问题是什么。我只是四处寻找我正在寻找的真正问题。根据评论中的反馈并阅读一些附加信息,我更新了我的问题。我认为我挖掘了正确的问题。但我的问题在我更新后并没有得到更多的关注。所以我真的希望这个问题现在更加清晰和容易理解 - 即使我知道我现在的问题是什么:D
感谢大家让 stackoverflow 来到这个很酷的社区 - 我经常在这里找到我的问题的解决方案。请不断反馈不好的问题,以便改进和更新它们,从而增加这个庞大的知识和解决方案数据库。 并随时纠正我的英语语法和拼写。

问题

JavaScript 中的 AES

我有一个加密的字符串,我可以用它解密AES 256 CTR 模式的 Javascript 实现 http://www.movable-type.co.uk/scripts/aes.html

password = "myPassphrase"
ciphertext = "bQJdJ1F2Y0+uILADqEv+/SCDV1jAb7jwUBWk"
origtext = Aes.Ctr.decrypt(ciphertext, password, 256);
alert(origtext)

这将解密我的字符串和警报框This is a test Text弹出。

AES 与 PyCrypto

现在我想解密这个字符串python 和 PyCrypto https://www.dlitz.net/software/pycrypto/

password = 'myPassphrase'
ciphertext = "bQJdJ1F2Y0+uILADqEv+/SCDV1jAb7jwUBWk"
ctr = Counter.new(nbits=128)
encryptor = AES.new(key, AES.MODE_CTR, counter=ctr)
origtext = encryptor.decrypt(base64.b64decode(ciphertext))
print origtext

这段代码不运行。我得到一个ValueError: AES key must be either 16, 24, or 32 bytes long。当我认识到我必须在 PyCrypto 中做更多事情然后调用解密方法时,我开始调查并尝试找出我必须做什么。

调查

我首先想到的基本事情是:

  • AES 256 位(?)。但AES标准是128位。将密码增加到 32 字节是否足够?
  • 计数器模式。使用 AES.MODE_CTR 在 PyCrypto 中轻松设置。但我必须指定一个 counter() 方法。所以我用了PyCrypto 提供的基本二进制计数器 https://www.dlitz.net/software/pycrypto/api/current/Crypto.Util.Counter-module.html。这与 Javascript 实现兼容吗?我无法弄清楚他们在做什么。
  • 该字符串采用 Base64 编码。问题不大。
  • 填充一般。密码短语和加密字符串。

对于密码短语,他们这样做:

for (var i=0; i<nBytes; i++) {
    pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
}

然后我在 python 中做了这个

l = 32
key = key + (chr(0)*(l-len(key)%l))

但这并没有帮助。我仍然得到一个奇怪的字符串? A???B??d9= ,?h????'用下面的代码

l = 32
key = 'myPassphrase'
key = key + (chr(0)*(l-len(key)%l))
ciphertext = "bQJdJ1F2Y0+uILADqEv+/SCDV1jAb7jwUBWk"
ctr = Counter.new(nbits=128)
encryptor = AES.new(key, AES.MODE_CTR, counter=ctr)
origtext = encryptor.decrypt(base64.b64decode(ciphertext))
print origtext

然后我读到了更多关于 Javascript 实现的内容,它说

[...] 在此实现中,初始块在前 8 个字节中保存随机数,在后 8 个字节中保存块计数。 [...]

我认为这可能是解决问题的关键。所以我测试了当我在 Javascript 中加密一个空字符串时会发生什么:

origtext = ""
var ciphertext =Aes.Ctr.encrypt(origtext, password, 256);
alert(ciphertext)

警报框显示/gEKb+N3Y08=(12 个字符)。但为什么是 12 个呢?不是应该是8+8=16Bytes吗?好吧,无论如何,我尝试了暴力破解通过测试解密来进行Python解密的方法for i in xrange(0,20): and ciphertext[i:] or base64.b64decode(ciphertext)[i:]。我知道这是一次非常尴尬的尝试,但我却越来越绝望。而且它也不起作用。

未来的前景也是以同样的方式实现加密。

附加信息

加密的字符串最初不是用这个Javascript实现 http://www.movable-type.co.uk/scripts/aes.html,它来自另一个来源。我刚刚认识到,Javascript 代码做了正确的事情。所以我确认这种实施方式就像“标准”.

问题

我能做什么,使用 PyCrypto 对字符串进行加密和解密与 Javascript 实现中的相同,以便我可以在 Javascript 和 Python 之间交换数据? 如果你能推荐另一个,我也会切换到 python 中的另一个加密库。 此外,我对任何类型的提示和反馈都很满意。

我认为,一切都归结为如何将随机数和块计数包含到加密字符串中? and 我如何提取这些信息进行解密?


我们仍然在这里处理一堆问题。

如何提取随机数和计数器进行解密?

这很容易。在 Javascript 实现中(不遵循特定的 这方面的标准)将 8 字节随机数添加到加密结果之前。 在 Python 中,您可以使用以下命令提取它:

import base64
from_js_bin = base64.decode(from_js)
nonce = from_js_bin[:8]
ciphertext = from_js_bin[8:]

Where from_js是您收到的二进制字符串。

无法提取计数器,因为 JS 实现不传输它。 然而,初始值为(通常发生的情况)0。

如何使用随机数和计数器来解密Python中的字符串?

First, it must be established how nonce and counter are combined to get the counter block. It seems that the JS implementation follows the NIST 800-38A standard http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf, where the left half is the nonce, and the right half is the counter. More precisely, the counter is in big endian format (LSB is the rightmost byte). This is also what Wikipedia shows: AES CTR mode.

不幸的是,CTR 模式在 PyCrypto 中的记录很少(a众所周知的问题 https://bugs.launchpad.net/pycrypto/+bug/899818)。 基本上,counter参数必须是callable返回的对象 对于每个后续调用,正确的 16 字节(对于 AES)计数器块。Crypto.Util.Counter这样做,但以一种晦涩的方式。

但它只是出于性能目的。您可以像这样轻松地自己实现它:

from Crypto.Cipher import AES
import struct

class MyCounter:

  def __init__(self, nonce):
    """Initialize the counter object.

    @nonce      An 8 byte binary string.
    """
    assert(len(nonce)==8)
    self.nonce = nonce
    self.cnt = 0

  def __call__(self):
    """Return the next 16 byte counter, as binary string."""
    righthalf = struct.pack('>Q',self.cnt)
    self.cnt += 1
    return self.nonce + righthalf

cipher_ctr = AES.new(key, mode=AES.MODE_CTR, counter=MyCounter(nonce))
plaintext = cipher_ctr.decrypt(ciphertext)

AES 的密钥有多长?

AES-128 的密钥长度为 16 个字节。 AES-192 的密钥长度为 24 字节。 AES-256 的密钥长度为 32 字节。 每个算法都是不同的,但大部分实现是共享的。 在所有情况下,该算法都对 16 字节数据块进行操作。 为简单起见,坚持使用 AES-128 (nBits=128).

你的代码能工作吗?

我感觉不会,因为计算 AES 密钥的方式似乎不正确。 JS代码将密码以UTF-8编码并用自身加密。 结果是实际的密钥材料。它的长度为 16 字节,因此对于 AES-192 和 -256,实现会在后面复制部分内容。此外,明文在加密前也经过 UTF-8 编码。

一般来说,我建议您遵循以下方法:

  1. 使您的 JS 实现可重现(现在加密取决于当前时间,该时间经常变化;-))。
  2. 在每一步打印键和数据的值(或使用调试器)。
  3. 尝试在 Python 中重现相同的算法,并打印值。
  4. 调查它们从哪里开始出现不同。

一旦你用 Python 复制了加密算法,解密算法就应该很容易了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 PyCrypto AES MODE_CTR 中包含随机数和块计数 的相关文章

随机推荐

  • jquery读取嵌套的json

    我有以下 json 如下所示 我正在尝试读取值 TOP1 TOP2 我有点不确定该怎么做 我正在使用以下内容 但这只会给我一个包含 TOP1 和 TOP2 嵌套对象的对象 如何获取 TOP1 和 TOP2 值 getJSON http lo
  • 将 TArray 类型转换为 X 数组是否安全?

    今天我发现了一个编译器错误 QC 108577 http qc embarcadero com wc qcmain aspx d 108577 以下程序无法编译 program Project1 APPTYPE CONSOLE proced
  • 系统找不到JavaApplicationLauncher

    我正在运行 Mac OS X 版本 12 0 1 也称为 Monterey 我已经安装了 MultiWii 程序来控制我正在构建的无人机 本教程逐步介绍下载 解压 甚至适用于 MacOS 的特殊 chmod 指令 然而 当我尝试运行 Mul
  • 读取、读取部分读取

    我似乎无法在文档中找到有关此内容的信息 The read系统调用文档说它读取的数据可能少于指定的数据 做read尝试阅读几次 我知道fread是一个包装器read 当我调用fread 它是否有可能多次从流中读取 直到它变为 0 或读取指定的
  • 如何围绕轮廓绘制矩形?

    我刚刚开始使用 opencv 我正在尝试制作一个程序 在沙子上的岩石图片周围放置方块 该函数的文档here http docs opencv org modules imgproc doc structural analysis and s
  • 如何将 Vec> 移动到 Vec>>

    我有一个Vec
  • Python 中使用回溯记录异常

    如何记录 Python 异常 try do something except How can I log my exception here complete with its traceback Use logging exception
  • 弹性容器中的等高行

    如您所见 list items在第一个row有相同的height 但第二个项目row有不同的heights 我希望所有物品都有统一的height 有什么方法可以在不付出的情况下实现这一目标固定高度并且只使用flexbox 这是我的code
  • 向上滚动时折叠工具栏图像消失

    我正在尝试实现一个带有大标题图像的折叠工具栏 我希望图像开始时非常大 并且它有效 并且不完全崩溃 这也有效 问题是 当工具栏达到最小可折叠高度时 图像会消失 并褪色为应用程序的主要颜色 我希望图像即使在折叠时也保持可见 另外 后退按钮与图片
  • 可观察集合替换项目

    我有一个ObservableCollection 我可以从集合中添加和删除项目 但我无法替换集合中的现有项目 有一种方法可以替换项目并将其反映在我的绑定组件上 System Collections Specialized NotifyCol
  • TPL 数据流:为什么 EnsureOrdered = false 会破坏此 TransformManyBlock 的并行性?

    我正在研究 TPL 数据流管道 并注意到与排序 并行性相关的一些奇怪行为TransformManyBlocks 也可能适用于其他块 这是我要重现的代码 NET 4 7 2 TPL Dataflow 4 9 0 class Program s
  • 如何删除单元格中第一个空格之后的所有字符?

    我有一个城市名称列表 后跟它们所在的州 所有这些都在 Excel 的一列中 如何删除第一个空格之后的所有内容 以便城市名称成为单元格中唯一保留的内容 示例 A1 约翰逊德克萨斯州 应该只是 A1 约翰逊 我假设你想要一个 VBA 解决方案
  • 使用 vscode 扩展 API 更改文件 EOL

    我可以在 VSCode 中默默地更改行尾顺序吗 像这样的事情 vscode commands executeCommand workbench action editor changeEOL LF 您可以将此行添加到您的用户首选项设置中 C
  • 应用按键后捕获 HTML 文本输入按键?

    完全是新手问题 所以请耐心等待 当 HTML 文本输入控件中发生按键时 有两个事件似乎对管理按键很有用 onKeyPress 和 onChanged onKeyPress 在按下按键后 但在将操作应用于控件的文本之前触发 仅当焦点从控件中移
  • 使用 webdriver 查找元素的最佳且最快的方法是什么? By.XPath 或 By.ID 还是其他?为什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 使用 webdriver 查找元素的最佳且最快的方法是什么 By XPath 或 By ID 还是其他 为什么 我在很多地方都读到 XPath
  • 替换字符串中的字符,而不使用字符串replace()方法[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有一个字符串 String originalString This car is my car 我想用 自行车 替换 汽车 而不使用字符
  • 使用 ExecutorService 将任务确定性分配给线程

    给定 Executor 服务具有固定的线程池 是否可以保证任务到线程的确定性分配 更准确地说 假设只有两个线程 即 pool thread 0 和 pool thread 1 并且有 2 个要执行的任务的集合 我希望实现的是前一个线程始终执
  • 将音频缓冲区从 44100 重新采样到 16000

    我有 data uri 格式的音频数据 然后我将此 data uri 转换为缓冲区 现在我需要新采样率的缓冲区数据 当前音频数据为 44 1khz 我需要 16khz 的数据 如果我记录了使用 RecordRTC API 录制音频 如果我以
  • 连接池 – 一个进程 – 多个线程

    我对连接池的理解是 如果连接字符串完全相同 则我们重用该连接而不是建立新连接 我的问题是我正在创建许多线程用于并行处理 在这个 虚拟 程序中 我创建了 500 个线程并让 ThreadPool 函数处理这些线程 步骤是 每个线程都会用 SQ
  • 在 PyCrypto AES MODE_CTR 中包含随机数和块计数

    一些背景信息 您可以跳过这部分以了解实际问题 这是我在 stackoverflow 上关于这个主题的第三个问题 为了完整起见 这些是其他问题AES 与 crypt js 和 PyCrypto https stackoverflow com