简而言之,AES 是一种块密码,这意味着它要求输入数据是块大小的倍数(AES 为 16 字节)。您的输入数据是 17 个字节,因此存在对齐错误。 (这不是在谈论内存中的对齐方式)。
处理这个问题的方法是在选项中指定 PKCS#7 填充:
kCCOptionPKCS7Padding | kCCOptionECBMode
输入数据将被填充到块倍数,并且在解密时填充将被删除。为了在加密中实现这一点,有必要将输出缓冲区增加一个块大小。
考虑不使用[ECB模式](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29(向下滚动到企鹅),它不安全。
如果您在 Android 上使用 mcrypt:don't,它是废弃软件,不支持标准填充,仅支持空填充。相反考虑defuse or RNC加密器这是一个完全安全的实现,可用于 iOS 和 Java。
如果您确实使用 mcrypt,您将需要添加自己的PKCS#7 填充.
这是示例代码:
+ (NSData *)doCipher:(NSData *)dataIn
key:(NSData *)symmetricKey
context:(CCOperation)encryptOrDecrypt // kCCEncrypt or kCCDecrypt
{
CCCryptorStatus ccStatus = kCCSuccess;
size_t cryptBytes = 0; // Number of bytes moved to buffer.
NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];
ccStatus = CCCrypt( encryptOrDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
symmetricKey.bytes,
kCCKeySizeAES128,
0,
dataIn.bytes, dataIn.length,
dataOut.mutableBytes, dataOut.length,
&cryptBytes);
if (ccStatus != kCCSuccess) {
NSLog(@"CCCrypt status: %d", ccStatus);
}
dataOut.length = cryptBytes;
return dataOut;
}
PHP PKCS#7 填充示例:
添加 PKCS#7 填充
$padLength = $blockSize - (strlen($clearText) % $blockSize);
$clearText = $clearText . str_repeat(chr($padLength), $padLength);
去除 PKCS#7 填充
$padLength = ord($cryptText[strlen($cryptText)-1]);
$cryptText = substr($cryptText, 0, strlen($cryptText) - $padLength);