Я новичок в криптографии и создаю несколько тестовых приложений, чтобы попытаться понять основы этого. Я не пытаюсь создавать алгоритмы с нуля, но я пытаюсь заставить две разные реализации AES-256 общаться друг с другом.
У меня есть база данных, которая была заполнена этой реализацией Javascript , хранящейся в Base64. Теперь я пытаюсь получить метод Objective-C для расшифровки его содержимого, но я немного растерялся относительно различий в реализациях. Я могу зашифровать / расшифровать в Javascript, и я могу зашифровать / расшифровать в Какао, но не могу сделать строку, зашифрованную в Javascript, расшифрованную в Какао или наоборот.
Полагаю, это связано с вектором инициализации, одноразовым номером, режимом работы счетчика или всем этим, что, прямо скажем, в данный момент не говорит со мной.
Вот что я использую в Objective-C, адаптированном в основном из этого и этого :
@implementation NSString (Crypto)
- (NSString *)encryptAES256:(NSString *)key {
NSData *input = [self dataUsingEncoding: NSUTF8StringEncoding];
NSData *output = [NSString cryptoAES256:input key:key doEncrypt:TRUE];
return [Base64 encode:output];
}
- (NSString *)decryptAES256:(NSString *)key {
NSData *input = [Base64 decode:self];
NSData *output = [NSString cryptoAES256:input key:key doEncrypt:FALSE];
return [[[NSString alloc] initWithData:output encoding:NSUTF8StringEncoding] autorelease];
}
+ (NSData *)cryptoAES256:(NSData *)input key:(NSString *)key doEncrypt:(BOOL)doEncrypt {
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256 + 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 = [input 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 numBytesCrypted = 0;
CCCryptorStatus cryptStatus =
CCCrypt(doEncrypt ? kCCEncrypt : kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionECBMode | kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
nil, // initialization vector (optional)
[input bytes], dataLength, // input
buffer, bufferSize, // output
&numBytesCrypted
);
if (cryptStatus == kCCSuccess) {
// the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
}
free(buffer); // free the buffer;
return nil;
}
@end
Конечно, вход предварительно декодируется Base64.
Я вижу, что каждое шифрование с тем же ключом и тем же содержимым в Javascript дает различную зашифрованную строку, что не имеет место в реализации Objective C, которая всегда дает одну и ту же зашифрованную строку. Я прочитал ответы этого поста , и это заставляет меня поверить, что я прав в отношении чего-то вроде инициализации вектора, но мне нужна ваша помощь, чтобы точно определить, что происходит.
Спасибо!