CCCrypto расшифровывает: ровно на один блок меньше
Я пытаюсь расшифровать строку, зашифрованную скриптом golang. Шифрование - CBC, размер ключа 256. 16 байтов длиной iv включают в начале зашифрованного текста, как предположил Голанг Док. Все работает отлично, за исключением кодов objc, всегда теряющих последний блок. например, когда я ожидаю возврата 80 байт, но получаю только 64, ожидаю 128, но получаю 112. Любой совет? Спасибо!
код Голанга
func encrypt(text_s, key_s string) byte[] {
text := []byte(text_s)
// padding text
n := aes.BlockSize - (len(text) % aes.BlockSize)
log.Println("Need to pad:", n)
if n != aes.BlockSize || n != 0 {
text = append([]byte(strings.Repeat(" ", n)), text...)
}
log.Println("to encrypt:'", string(text), "'")
log.Println("padded length:", len(text))
key := []byte(key_s)[:32]
block, _ := aes.NewCipher(key)
// if err != nil {
// panic(err)
// }
ret := make([]byte, aes.BlockSize + len(text))
iv := ret[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
cbc := cipher.NewCBCEncrypter(block, iv)
cbc.CryptBlocks(ret[aes.BlockSize:], text)
return ret
}
коды объектов:
- (NSData *)decrypt:(NSData*)data{
if (!key) {
key = [[_token substringToIndex:32] dataUsingEncoding:NSUTF8StringEncoding];
}
// NSLog(@"decodbase64 :%@",[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
// NSString *key = _token;
//
// char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
// bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// BOOL patchNeeded = ([_token length] > kCCKeySizeAES256);
// NSLog(@"need patch? %@", patchNeeded ? @"YES": @"NO");
//
// if (patchNeeded) {
// key = [_token substringToIndex:kCCKeySizeAES256]; // Ensure that the key isn't longer than what's needed (kCCKeySizeAES256)
// }
// fetch key data
// [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSASCIIStringEncoding];
// if (patchNeeded) {
// // Previous iOS version than iOS7 set the first char to '\0' if the key was longer than kCCKeySizeAES256
// keyPtr[0] = '\0';
// }
size_t dataLength = [data length] - kCCBlockSizeAES128;
NSData *iv = [data subdataWithRange:NSMakeRange(0, kCCBlockSizeAES128)];
NSData *encrypted = [data subdataWithRange:NSMakeRange(kCCBlockSizeAES128, dataLength)];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
// size_t bufferSize = dataLength + kCCBlockSizeAES128;
// void *buffer = malloc(dataLength);
NSMutableData *ret = [NSMutableData dataWithLength:dataLength + kCCBlockSizeAES128];
size_t numBytesDecrypted = 0;
CCCryptorStatus status = CCCrypt(kCCDecrypt, kCCAlgorithmAES,
kCCOptionPKCS7Padding,
[key bytes],
kCCKeySizeAES256,
[iv bytes],
[encrypted bytes], dataLength, /* input */
[ret mutableBytes], [ret length], /* output */
&numBytesDecrypted
);
NSLog(@"err: %d", status);
NSLog(@"dataLength: %d, num: %d", (int)dataLength, (int)numBytesDecrypted);
if (status == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return ret;
}
// free(buffer); //free the buffer;
return nil;
}
1 ответ
Решение
Оказывается, проблема в опции дешифрования:
CCCryptorStatus status = CCCrypt(kCCDecrypt, kCCAlgorithmAES,
0, // change to 0 solve the problem
[key bytes],
kCCKeySizeAES256,
[iv bytes],
[encrypted bytes], dataLength, /* input */
[ret mutableBytes], [ret length], /* output */
&numBytesDecrypted
);