Fla*_*Man 5 encryption coldfusion aes
我使用初始化矢量和填充来实现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>
Run Code Online (Sandbox Code Playgroud)
以下是示例输出:
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
Run Code Online (Sandbox Code Playgroud)
每个EncryptedString以相同的21个字符结尾:
FyT4jUMzZ56pG5uFt6bGG
Run Code Online (Sandbox Code Playgroud)
当原始字符串相同时(在第3和第4个示例中为“ String3”),EncryptedString以相同的42个字符结尾:
8Egv8Oiyb2yy12hiVcJjqFyT4jUMzZ56pG5uFt6bGG
Run Code Online (Sandbox Code Playgroud)
更新:按照公认的答案,我不应该自己做填充或初始化向量。Coldfusion的加密/解密功能可以自动处理此问题,并且加密的值将没有重复的模式。例如:
EncryptedString=encrypt(StringToEncrypt, EncryptKey, 'AES/CBC/PKCS5Padding', 'Base64')
DecryptedString=decrypt(EncryptedString, EncryptKey, 'AES/CBC/PKCS5Padding', 'Base64')
Run Code Online (Sandbox Code Playgroud)
不要自己进行填充,而是让加密函数来完成。它附加到明文之后,而不是前置。通常的填充称为 PKCS5 填充,并添加 $t$ 乘以字节 $t \in {1,2,3,\ldots,16}$ 以组成完整的块。
此外,iv 是加密函数的一个参数,并且不添加在明文之前。它实际上(当您使用 CBC、OFB、CFB 等链模式时)添加到密文之前。
因此,您可以像您一样生成 IV(尽管可能有更好的函数可以做到这一点),然后按原样使用明文并加密:
EncryptedString=encrypt(StringToEncrypt, EncryptKey, 'AES/CBC/PKCS5Padding', 'Base64', binaryDecode(IV, "base64"))
(基于本文档)
添加2 根据这些文档,iv 应该是二进制的,因此必须转换generateKey 中的base64。感谢@Agax 的评论和他的“cftry”示例......
添加 1事实证明,省略 IV 将导致函数生成自己的 IV,并且以一种看似不重复的方式。无论如何我们都可以使用
EncryptedString=encrypt(StringToEncrypt, EncryptKey, 'AES/CBC/PKCS5Padding', 'Base64')
反而。必须使用像 CBC 这样的链接模式来从随机 IV 中获得传播效果,该随机 IV 屏蔽相同的明文并且默认的“AES”保持可见(这可能是 ECB 模式)。
当我们将其作为参数给出时,IV 实际上并未添加到密文之前,因此您必须以某种方式记住它才能解密第一个纯文本块。相当不标准。当您让 encrypt 自己生成它时,它会在前面添加它。所以你必须使用相同签名版本的解密。