我尝试使用带有ECB选项的AES算法加密一些字符串。
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode,
encryptionKey, kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
但是func返回kCCAlignmentError(-4303)
然后,我尝试对齐数据:
unsigned long diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
unsigned long newSize = 0;
if (diff > 0) {
newSize = dataLength + diff;
}
char dataPtr[newSize];
memcpy(dataPtr, [self bytes], [self length]);
for(int i = 0; i < diff; i++) {
dataPtr[i + dataLength] = 0x20;
}
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode,
encryptionKey, kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
dataPtr, sizeof(dataPtr), /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
输入字符串
"test_string,test2"
结果是
jxtFOhYpgBVieM90zx9oDanqBkcsVAvRRJsM4GL3cio=
在Android上的结果是
jxtFOhYpgBVieM90zx9oDUfV7v43WFv7F5bzErfxrL8=
我怎么了
简单来说,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:do n't,则它是废弃软件,不支持标准填充,仅支持空填充。而是考虑使用defuse或RNCryptor,这是适用于iOS和Java的完全安全的实现。
如果确实使用mcrypt,则需要添加自己的PKCS#7 padding。
这是示例代码:
+ (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);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句