一尘不染

解密使用Java用Objective-C AES加密的数据

java

我尝试解密最初使用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
你好!用ObjC加密:A3 61 32 8E A5 E6 66 E0 41 64 89 25 62 D3 21 16

文件内容不应该相同吗?我想我没有两种语言的算法所有参数都相同。

我需要更改Java代码以获得与Objective-C代码相同的结果,以便能够解密使用Objective-C加密的某些数据。


阅读 232

收藏
2020-12-03

共1个答案

一尘不染

  1. 我不认为CCCrypt支持使用相同的数组进行输入和输出。尝试使用两个不同的数组。
  2. 您必须自己调整输出数组的大小(调用后numBytesEncrypted应该等于16)。
  3. 据我所知,使用ECB加密而不是CBC的IV信号为空。只要您的输入小于15个字节,它就不会有任何区别,但是仍然应该解决。

编辑: 另一个问题:

  1. 您正在使用24字节密钥。AES-128需要128位= 16字节密钥,AES-192需要192位= 24字节密钥,而AES-256需要256位= 32字节密钥。您向CCCrypt明确指示AES-128,这意味着它会忽略密钥的最后8个字节。您只是将AES指示为Java,这意味着它将查看密钥大小来确定要使用的AES变体。由于您提供的是24字节密钥,因此它使用AES-192。修复它,以便两端使用相同的算法,您应该会很好。
2020-12-03