我正在使用AES256进行加密/解密,以便在iOS和PHP之间使用不安全的通道进行通信。
我看到了许多类似的问题,这些问题围绕着密钥大小、模式(CBC或ECB)、使用随机iv等方面。但在这种情况下,我发现了一个奇怪的行为,如下所示。
两个环境中的配置: - 密钥:32字节(256位) - 块大小:128位(标准) - iv:16字节(用于测试的静态值) - 模式:CBC
如果我加密一个16或32字节的文本(以匹配AES块大小),那么Swift和PHP中的结果相似但不完全相同:
key = "12345678901234567890123456789012" plainText = "12345678901234567890123456789012" iv = "1234567890123456"
Swift cipher = e5RnnlJkv4QGnGhkMwfvgMHr80NWUVhbvvfCdPQ5V2KyKJTx4KfWmn4HXi4dG0b8 PHP cipher = e5RnnlJkv4QGnGhkMwfvgMHr80NWUVhbvvfCdPQ5V2I=
正如您所看到的,密码的长度以及PHP Base64字符串的最后2个字符存在差异。
但是,如果我使用的文本不是AES128块大小的倍数,比如“Hello World”,则两个环境会报告不同(但大小相同)的密码,如下所示:
Swift cipher = bdwO/5C8a+pliIoIXtuzfA==
PHP cipher = oPotHCkxpOwQhIaCz6hNMw==
在这两种情况下(Swift和PHP),无论明文的大小如何,密码都可以正确解密。此外,Swift的结果与Objective-C版本的代码一致。
以下是使用的简化代码:
PHP
$key = "12345678901234567890123456789012";
$iv = "1234567890123456";
$plaintext = "Hello World";
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
$ciphertext_base64 = base64_encode($ciphertext);
echo "ciphertext: ".$ciphertext_base64."</br>";
快捷
let keyData: NSData! = (key as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let keyBytes = UnsafePointer<UInt8>(keyData.bytes)
let keyLength = size_t(kCCKeySizeAES256)
let plainData = (plainText as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let dataLength = UInt(plainData.length)
let dataBytes = UnsafePointer<UInt8>(plainData.bytes)
var bufferData = NSMutableData(length: Int(dataLength) + kCCBlockSizeAES128)
var bufferPointer = UnsafeMutablePointer<UInt8>(bufferData.mutableBytes)
let bufferLength = size_t(bufferData.length)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES128)
let options = UInt32(kCCOptionPKCS7Padding)
let ivData: NSData! = (iv as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData!
let ivPointer = UnsafePointer<UInt8>(ivData.bytes)
var numBytesEncrypted: UInt = 0
var cryptStatus = CCCrypt(operation, algoritm, options, keyBytes, keyLength, ivPointer, dataBytes, dataLength, bufferPointer, bufferLength, &numBytesEncrypted)
bufferData.length = Int(numBytesEncrypted)
let base64cryptString = bufferData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
println(base64cryptString)
为什么它们不同呢?