Я бился головой об стену с этим. Мне нужно закодировать приложение iPhone для шифрования 4-значного «пин-кода» с помощью 3DES в режиме ECB для передачи на веб-сервис, который, по моему мнению, написан на .NET.
+ (NSData *)TripleDESEncryptWithKey:(NSString *)key dataToEncrypt:(NSData*)encryptData {
NSLog(@"kCCKeySize3DES=%d", kCCKeySize3DES);
char keyBuffer[kCCKeySize3DES+1]; // room for terminator (unused)
bzero( keyBuffer, sizeof(keyBuffer) ); // fill with zeroes (for padding)
[key getCString: keyBuffer maxLength: sizeof(keyBuffer) encoding: NSUTF8StringEncoding];
// encrypts in-place, since this is a mutable data object
size_t numBytesEncrypted = 0;
size_t returnLength = ([encryptData length] + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
// NSMutableData* returnBuffer = [NSMutableData dataWithLength:returnLength];
char* returnBuffer = malloc(returnLength * sizeof(uint8_t) );
CCCryptorStatus ccStatus = CCCrypt(kCCEncrypt, kCCAlgorithm3DES , kCCOptionECBMode,
keyBuffer, kCCKeySize3DES, nil,
[encryptData bytes], [encryptData length],
returnBuffer, returnLength,
&numBytesEncrypted);
if (ccStatus == kCCParamError) NSLog(@"PARAM ERROR");
else if (ccStatus == kCCBufferTooSmall) NSLog(@"BUFFER TOO SMALL");
else if (ccStatus == kCCMemoryFailure) NSLog(@"MEMORY FAILURE");
else if (ccStatus == kCCAlignmentError) NSLog(@"ALIGNMENT");
else if (ccStatus == kCCDecodeError) NSLog(@"DECODE ERROR");
else if (ccStatus == kCCUnimplemented) NSLog(@"UNIMPLEMENTED");
if(ccStatus == kCCSuccess) {
NSLog(@"TripleDESEncryptWithKey encrypted: %@", [NSData dataWithBytes:returnBuffer length:numBytesEncrypted]);
return [NSData dataWithBytes:returnBuffer length:numBytesEncrypted];
}
else
return nil;
} }
Я получаю значение, зашифрованное с использованием приведенного выше кода, однако оно не совпадает со значением из веб-службы .NET.
Я считаю, что проблема заключается в том, что ключ шифрования, который мне предоставили разработчики веб-службы, имеет длину 48 символов.
Я вижу, что константа iPhone SDK "kCCKeySize3DES" равна 24. Поэтому я ПОДТВЕРЖДАЮ, но не знаю, что вызов API commoncrypto использует только первые 24 символа предоставленного ключа.
Это правильно?
Есть ли ЛЮБОЙ способ, которым я могу получить это, чтобы сгенерировать правильный зашифрованный пин-код? Я вывел байты данных из ПРИОР шифрования в base64, кодирующие его, и попытался сопоставить их с теми, которые были сгенерированы из кода .NET (с помощью разработчика .NET, который отправил мне вывод байтового массива). Ни байтовый массив не в кодировке base64, ни в окончательных строках в кодировке base64 не совпадают.