ECB AES-128 的 R 实现不兼容?
R implementation of ECB AES-128 not compatible?
我对加密非常陌生,所以我尝试重新创建一个简单的 ECB AES-128 加密,如这个在线工具所显示的那样:
https://www.devglan.com/online-tools/aes-encryption-decryption
然而,当试图加密明文时:
"参数1=1&参数2=2&par3=3"
使用密钥:
"1234567890123456"
我从摘要 R 实现和上述站点得到不同的结果。
即 R 给我十六进制结果:
"00 63 2a 41 0a 39 0a ab b7 b9 80 b8 f1 4b 07 d9 a7 20 94 d6 b0 5b 57 17 67 68 36 a2 70 ca a2 8f"
而在线工具给我:
"00 63 2A 41 0A 39 0A AB B7 B9 80 B8 F1 4B 07 D9 1B 09 5D 83 76 9F 6B 47 7E 51 FA D9 99 56 CE 2C B7 5A 26 54 C9 F3 6F EC 36 EF B5 D6 D2 1D 2C 0B"
有趣的是前16个字节是一样的,后面就不同了。
代码如下:
Test_String <- paste("parameter1=1", "parameter2=2", "par3=3", sep = "&")
Passphrase <- charToRaw("1234567890123456")
ECB_AES <- AES(key = Passphrase , mode = "ECB")
(Encrypted_Test_String <- ECB_AES$encrypt(Test_String))
在您的在线工具中,可用的密钥大小为 128、196 和 256 位。
如果您查看 ECB_AES
,它会告诉您 R
中的密钥大小为 16
> ECB_AES
AES cipher object; mode ECB key size 16
以防万一有人再次需要这个,这是我想出的解决方案,感谢@Topaco 的提示。
问题确实是,默认情况下,digest::AES() 不会填充原始转换后的纯文本。
我的初始 post 中引用的在线工具,以及与此相关的大多数在线工具,都使用 PKCS7,它使用间隙长度的字节表示来填充块长度(16 字节)的间隙,如果块长度完全对齐,则为 16。
示例:纯文本“parameter1=1¶meter2=2¶meter3=3&par4=4”原始转换
Test_String <- "parameter1=1¶meter2=2¶meter3=3&par4=4"
Raw_Test_String <- charToRaw(Test_String)
的长度为 45 (70 61 72 61 6d 65 74 65 72 31 3d 31 26 70 61 72 61 6d 65 74 65 72 32 3d 32 26 70 61 72 61 6d 65 74 65 72 33 26 d 33
70 61 72 34 3d 34) 所以到块长度 16 (16 * 3 = 48) 的间隙是 3。
因此,字符串必须用字节表示形式 (03) 中的 3 个 3 来填充。
charToRaw 在这里不起作用,所以我们需要使用 as.raw(3) 来获得所需的字节表示。
Raw_Padded_String <- c(Raw_Test_String, c(as.raw(3),as.raw(3),as.raw(3)))
解密后生成与在线工具相同的输出:
Passphrase <- charToRaw("1234567890123456")
ECB_AES <- AES(key = Passphrase , mode = "ECB")
(Encrypted_Test_String <- ECB_AES$encrypt(Raw_Padded_String))
由于没有函数可以对我能找到的任何字符串长度的重复过程执行此操作,这里有一个以防有人需要它:
PKCS7 <- function(Raw_Text, block_length = 16){
bytes_to_padd <- (ceiling((length(Raw_Text) / block_length)) - (nchar(Raw_Text) / block_length)) * block_length
if(bytes_to_padd == 0) bytes_to_padd <- 16
Padded_Raw_Text <- c(Raw_Text, rep(as.raw(bytes_to_padd), times = bytes_to_padd))
return(Padded_Raw_Text)
}
我敢肯定这不理想,但它适合我。
我对加密非常陌生,所以我尝试重新创建一个简单的 ECB AES-128 加密,如这个在线工具所显示的那样: https://www.devglan.com/online-tools/aes-encryption-decryption
然而,当试图加密明文时:
"参数1=1&参数2=2&par3=3"
使用密钥:
"1234567890123456"
我从摘要 R 实现和上述站点得到不同的结果。
即 R 给我十六进制结果:
"00 63 2a 41 0a 39 0a ab b7 b9 80 b8 f1 4b 07 d9 a7 20 94 d6 b0 5b 57 17 67 68 36 a2 70 ca a2 8f"
而在线工具给我:
"00 63 2A 41 0A 39 0A AB B7 B9 80 B8 F1 4B 07 D9 1B 09 5D 83 76 9F 6B 47 7E 51 FA D9 99 56 CE 2C B7 5A 26 54 C9 F3 6F EC 36 EF B5 D6 D2 1D 2C 0B"
有趣的是前16个字节是一样的,后面就不同了。
代码如下:
Test_String <- paste("parameter1=1", "parameter2=2", "par3=3", sep = "&")
Passphrase <- charToRaw("1234567890123456")
ECB_AES <- AES(key = Passphrase , mode = "ECB")
(Encrypted_Test_String <- ECB_AES$encrypt(Test_String))
在您的在线工具中,可用的密钥大小为 128、196 和 256 位。
如果您查看 ECB_AES
,它会告诉您 R
中的密钥大小为 16
> ECB_AES
AES cipher object; mode ECB key size 16
以防万一有人再次需要这个,这是我想出的解决方案,感谢@Topaco 的提示。
问题确实是,默认情况下,digest::AES() 不会填充原始转换后的纯文本。
我的初始 post 中引用的在线工具,以及与此相关的大多数在线工具,都使用 PKCS7,它使用间隙长度的字节表示来填充块长度(16 字节)的间隙,如果块长度完全对齐,则为 16。
示例:纯文本“parameter1=1¶meter2=2¶meter3=3&par4=4”原始转换
Test_String <- "parameter1=1¶meter2=2¶meter3=3&par4=4"
Raw_Test_String <- charToRaw(Test_String)
的长度为 45 (70 61 72 61 6d 65 74 65 72 31 3d 31 26 70 61 72 61 6d 65 74 65 72 32 3d 32 26 70 61 72 61 6d 65 74 65 72 33 26 d 33 70 61 72 34 3d 34) 所以到块长度 16 (16 * 3 = 48) 的间隙是 3。 因此,字符串必须用字节表示形式 (03) 中的 3 个 3 来填充。 charToRaw 在这里不起作用,所以我们需要使用 as.raw(3) 来获得所需的字节表示。
Raw_Padded_String <- c(Raw_Test_String, c(as.raw(3),as.raw(3),as.raw(3)))
解密后生成与在线工具相同的输出:
Passphrase <- charToRaw("1234567890123456")
ECB_AES <- AES(key = Passphrase , mode = "ECB")
(Encrypted_Test_String <- ECB_AES$encrypt(Raw_Padded_String))
由于没有函数可以对我能找到的任何字符串长度的重复过程执行此操作,这里有一个以防有人需要它:
PKCS7 <- function(Raw_Text, block_length = 16){
bytes_to_padd <- (ceiling((length(Raw_Text) / block_length)) - (nchar(Raw_Text) / block_length)) * block_length
if(bytes_to_padd == 0) bytes_to_padd <- 16
Padded_Raw_Text <- c(Raw_Text, rep(as.raw(bytes_to_padd), times = bytes_to_padd))
return(Padded_Raw_Text)
}
我敢肯定这不理想,但它适合我。