首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Java解密用Objective-C加密的AES数据

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

Stack Overflow用户
提问于 2010-06-22 18:23:57
回答 3查看 4.6K关注 0票数 4

我尝试在Java中解密最初用Objective-C加密的数据。

还有其他问题提到了这一点,但他们真的很混乱,其中许多还没有解决,因此我将张贴我自己的。

这是加密数据的代码:

代码语言:javascript
复制
  - (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;
}

我执行此函数,并使用以下代码将结果数据写入磁盘:

代码语言:javascript
复制
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中,我使用以下代码来尝试实现相同的行为:

代码语言:javascript
复制
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加密的文件,我会得到一个错误填充异常。如果我打开包含加密内容的两个文件,它们是不同的:

Hallo Welt!用Java加密:96 C5 CB 51 39 B5 27 FB B3 93 BF 92 18 BB 16 9B

Hallo Welt!使用ObjC加密:A3 61 32 8E A5 E6 66 E0 41 64 89 25 62 D3 21 16

文件内容不应该是相同的吗?我想我在这两种语言中并没有得到算法的所有参数。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-06-22 20:51:07

  1. 我不认为CCCrypt支持对输入和输出使用相同的数组。尝试使用两个不同的数组。
  2. 你必须自己调整输出数组的大小(调用后numBytesEncrypted应该等于16 )。
  3. 据我所知,使用ECB-
  4. 而不是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。修复它,使两端都使用相同的算法,这样你就可以做得很好。
票数 2
EN

Stack Overflow用户

发布于 2010-06-22 18:49:05

你可能会有一堆问题。

在进行任何加密/解密时,您需要确保:

  • 字符串编码相同(您在两者中都使用UTF8,这很好)
  • 填充方案相同(一个上有pkcs5,另一个上有pkcs7 )

..and当然,加密方案是相同的。令人困惑的是,尽管评论讨论了使用AES256,但您的加密似乎使用了AES128。不确定Java版本使用的是什么

票数 1
EN

Stack Overflow用户

发布于 2010-06-22 20:54:05

这可能不会导致您的问题,但不管怎样,它是错误的:

代码语言:javascript
复制
   char * keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)

它定义了一个kCCKeySizeAES128 +1指针数组,而不是kCCKeySizeAES128 +1字节。碰巧,这是可以的,因为你得到的缓冲区比你需要的大四倍或八倍,这取决于你是编译32位还是64位。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3092190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档