【问题标题】:How can I encrypt/decrypt data using AES CBC+CTS (ciphertext stealing) mode in PHP?如何在 PHP 中使用 AES CBC+CTS(密文窃取)模式加密/解密数据?
【发布时间】:2012-05-11 18:24:51
【问题描述】:
我必须在 PHP 中以 AES CTS 模式(密文窃取,有时称为 AES-XTS)加密和解密数据,才能与用 .NET 平台编写的远程系统进行互操作。在 .NET 4 中,此模式为 supported natively。
对于PHP,我找不到解决方案,根据手册,mcrypt似乎不支持这种模式。
谁能解释一下普通 CBC 和 CBC-CTS 之间的区别?是否可以使用现有的模块/库使后者在 PHP 中工作?
【问题讨论】:
标签:
php
.net
cryptography
aes
mcrypt
【解决方案1】:
这是来自维基百科 article 的步骤插入我的 cmets 解释
-
LDn = 解密 (K, Cn-1)。解密倒数第二个密文块(倒数第二个 128bit/16 字节块块),使用零作为 IV。
你可以用标准的 PHP mcrypt 函数做到这一点,只需通过
$second_to_last_cipher=array_slice($your_cipher_text_byte_array,count($your_cipher_text_byte_array)-32,16)
到 mcrypt_decrypt 的 Iv 为空
$second_to_last_clear = mcrypt_decrypt"MCRYPT_RIJNDAEL_128",$key,$second_to_last_ciphe)
-
Cn = Cn ||尾巴(Dn,BM)。使用倒数第二个密文块的块密码解密的最后 B-M 位将密文填充到块大小的最接近的倍数。
将刚刚解密的值的最后n个字节复制到最后一个密文块中。
$n = 16 - ($second_to_last_clear % 16)
然后使用数组拷贝来拷贝数据
-
交换最后两个密文块。
只需交换密文数组中最后一个和第二个最后两个单元格的内容
-
使用标准 CBC 模式解密密文直到最后一个块。
进行标准解密调用。
-
最后一个密文(已在步骤 1 中解密)与倒数第二个密文异或。
不言自明。
- 将明文截断为原始密文的长度。
【解决方案2】:
我找到了一个用C语言实现的AES算法,你可以在源代码here找到它。
Android 中使用了作者的旧实现。所以我认为这个实现会很有希望。
最后,在你下载完源代码后,再查看文件aesxam.c,有一个非常好的CTS示例,带有CBC进行文件加密。
所有学分都转到Brian Gladman。
Brian Gladman 现在维护自己的 github repo for AES。