Обновление: найдено решение. Я скоро обновлю этот вопрос, указав фактический рабочий код и команду.
Клиент шифрует файл на стороне сервера с помощью C++, и мне нужно расшифровать его в приложении для iPhone.
Мой клиент может шифровать и расшифровывать на своей стороне, и я тоже на айфоне, но мы не можем расшифровать зашифрованный друг другом файл. Я видел много связанных вопросов по SO, но ни один из них не помог мне найти реализацию, которая работает одинаково с обеих сторон.
Я хочу вывести некоторые примеры значений, которые мы примем в качестве общей реализации.
Я пытался зашифровать файл с помощью openssl и расшифровать его с помощью какао, но не смог.
Вот что я использую для шифрования:
echo "123456789ABCDEFG" | openssl enc -aes-128-ecb -nosalt -K "41414141414141414141414141414141" -iv 0 > hello.txt.bin
Добавление опции -p к вызову openssl показывает, что используются ожидаемый ключ и iv:
key=41414141414141414141414141414141
iv =00000000000000000000000000000000
И для расшифровки какао (в категории NSData):
- (NSData *)AESDecryptWithKey:(NSString *)key {
char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//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(bufferSize);
size_t numBytesEncrypted = 0;
char iv[32];
for (int i = 0; i < 32; i++) {
iv[i] = 0;
}
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode + kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
iv, //"00000000000000000000000000000000" /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer); //free the buffer;
return nil;
}
называется так:
- (void)testBinaryFileDecryption {
NSString *databasePath = [[NSBundle mainBundle] pathForResource:@"hello" ofType:@"txt.bin"];
NSData *data = [NSData dataWithContentsOfFile:databasePath];
NSAssert(nil != data, @"Encrypted data, freshly loaded from file should not be nil");
NSData *plain = [data AESDecryptWithKey:@"AAAAAAAAAAAAAAAA"];
NSAssert(nil != plain, @"Decrypted plain data should not be nil");
NSLog(@"Result: '%@'", [[NSString alloc] initWithData:plain encoding:NSASCIIStringEncoding]);
}
Журналы результатов: Result: '4¨µ¢Ä½Pk£N
Какой вариант я забыл? Является ли кодировка NSData возвращенной чем-то другим, кроме NSASCIIStringEncoding ?