Bog*_*rda 4 encryption aes ios
我尝试使用带有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];
}
Run Code Online (Sandbox Code Playgroud)
但是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);
Run Code Online (Sandbox Code Playgroud)
输入字符串
"test_string,test2"
Run Code Online (Sandbox Code Playgroud)
结果是
jxtFOhYpgBVieM90zx9oDanqBkcsVAvRRJsM4GL3cio=
Run Code Online (Sandbox Code Playgroud)
在Android上的结果是
jxtFOhYpgBVieM90zx9oDUfV7v43WFv7F5bzErfxrL8=
Run Code Online (Sandbox Code Playgroud)
我错了什么?
简单地说,AES是一个块密码,这意味着它要求它的输入数据是块大小的倍数(AES为16字节).您的输入数据是17个字节,因此对齐错误.(它不是在谈论内存中的对齐).
处理此问题的方法是在选项中指定PKCS#7填充:
kCCOptionPKCS7Padding | kCCOptionECBMode
Run Code Online (Sandbox Code Playgroud)
输入数据将被填充到块多个,并且在解密时将删除填充.要在加密时允许此操作,必须将输出缓冲区增加一个块大小.
考虑不使用[ECB模式](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29 (向下滚动到企鹅),它不安全.
如果你在Android上使用mcrypt:不要,它是放弃软件,不支持标准填充,只支持空填充.相反,可以考虑使用defuse或RNCryptor作为完全安全的实现,适用于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;
}
Run Code Online (Sandbox Code Playgroud)
示例PHP PKCS#7填充:
添加PKCS#7填充
$padLength = $blockSize - (strlen($clearText) % $blockSize);
$clearText = $clearText . str_repeat(chr($padLength), $padLength);
Run Code Online (Sandbox Code Playgroud)
剥离PKCS#7填充
$padLength = ord($cryptText[strlen($cryptText)-1]);
$cryptText = substr($cryptText, 0, strlen($cryptText) - $padLength);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2472 次 |
最近记录: |