gpt4 book ai didi

encryption - 使用初始化向量和填充正确实现 AES 128 加密

转载 作者:行者123 更新时间:2023-12-03 23:42:43 30 4
gpt4 key购买 nike

我使用初始化向量和填充实现了 AES 128 位加密,如下面的代码所示。我碰巧在使用 ColdFusion,但我认为这并不重要。加密结果显示了一些重复的模式,这是我没想到的,但是我又不知道正确输出的特征。我是否正确地进行了初始化向量和填充?

<!---
To encrypt this, for example:
"String1"
Prefix the string with an Initialization Vector of 16 random characters,
plus enough padding ("000000001") to make the entire string a multiple of 16 characters (32 characters, here)
"HoMoz4yT0+WAU7CX000000001String1"
Now encrypt the string to this (64 characters):
"Bn0k3q9aGJt91nWNA0xun6va8t8+OiJVmCqv0RzUzPWFyT4jUMzZ56pG5uFt6bGG"
--->

<cfoutput>

<cfset EncryptKey="LpEecqQe3OderPakcZeMcw==">

<cfloop index="StringToEncrypt" list="String1,String2,String3,String3">
<!--- Make random Initialization Vector (IV) of length 16
(create it from GenerateSecretKey(), but GenerateSecretKey is NOT the key that we encrypt/decrypt with) --->
<cfset IV=left(GenerateSecretKey("AES",128),16)>
<!--- Pad the string so its length is a multiple of 16 --->
<cfset padlength=16 - (len(StringToEncrypt) mod 16)>
<cfset padding=repeatstring("0",padlength-1) & "1">
<cfset NewStringToEncrypt=IV & padding & StringToEncrypt>
<cfset EncryptedString=encrypt(NewStringToEncrypt,EncryptKey,"AES","Base64")>
<pre>Original string: #StringToEncrypt#
StringToEncrypt: #NewStringToEncrypt#
EncryptedString: #EncryptedString#</pre>
</cfloop>

</cfoutput>

下面是示例输出:
Original string: String1
StringToEncrypt: QLkApY6XKka7mQge000000001String1
EncryptedString: BOAVeSKidQyyHrEa15x9Uava8t8+OiJVmCqv0RzUzPWFyT4jUMzZ56pG5uFt6bGG

Original string: String2
StringToEncrypt: DboCmHHuVrU05oTV000000001String2
EncryptedString: 4Yk14F0ffz9+djbvSiwA1/X3FHhS5Vhta7Q8iocBPhmFyT4jUMzZ56pG5uFt6bGG

Original string: String3
StringToEncrypt: 8om5VbbWQgvRWK7Q000000001String3
EncryptedString: 01AF+pmF9sDsUHcIXSVfom8Egv8Oiyb2yy12hiVcJjqFyT4jUMzZ56pG5uFt6bGG

Original string: String3
StringToEncrypt: T4qJodVe6aEv0p1E000000001String3
EncryptedString: aAjCbSBRZ+cd7ZwpFPZUxW8Egv8Oiyb2yy12hiVcJjqFyT4jUMzZ56pG5uFt6bGG

每个 EncryptedString 以相同的 21 个字符结尾:
FyT4jUMzZ56pG5uFt6bGG

当原始字符串相同时(第三个和第四个示例中的“String3”),EncryptedString 以相同的 42 个字符结尾:
8Egv8Oiyb2yy12hiVcJjqFyT4jUMzZ56pG5uFt6bGG

更新:根据接受的答案,我不应该做我自己的填充或初始化向量。 Coldfusion 的加密/解密函数可以自动处理,加密的值不会有重复的模式。例如:
EncryptedString=encrypt(StringToEncrypt, EncryptKey, 'AES/CBC/PKCS5Padding', 'Base64')
DecryptedString=decrypt(EncryptedString, EncryptKey, 'AES/CBC/PKCS5Padding', 'Base64')

最佳答案

不要自己做填充,而是让加密函数来做。它附加到明文中,而不是前置。通常的填充称为 PKCS5 填充,并将 $t$ 乘以字节 $t\in {1,2,3,\ldots,16}$ 以组成完整的块。

此外, iv 是 encrypt 函数的参数,而不是在明文之前。它实际上是(当你使用像 CBC、OFB、CFB 这样的链模式时)预置在密文之前。

因此,您可以按照自己的方式生成 IV(尽管可能有更好的功能可以做到),然后按原样使用明文并进行加密:
EncryptedString=encrypt(StringToEncrypt, EncryptKey, 'AES/CBC/PKCS5Padding', 'Base64', binaryDecode(IV, "base64"))
(基于 this documentation )

添加 2
根据这些文档,iv 应该是二进制的,因此必须转换来自 generateKey 的 base64。感谢@Agax 和他的“cftry”示例的评论......

添加 1 事实证明,省略 IV 会导致函数
以一种看似不重复的方式生成自己的 IV。
在任何情况下我们都可以使用
EncryptedString=encrypt(StringToEncrypt, EncryptKey, 'AES/CBC/PKCS5Padding', 'Base64')
反而。必须使用像 CBC 这样的链接模式来从随机 IV 获得传播效果,该随机 IV 掩盖了相同的明文,并且默认的“AES”保持可见(这可能是 ECB 模式)。

当我们将其作为参数给出时,IV 实际上并未附加到密文中,因此您必须以某种方式记住它才能解密第一个纯文本块。很不标准。当您让 encrypt 自己生成它时,它确实在前面加上了它。所以你必须使用相同的解密签名版本。

关于encryption - 使用初始化向量和填充正确实现 AES 128 加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56924420/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com