在 AES-CTR 模式下正确使用随机数和计数器

2024-01-11

据我了解,在 AES 计数器模式下,我需要使用 128 位随机数。最简单的方法是使用随机 128 位随机数,但我不确定如果将其作为所有随机位传递,算法是否能够正确增加计数器。我认为正确的方法是使用 96 位随机数和从 0 开始的 32 位计数器,例如:

var key = CryptoJS.enc.Hex.parse('01ab23cd45ef67089a1b2c3d4e5f6a7b'); // 128 bits / 16 bytes
var nonce = '2301cd4ef785690a1b2c3dab'; // 96 bits / 12 bytes
var counter = '00000000'; // 32 bits / 4 bytes
var nonceAndCounter = nonce + counter;
    nonceAndCounter = CryptoJS.enc.Hex.parse(nonceAndCounter);
var plaintext = 'The quick brown fox jumps over the lazy dog.';

var encryption = CryptoJS.AES.encrypt(plaintext, key, { iv: nonceAndCounter, mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding });
var ciphertext = encryption.ciphertext.toString(CryptoJS.enc.Hex);

这是正确的方法吗CryptoJS 库 https://code.google.com/p/crypto-js/?或者什么是正确的方法?


当我深入研究库代码以了解它的真正作用时,我将回答我自己的问题。

Summary:

答案是您可以使用两种方法中的任何一种,它将按预期工作:

1)传入长度为 96 位的随机数,库本身将自动添加 32 位计数器,并随着生成的每个密钥流块而递增它。例如。

var nonce = CryptoJS.enc.Hex.parse('2301cd4ef785690a1b2c3dab'); // 12 Bytes
var encryption = CryptoJS.AES.encrypt(plaintext, key, { iv: nonce, mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding });

2)传入长度为 96 位的随机数,并根据需要显式指定 32 位计数器。您甚至可以指定一个计数器,例如00000009如果你想从第9块开始加密/解密。下面是从计数器 0 开始的示例:

var nonce = '2301cd4ef785690a1b2c3dab';  // 12 Bytes
var counter = '00000000';                // 4 Bytes, start at counter 0
var nonceAndCounter = CryptoJS.enc.Hex.parse(nonce + counter);  // 16 Bytes
var encryption = CryptoJS.AES.encrypt(plaintext, key, { iv: nonceAndCounter, mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding });

解释:

使用问题中的代码和 32 位计数器00000000,相关代码在这个文件中模式ctr.js https://crypto-js.googlecode.com/svn/tags/3.1.2/src/mode-ctr.js:

/**
 * Counter block mode.
 */
CryptoJS.mode.CTR = (function () {
    var CTR = CryptoJS.lib.BlockCipherMode.extend();

    var Encryptor = CTR.Encryptor = CTR.extend({
        processBlock: function (words, offset) {
            // Shortcuts
            var cipher = this._cipher
            var blockSize = cipher.blockSize;
            var iv = this._iv;
            var counter = this._counter;

            // Generate keystream
            if (iv) {
                counter = this._counter = iv.slice(0);

                // Remove IV for subsequent blocks
                this._iv = undefined;
            }
            var keystream = counter.slice(0);
            cipher.encryptBlock(keystream, 0);

            // Increment counter
            counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0

            // Encrypt
            for (var i = 0; i < blockSize; i++) {
                words[offset + i] ^= keystream[i];
            }
        }
    });

    CTR.Decryptor = Encryptor;

    return CTR;
}());

当使用断点在浏览器 JS 调试器中运行此代码时,它会将nonceAndCounter转换为由 32 位元素组成的 WordArray:

[587320654, -142251766, 455884203, 0]

这用于加密块。为了加密下一个块,它运行以下行:

counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0

哪个评估采取counter[3]元素,即整数 0 并将其递增到:

[587320654, -142251766, 455884203, 1]

通过后续的块和随机数,我可以看到......

[587320654, -142251766, 455884203, 2]

[587320654, -142251766, 455884203, 3]

[587320654, -142251766, 455884203, 4]

等等。所以它似乎以这种方式正常工作。

将其与传递 128 位随机数的工作原理进行对比,例如

var nonceAndCounter = CryptoJS.enc.Hex.parse('2301cd4ef785690a1b2c3dabdf99a9b3');

这会产生一个随机数:

[587320654, -142251766, 455884203, -543577677, 0]

所以它创建了 5 个数组元素!?然后该函数将第四个元素从-543577677 to -543577676, then -543577675, then -543577674等等。所以它在某种程度上仍然有效,但不会像从 0 开始那样递增,并且可能更容易出错。

当我仅传入 96 位随机数时,库会自动将起始计数器添加为 0 到计数器数组的末尾,并为后续块正确递增它。例如

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

在 AES-CTR 模式下正确使用随机数和计数器 的相关文章

