Задача c декодировать зашифрованные данные
Я получаю часть зашифрованного json от вызова веб-службы rest. Следующий код ruby правильно декодирует ответ обратно в json. Полученные данные сначала декодируются base64, затем первые 16 байт обрабатываются как iv, а остальные-как данные. Ключ сначала де-заколдовывается (отсутствие лучшего выражения).
encrypted = Base64.decode64(res) #base 64 decode
de_cipher = OpenSSL::Cipher::Cipher.new("AES-128-CBC")
de_cipher.decrypt
de_cipher.key = [key].pack('H*') #de-hex the key
de_cipher.iv = encrypted[0..15] # the first 16 bytes is the IV
descrypted = de_cipher.update(encrypted) << de_cipher.final;
json_string = descrypted[16 .. (descrypted.size - 1)] #taking away the first 16, rest is data
Рубиновый код был просто подготовкой для меня, чтобы понять данные. Что мне действительно нужно, так это вызвать этот веб-сервис и декодировать в objective c на iPhone. Но пока что там не повезло, и я не могу расшифровать полученную строку до правильного json. Ниже то, что у меня есть:
//self.responseData is received through NSURLConnection, pretty sure it is piece together correctly. But there is rn at the end, which made it not correct length for base64, so I took the last two bytes away.
NSString *str = [[[NSString alloc] initWithData:[self.responseData subdataWithRange:(NSRange){0, self.responseData.length - 2}] encoding:NSUTF8StringEncoding] autorelease];
NSLog(@"tvm get token response = [%@]",str);
//CreateDataWithHexString is something I found on stack overflow, supposed to reverse hex string to binary
NSString * key =[[MyProfile sharedInstance] getOneProperty:TVM_KEY];
//NSData *keyData = [[NSData alloc] initWithBase64EncodedString:key options:0];
NSData *keyData = [self CreateDataWithHexString:key];
//base64 decode the received string
NSData * whole = [[NSData alloc] initWithBase64EncodedString:str options:0];
NSData * iv = [whole subdataWithRange:(NSRange){0, 16}];
NSData * data = [whole subdataWithRange:(NSRange){16, whole.length - 16}];
CCCryptorStatus ccStatus = kCCSuccess;
size_t cryptBytes = 0; // Number of bytes moved to buffer.
NSMutableData *dataOut = [NSMutableData dataWithLength:data.length + kCCBlockSizeAES128];
ccStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyData.bytes,
kCCKeySizeAES128,
iv.bytes,
data.bytes,
data.length,
dataOut.mutableBytes,
dataOut.length,
&cryptBytes);
if (ccStatus == kCCSuccess) {
dataOut.length = cryptBytes;
NSString * json = [dataOut base64Encoding];
NSLog(@"json = [%@]", dataOut);
NSLog(@"json = [%@]", json);
}
else {
Ключ изначально был сгенерирован следующим образом, надеюсь, что имеет смысл де-hex, как указано выше:
CFUUIDRef theKeyUUID = CFUUIDCreate(NULL);
CFStringRef keyuuid = CFUUIDCreateString(NULL, theKeyUUID);
CFRelease(theKeyUUID);
//server side expect a uuid without those -'s.
NSString * key = [(__bridge NSString *)keyuuid stringByReplacingOccurrencesOfString:@"-" withString:@""];
CFRelease(keyuuid);
Ниже CreateDataWithHexString я нашел на переполнение стека, надеюсь, что это для правильной цели здесь:
-(NSData *)CreateDataWithHexString:(NSString *)inputString
{
NSUInteger inLength = [inputString length];
unichar *inCharacters = alloca(sizeof(unichar) * inLength);
[inputString getCharacters:inCharacters range:NSMakeRange(0, inLength)];
UInt8 *outBytes = malloc(sizeof(UInt8) * ((inLength / 2) + 1));
NSInteger i, o = 0;
UInt8 outByte = 0;
for (i = 0; i < inLength; i++) {
UInt8 c = inCharacters[i];
SInt8 value = -1;
if (c >= '0' && c <= '9') value = (c - '0');
else if (c >= 'A' && c <= 'F') value = 10 + (c - 'A');
else if (c >= 'a' && c <= 'f') value = 10 + (c - 'a');
if (value >= 0) {
if (i % 2 == 1) {
outBytes[o++] = (outByte << 4) | value;
outByte = 0;
} else {
outByte = value;
}
} else {
if (o != 0) break;
}
}
return [[NSData alloc] initWithBytesNoCopy:outBytes length:o freeWhenDone:YES];
}