我尝试解密最初用Java中的Objective-C加密的数据。
还有其他问题提到这一点,但它们真的很混乱,其中很多都没有解决,因此我会发布自己的。
这是加密数据的代码:
- (int) encryptWithKey: (NSString *) key
{
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
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];
// encrypts in-place, since this is a mutable data object
size_t numBytesEncrypted = 0;
CCCryptorStatus result = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self mutableBytes], [self length], /* input */
[self mutableBytes], [self length]+32, /* output */
&numBytesEncrypted );
return numBytesEncrypted;
}
我执行此功能并使用以下代码将结果数据写入光盘:
NSString* strTest = @"Hallo Welt!";
NSLog(@"strTest = %@", strTest);
NSMutableData *protectedData = [NSMutableData dataWithData:[strTest dataUsingEncoding:NSUTF8StringEncoding]];
int laenge = [protectedData encryptWithKey:@"keykeykeykeykeykeykeykey"];
NSData* dataOutput = [[NSData alloc] initWithBytes:[protectedData bytes] length:laenge];
[dataOutput writeToFile:@"/encryptedFileObjC" atomically:YES];
在Java中,我使用此代码尝试实现相同的行为:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
String keyString = "keykeykeykeykeykeykeykey";
byte[] keyBytes = keyString.getBytes("UTF-8");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"),
new IvParameterSpec(new byte[16]));
byte[] resultBytes = cipher.doFinal("Hallo Welt!".getBytes("UTF8"));
FileOutputStream out =
new FileOutputStream(new File("encryptedFileJava"));
out.write(resultBytes);
out.close();
如果我现在尝试解密通过Objective-C加密的文件,我会得到一个错误的填充异常。如果我用加密内容打开这两个文件,它们是不同的:
哈洛韦尔特!用Java加密:96 C5 CB 51 39 B5 27 FB B3 93 BF 92 18 BB 16 9B
A3 61 32 8E A5 E6 66 E0 41 64 89 25 62 D3 21 16
文件内容不应该相同吗?我想我在两种语言中没有得到算法的所有参数。
我需要更改Java代码以获得与Objective-C代码相同的结果,以便能够解密使用Objective-C加密的某些数据。
答案 0 :(得分:2)
编辑:另一个问题:
答案 1 :(得分:1)
你可能有很多问题。
进行任何加密/解密时,您需要确保:
..当然加密方案是相同的。令人困惑的是,您的加密似乎是使用AES128,尽管评论讨论使用AES256。不确定Java版本正在使用什么
答案 2 :(得分:1)
这可能不会导致您的问题,但无论如何都是错误的:
char * keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)
它定义了一个kCCKeySizeAES128 + 1 指针的数组,而不是kCCKeySizeAES128 + 1个字节。实际上,它是正常的,因为你得到的缓冲区比你需要的大4或8倍,这取决于你是编译32位还是64位。