【问题标题】:What is a WordArray?什么是字数组?
【发布时间】:2019-10-23 13:41:53
【问题描述】:

我一直在研究 crypto-jsits encoderWordArray 之间的转换。我查了the documentation,找不到任何关于WordArray可能是什么的解释。

据我所知,在 JavaScript 中甚至没有一个名为 WordArraytyped array,在该名称的任何类型化数组上也没有 DataView

我知道WORD is in the Visual C++ parlance 是什么意思,但我不确定它在这里是什么意思。

奇怪,我在 crypto-js 上发现的所有线程(hereherehere)都在使用 WordArray 这个词,而没有人真正问它是什么。

真的有人能告诉我吗?是Uint16Array 吗?或者只是常规字节数组的另一个花哨的词(Uint8Arrayuntyped Array 的整数值)?

【问题讨论】:

  • 第一次出现的字符串WordArray(在您标记为“文档”的链接中)声明:“(哈希算法接受字符串或 CryptoJS.lib.WordArray 的实例。)* WordArray 对象表示 32 位字的数组。*"。您在下面链接的要点中重复了相同的内容。看起来很简单。
  • @mbojko 谢谢。我错过了。尽管如此,问题仍然存在。所以,如果我有字符串“he”,在 UTF-8 中它变成两个相邻的 16 位无符号整数。如果我将它们转换为WordArray,这是否会导致一个数组只有一个 32 位元素,由字母“h”的 16 位作为HIWORD 和字母“e”作为@ 987654343@?
  • 我刚刚为此发布了一个单独的问题。 stackoverflow.com/q/58525372/303685
  • 顺便说一句,您在另一个问题中指定的是 UTF-16,或者更准确地说是没有字节顺序标记的 UTF-16BE。
  • 不知道,一定是有一次碰到了 BOM :)

标签: javascript cryptography cryptojs


【解决方案1】:

该类在 CryptoJS 库中的 core.js 中定义:

/**
 * An array of 32-bit words.
 *
 * @property {Array} words The array of 32-bit words.
 * @property {number} sigBytes The number of significant bytes in this word array.
 */
var WordArray = C_lib.WordArray = Base.extend({

放在那里的(字节)值放在单词的最高有效位中(我已经对照源代码检查了这一点)。

例如,如果您将值 "he" 作为 UTF-8(或 Latin1 或 ASCII)放入其中,那么您将获得一个包含值 68_65_00_00 的单元素数组,并将 words 设置为值 2。这是因为 UTF-8 编码为 8 位字节,并且这些字节被分组在最高 16 位中。


通常(对称)加密算法被指定为对位进行操作。但是,它们通常针对 32 位或 64 位字进行优化,因为它们在 i86 或 x64 等 32 位或 64 位机器中是最佳的。因此,任何语言的任何库都会在执行操作之前在内部转换为单词。

通常,库将其操作定义为使用字节而不是单词。 CryptoJS 有点特殊,因为它对单词缓冲区进行操作。这是合乎逻辑的,因为 JavaScript 没有定义字节数组。它还跳过了一个步骤,否则您必须从 UTF-8 转换为字节,然后在算法实现中再次转换为单词。

CryptoJS 还存在一个 64 位字数组,无疑是针对 SHA-512 等针对 64 位操作进行优化的算法。

【讨论】:

  • 是的,与其他任何语言相比,缺少对面向位的类型(如字节和字)的直接支持将使原生 JavaScript 加密库 狗慢,更不用说 C或汇编程序。在这里,即使使用 JIT,解释器也几乎没用。您必须使用较低级别的机器代码来加快速度。
  • 还有一件事。我注意到我从字节数组转换的WordArray 中的一些值是有符号的。我没有考虑二进制补码。我只是将四位字节左移到每个 WordArray 的一个元素中。所以,问题是:WordArray 的元素可以签名,对吗?我的意思是,它们不应该是无符号类型,对吗?
  • 好的,我试过了,它就像一个魅力。在客户端和 ASP.NET 服务器上使用相同的密钥(作为字节数组而不是 WordArray)。那么WordArray 的元素是什么都是有意义的。也就是说,它具有带符号的 32 位整数。
  • 是的,没问题。例如,all Java 的基本类型(char 除外,它仅用于字符)是有符号的。 int(32 位字等效)中的位也有符号。但最后,对于像 AES 这样的操作,这并不重要。它确实使一些计算变得更加困难,特别是对于int 以外的类型,因为你必须采取例如签名扩展考虑。这对于 程序员 而不是计算机来说是一个更大的问题。所以其他语言也可以毫无问题地对有符号整数进行操作。
  • 请注意,对于 2-补码值,不仅位操作保持不变。还有例如减法和加法在 mod 2^32 中是相同的。例如,您可能必须在没有符号的情况下解释结果。比较为整数,但仅此而已。而且 AES 不需要比较,所有操作都是在不查看实际内容的情况下执行的(如果您基于内容,您可能有一个侧通道)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 2020-04-18
  • 2020-08-05
  • 2011-04-30
  • 2016-09-28
  • 1970-01-01
相关资源
最近更新 更多