随机推荐

  • 使用 Mockito 调用回调

    我有一些代码 service doAction request Callback
  • Python 中运算符重载的综合指南 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有关于操作员重载的综合指南 最好是在网上 但一本书也可以 的描述操作员模块 http docs p
  • 自动调整ScrollViewInsets 不起作用

    我创建了一个非常简单的演示应用程序来测试其功能automaticallyAdjustsScrollViewInsets 但 tableView 的最后一个单元格被我的选项卡栏覆盖 我的 AppDelegate 代码 UITabBarCont
  • NSDateFormatter 中“YYYY”和“yyyy”之间的区别

    YYYY 和 yyyy 之间的确切区别是什么 我读到这个链接 https developer apple com library mac documentation Cocoa Conceptual DataFormatting Artic
  • 在Android studio中组织资源

    我正在开发一个包含大量 xml 布局文件的项目 我想将它们组织在单独的文件夹中 这好像是资源合并将是正确的解决方案 http tools android com tech docs new build system resource mer
  • Scala 将函数列表应用于对象

    我有很多功能 val f1 x Int gt x 1 val f2 x Int gt x 2 val f3 x Int gt x 3 我有一个值 val data 5 我想将所有函数应用于该值并返回单个值 所以 f3 f2 f1 data
  • 如何在 iOS 中使用 SVGKit 将 SVG 路径组件解析为 UIBezierPath?

    我正在 iOS 中使用 Swift 制作 SVG 图像动画 我已经能够使用 SVGKit 轻松渲染 SVG https github com SVGKit SVGKit https github com SVGKit SVGKit 但要对其
  • UIImage 不使用 Swift 显示

    用 Swift 编写的用于显示 UIImages 的代码可以在 iOS 8 0 模拟器中运行 但由于某种原因无法在运行 IOS 7 0 的手机上运行 let image1 UIImage named img1 let imageview U
  • 温莎城堡 - 使用 InstallerFactory 的示例

    有人有一些使用温莎城堡 InstallerFactory 来订购安装程序安装的示例代码吗 似乎无法在文档或其他地方找到它 Cheers 您只能使用InstallerFactory连同FromAssembly class 使用 FromAss
  • 是否有解决方法可以为“csv.reader”使用多字符分隔符?

    目前只允许使用一个字符 Dialect delimiter 用于分隔字段的单字符字符串 它 默认为 https docs python org 3 6 library csv html csv Dialect delimiter https
  • 箭头的创意运用

    我刚刚读了帖子单子的创造性用途 https stackoverflow com questions 412929 creative uses of monads 其中充满了非常有趣的想法和参考 所以我很好奇 箭头怎么样 我并不是在寻找有关基
  • 使用 Java2d 平滑绘图而不使用 Opengl 或 Direct3d Pipelines?

    当 opengl 和 direct3d 管道被禁用时 我无法找到一种方法来使用 Java2d 获得任何东西的平滑移动或动画 通过使用 Dsun java2d d3d false 和 Dsun java2d opengl false 调用虚拟
  • JavaFX 2.2:设置表格单元格样式并处理行伪类(悬停、选定等)

    我正在开发一个 JavaFX 应用程序 其中包含一个带有特殊单元格的 TableView 这样当单元格中的数据无效时 单元格就会变成红色 这对于 css 来说很容易 但是我在覆盖 TableCell 的所有伪类时遇到了麻烦 import j
  • 在intellij上发起一场战争

    我有一个 Java EE 项目 已导入 IntelliJ 中 我可以编译该项目 但由于某种原因无法构建战争工件 当我转到build选项卡
  • Delphi 7 中的圆形标题为“TPanel”

    我的应用程序中有一个 TPanel 但外观不同 对于它 我想要一个彩色标题栏和圆角的上角 就像在某些用户界面中一样it http demo bricolagecms org login welcome html referer login
  • 如何使用外部 JavaScript 代码访问和更新 Bokeh 图或小部件?

    我有一个由时间散景滑块控制的散景图 我试图通过单击按钮将滑块的时间和相应的绘制数据设置为浏览器的当前时间 如果一切都完全用 JS 开发 我知道如何做同样的事情 但我正在编写嵌入 HTML 文件中的外部 JS 函数 并且我不知道如何访问 Bo
  • Spring MVC 测试(安全集成测试),JSESSIONID 不存在

    我为我的 Spring Boot 应用程序创建了自定义登录表单 在我的表单集成测试中 我想检查收到的 cookie 是否包含JS会话ID and XSRF 令牌 但是 我只收到了XSRF 令牌 这是我的测试 RunWith SpringJU
  • python/numpy 中的线性组合

    问候 我不确定这是否是一个愚蠢的问题 假设我有 3 个 numpy 数组 A1 A2 A3 和 3 个浮点数 c1 c2 c3 我想评估 B A1 c1 A2 c2 A3 c3 numpy 会计算这个 例如 E1 A1 c1 E2 A2 c
  • 如何更改滚动条拇指的高度?

    有没有办法将滚动条的高度更改为固定高度并相应地更改滚动的内容量 这是我当前的CSS代码 webkit scrollbar width 30px Track webkit scrollbar track box shadow inset 0
  • 在 AES-CTR 模式下正确使用随机数和计数器

    据我了解 在 AES 计数器模式下 我需要使用 128 位随机数 最简单的方法是使用随机 128 位随机数 但我不确定如果将其作为所有随机位传递 算法是否能够正确增加计数器 我认为正确的方法是使用 96 位随机数和从 0 开始的 32 位计