我试图解密服务器发送到我的应用程序的一些AES加密数据。
为了提炼问题,我编写了一个小型java程序来模拟服务器正在做什么。它使用AES加密一些测试数据,然后将其编码为Base64:
AesCipherService cipherService = new AesCipherService();
cipherService.setKeySize(128);
String stringKey = "2EE1F10212ADD4BE";
byte[] keyAsBytes = stringKey.getBytes();
String text = "text to encrypt";
byte[] encryptedBytes = cipherService.encrypt(text.getBytes(), keyAsBytes).getBytes();
String base64String = Base64.encodeToString(encryptedBytes);
System.out.println(base64String);
// Reverse the process to check can retrieve "text to encrypt":
byte[] bytesToDecode = Base64.decode(base64String);
byte[] decryptedBytes = cipherService.decrypt(bytesToDecode, keyAsBytes).getBytes();
String decryptedString = new String(decryptedBytes);
System.out.println(decryptedString);
运行时,这是输出:
R5UBpP30YjX9Ae2HoPb2Rrfi5rQJY2d0ac1 + zaIX5A4 =
要加密的文字
所以我可以成功加密数据,打印出来。然后,如果我没有加密它,原始文本就会显示出来,所以这里的一切都运转正常。
现在这是我的Obj-C代码,我尝试解密从Java代码加密的数据。我已经从NetBeans IDE输出窗口复制/粘贴了加密数据作为要解密的obj-c内容的源数据:
- (void) decryptData
{
NSData* dataToDecrypt = [[NSData alloc] initWithBase64EncodedString: @"R5UBpP30YjX9Ae2HoPb2Rrfi5rQJY2d0ac1+zaIX5A4=" options: 0];
NSString* key = @"2EE1F10212ADD4BE";
char keyPtr[kCCKeySizeAES128];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [dataToDecrypt length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES,
kCCOptionPKCS7Padding,
keyPtr,
kCCBlockSizeAES128,
keyPtr,
[dataToDecrypt bytes],
dataLength,
buffer,
bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
NSLog(@"Success");
NSData* unencryptedData = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
Byte *unencryptedAsBytes = (Byte*)malloc(unencryptedData.length);
memcpy(unencryptedAsBytes, [unencryptedData bytes], unencryptedData.length);
NSString *decryptedString = [NSString stringWithUTF8String:[unencryptedData bytes]];
NSLog(@"%@", decryptedString);
}
}
运行时,状态为kCCSuccess,numBytesDecrypted为32(与dataLength相同),但解密后的字符串不是“要加密的文本”,decryptedString为nil,如果我在Xcode的控制台中未加密AsBytes,则会显示:
“\一条Y | \ 376 \ 347cD * \ 320NC \ X14 \ x91C \ X88 \ 301 \ 341z \ XACA \ X11 \ 371
知道这里有什么问题吗?
答案 0 :(得分:2)
Java加密代码生成随机IV并使用它加密前缀。为了解密,IV从加密中分离出来。
以十六进制:
key: 32454531463130323132414444344245
iv: 479501A4FDF46235FD01ED87A0F6F646 (first 16 binary bytes of the full encryption)
encrypted: B7E2E6B40963677469CD7ECDA217E40E (rest of binary bytes of the full encryption)
decrypted: 7465787420746F20656E6372797074
代码:
NSData* fullEncrypted = [[NSData alloc] initWithBase64EncodedString: @"R5UBpP30YjX9Ae2HoPb2Rrfi5rQJY2d0ac1+zaIX5A4=" options: 0];
NSData *ivData = [fullEncrypted subdataWithRange:NSMakeRange(0, kCCBlockSizeAES128)];
NSData *encryptedData = [fullEncrypted subdataWithRange:NSMakeRange(kCCBlockSizeAES128, fullEncrypted.length-kCCBlockSizeAES128)];
NSLog(@"ivData: %@", ivData);
NSLog(@"encryptedData: %@", encryptedData);
NSData *keyData = [@"2EE1F10212ADD4BE" dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"keyData: %@", keyData);
NSMutableData *unencryptedData = [NSMutableData dataWithLength:encryptedData.length];
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES,
kCCOptionPKCS7Padding,
keyData.bytes, keyData.length,
ivData.bytes,
encryptedData.bytes, encryptedData.length,
unencryptedData.mutableBytes, unencryptedData.length,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
NSLog(@"Success");
unencryptedData.length = numBytesDecrypted;
NSLog(@"unencryptedData: %@", unencryptedData);
NSString *decryptedString = [[NSString alloc] initWithData:unencryptedData encoding:NSUTF8StringEncoding];
NSLog(@"decryptedString: %@", decryptedString);
}
输出:
ivData: 479501a4 fdf46235 fd01ed87 a0f6f646
encryptedData: b7e2e6b4 09636774 69cd7ecd a217e40e
keyData: 32454531 46313032 31324144 44344245
Success
unencryptedData: 74657874 20746f20 656e6372 79707400
decryptedString: text to encrypt