“长度为 x 位的密钥”是什么意思?

信息安全 密码学 加密 密钥管理 电子签名
2021-08-29 09:14:17

我想知道“密码系统 C 使用长度为 x 位的密钥”是什么意思。我不明白比特长度是什么意思......它不取决于编码吗?同一个词在utf8、iso和unicode中编码成不同长度的位串,那么有没有通用的编码来定义一个key的长度呢?或者“x 位的长度”是否意味着完全不同的东西?

4个回答

对于对称算法对称加密消息验证码),密钥是位序列,因此任何长度正确的序列都是可能的密钥。例如,AES是一种对称加密算法(特别是分组密码),它定义在 128、192 和 256 位的密钥上:任何 128、192 或 256 位的序列都可以用作密钥。如何对这些位进行编码在这里无关紧要:无论您是否只是将它们转储为原始(每字节 8 位),还是使用 Base64,或十六进制,或从字符串推断它们,或者其他什么,都取决于您。

一些算法有一些陷阱。最好的例子是DES,AES 的前身。DES 被定义为使用 64 位密钥。但是,如果您查看算法定义,您会发现其中只有 56 个位被使用;其他 8 位被简单地忽略(如果您将位编号从 1 到 64,这些位是 8、16、24、32、40、48、56 和 64;它们应该是“奇偶校验位”,具体取决于其他 56 个位,但没有人真正关心设置或检查它们)。所以人们常说 DES 有一个56 位的密钥这是因为密钥长度与安全性有关:如果一个算法接受长度为n位的密钥,那么有2 n可能的密钥,因此尝试全部(称为“穷举搜索”或“蛮力”的攻击)的时间与2 n成正比(n足够大,即大于约 85,这在技术上是不可行的)。从这个意义上说,DES 提供了 56 位密钥的安全性(2 56个“真正不同”的可能密钥)。然而,如果您使用实现 DES 的库,该库将期望 DES 密钥作为 64 位序列(通常以 8 字节提供)。

另一种具有特殊规则的算法是RC2它接受长度为 8 到 128 位的密钥(仅 8 的倍数);但它还有一个额外的参数,称为有效密钥长度,用“T1”表示。在密钥处理过程中,内部值被“缩减”为一系列 T1 位,这意味着后续加密将仅取决于该内部值中 T1 特定位的值。RC2 对穷举搜索的抵抗力不超过 T1 位密钥所提供的阻力,因为人们可以尝试所有可能的 T1 位序列来获取该内部值。然而,RC2 仍然有一个实际的密钥长度(作为密钥提供的位序列的长度),它可以大于 T1。

对于非对称算法(也称为公钥密码学,包括非对称加密、数字签名、一些密钥交换协议和一些更深奥的算法),密钥由公钥和私钥组成的对工作。这些键是具有一些沉重内部结构的数学对象。然后,“密钥长度”是所涉及的数学对象之一的大小的常规度量。

例如,一个 RSA 公钥包含一个称为模数的大整数,以及一个称为公共指数的其他整数(通常很小)当我们说“1024 位 RSA 密钥”时,我们的意思是模数的长度为 1024 位,即大于2 1023但小于2 1024的整数. 这样的整数可以编码为 1024 位的序列,即 128 字节。然而,公钥还必须包含公共指数,因此实际编码长度会更大。从理论上讲,私钥是关于如何将模数分解为素数的知识;该知识的传统编码是主要因素的编码,以及一堆可以从因素重新计算的辅助值(但这会稍微昂贵),并且可能有助于更快地执行算法。

对于适用于不同数学的不同密钥类型,使用其他“长度”,因此您不能通过简单地比较密钥长度来直接比较算法的安全性。256 位ECDSA密钥比 768 位 RSA 密钥安全得多。此外,公钥/私钥对固有的数学结构允许比简单地尝试一堆随机位更快的攻击,并且有许多微妙的细节。有关许多监管机构提出的关于比较密钥大小的各种规则的解释和在线计算器,请参阅此站点。

考虑将字母表中的每个字母向右移动一个的简单加密,这样 A 变为 B,B 变为 C,依此类推。因此:HELLO 被加密为:IFMMP

我可以向右移动一个字母,向右移动两个字母,或者向右移动最多 25 个字母。将“向右的字母数”视为“键”。保存 0 到 25 之间的数字需要 5 位。因此,密钥大小为“5 位”。

或者,不是向右移动,而是假设我们随机重新排序字母表,并进行一对一映射: ABCDEFGHIJKLMNOPQRSTUVWXYZ RJQFGSKPBTODUZLNHYAVXEMWIC 在这种情况下,我们在表中查找字母“H”,看到它被转换为字母“P”,并且消息:HELLO 变为:PGDDL

假设字母表的随机重新排序是使用基于 5 位数字的数学序列完成的,这样每个数字都会生成不同的序列。因此,5 位数字再次成为“关键”。

5 位密钥的问题在于它只有 32 种组合。如果我知道加密算法,我可以全部 32 个密钥,直到找到正确的组合。密钥越大,这变得越困难——成倍增加。6 位密钥有 64 种组合,7 位密钥有 128 种组合,依此类推。一个 10 位密钥有一千个组合,一个 20 位密钥有一百万个组合,一个 30 位密钥有十亿个组合。

假设您有一台可以每秒测试十亿个键的计算机,试图暴力破解所有组合。这意味着您可以在一秒钟内破解 30 位密钥。但是,这意味着破解 60 位密钥需要 10 亿秒(或 34 年)。

我们每增加 30 位,难度就会增加 10 亿倍。像 NSA 这样的间谍机构可以使用超级计算机破解 60 位密钥,但 90 位密钥的破解难度是 10 亿倍,而 120 位密钥的破解难度将比 90 位密钥高 10 亿倍。

这就是为什么旧的 WEP(40 位)和 DES(56 位)被认为过时的原因:我们可以通过尝试所有组合来用台式计算机破解它们。这就是为什么现代加密(例如 AES)使用 128 位的原因。我们不能蛮力破解这些算法。

密钥的长度(以位为单位)只不过是其大小的规范。一个 128 位的密钥占用 16 个字节的空间——只是处理器使用的原始位。没有什么特别的,没有翻译。

编码是位到有意义的事物的映射。例如,ASCII 中的 8 位序列 01100001 (0x61) 是字母“a”。因为密钥是随机数据并且它们没有意义,所以编码只在将二进制数据转换为可打印的东西时起作用,例如 BASE64。因此,而不是“我必须用什么序列来写字母 a?” ——它可以随着不同的编码而变化,一个关键是“这个位是什么?这个位是什么?这个位是什么?”。

同一个词在utf8、iso和unicode中编码成不同长度的位串,那么有没有通用的编码来定义一个key的长度呢?

钥匙不是一个词。它是一个位序列。您所说的“一般编码”是无编码。

另一方面,有称为 UTF-8 和 ISO-* 的 code-point->string 编码,但 unicode 不是编码。它是一个字符集。

也许定义一些术语可能会有所帮助。

“字符集”,例如 unicode,是一组通常由整数索引标识的符号。在 unicode 中,这些符号也称为代码点(严格的 unicode 标量值)。

“字符串”是从字母表中选择的一系列符号。除非另有说明,否则序列是有限长度的,字母表是 unicode 的子集,但该术语也可用于其他字母表:“字节字符串”(其中字母表是可表示为 8 位 [0,255] 的整数集或 [-128,127])或“UTF-16 字符串”(其中字母表是整数集 [0,65535])。

“编码”是从一种字符串到另一种字符串的(通常是可逆的)映射。UTF-8 将“代码点”序列(也称为常规字符串)映射到字节字符串。