如何使 Java 和 Objective-C (iPhone) 之间的 AES 加密相同? [英] How can I make my AES encryption identical between Java and Objective-C (iPhone)?

查看:19
本文介绍了如何使 Java 和 Objective-C (iPhone) 之间的 AES 加密相同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Objective-c 加密一个字符串,并使用 AES 在 Java 中加密同一个字符串,我看到了一些奇怪的问题.结果的第一部分匹配到某个点,但随后就不同了,因此当我将结果从 Java 解码到 iPhone 上时,它无法解密.

I am encrypting a string in objective-c and also encrypting the same string in Java using AES and am seeing some strange issues. The first part of the result matches up to a certain point but then it is different, hence when i go to decode the result from Java onto the iPhone it cant decrypt it.

我使用的源字符串是那么,这是什么废话.你知道吗?"使用密钥1234567890123456"

I am using a source string of "Now then and what is this nonsense all about. Do you know?" Using a key of "1234567890123456"

要加密的objective-c 代码如下: 注意:它是一个NSData 类别,因此假设该方法是在NSData 对象上调用的,因此'self' 包含要加密的字节数据.

The objective-c code to encrypt is the following: NOTE: it is a NSData category so assume that the method is called on an NSData object so 'self' contains the byte data to encrypt.

   - (NSData *)AESEncryptWithKey:(NSString *)key {
 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];

 NSUInteger dataLength = [self length];

 //See the doc: For block ciphers, the output size will always be less than or 
 //equal to the input size plus the size of one block.
 //That's why we need to add the size of one block here
 size_t bufferSize = dataLength + kCCBlockSizeAES128;
 void *buffer = malloc(bufferSize);

 size_t numBytesEncrypted = 0;
 CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
            keyPtr, kCCKeySizeAES128,
            NULL /* initialization vector (optional) */,
            [self bytes], dataLength, /* input */
            buffer, bufferSize, /* output */
            &numBytesEncrypted);
 if (cryptStatus == kCCSuccess) {
  //the returned NSData takes ownership of the buffer and will free it on deallocation
  return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
 }

 free(buffer); //free the buffer;
 return nil;
}

而java加密码是...

And the java encryption code is...

public byte[] encryptData(byte[] data, String key) {
    byte[] encrypted = null;

    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    byte[] keyBytes = key.getBytes();

    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

    try {
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);

        encrypted = new byte[cipher.getOutputSize(data.length)];
        int ctLength = cipher.update(data, 0, data.length, encrypted, 0);
        ctLength += cipher.doFinal(encrypted, ctLength);
    } catch (Exception e) {
        logger.log(Level.SEVERE, e.getMessage());
    } finally {
        return encrypted;
    }
}

objective-c 代码的十六进制输出是 -

The hex output of the objective-c code is -

7a68ea36 8288c73d f7c45d8d 22432577 9693920a 4fae38b2 2e4bdcef 9aeb8afe 69394f3e 1eb62fa7 74da2b5c 8d7b3c89 a295d306 f1f90349 6899ac34 63a6efa0

Java 输出是 -

7a68ea36 8288c73d f7c45d8d 22432577 e66b32f9 772b6679 d7c0cb69 037b8740 883f8211 748229f4 723984beb 50b5aea1 f17594c9 fad2d05e e0926805 572156d

如你所见,一切都很好 -

As you can see everything is fine up to -

7a68ea36 8288c73d f7c45d8d 22432577

我猜我有一些不同的设置,但不知道是什么,我尝试在 Java 端在 ECB 和 CBC 之间进行更改,但没有效果.

I am guessing I have some of the settings different but can't work out what, I tried changing between ECB and CBC on the java side and it had no effect.

谁能帮忙!?请....

Can anyone help!? please....

推荐答案

CCCrypt 既然采用了 IV,那么它是否不使用链接分组密码方法(例如 CBC)?这与您看到的一致:第一个块是相同的,但在第二个块中,Java 版本应用原始密钥进行加密,但 OSX 版本似乎使用了其他东西.

Since the CCCrypt takes an IV, does it not use a chaining block cipher method (such as CBC)? This would be consistant with what you see: the first block is identical, but in the second block the Java version applies the original key to encrypt, but the OSX version seems to use something else.

这里我看到了一个例子.似乎您需要将 kCCOptionECBMode 传递给 CCCrypt:

From here I saw an example. Seems like you need to pass the kCCOptionECBMode to CCCrypt:

ccStatus = CCCrypt(encryptOrDecrypt,
        kCCAlgorithm3DES,
        kCCOptionECBMode, <-- this could help
        vkey, //"123456789012345678901234", //key
        kCCKeySize3DES,
        nil, //"init Vec", //iv,
        vplainText, //"Your Name", //plainText,
        plainTextBufferSize,
        (void *)bufferPtr,
        bufferPtrSize,
        &movedBytes);

编辑 2:

我尝试了一些命令行,看看哪个是正确的.我以为我可以贡献它:

I played around with some command line to see which one was right. I thought I could contribute it:

$ echo "Now then and what is this nonsense all about. Do you know?" | openssl enc -aes-128-ecb -K $(echo 1234567890123456 | xxd -p) -iv 0 | xxd 
0000000: 7a68 ea36 8288 c73d f7c4 5d8d 2243 2577  zh.6...=..]."C%w
0000010: e66b 32f9 772b 6679 d7c0 cb69 037b 8740  .k2.w+fy...i.{.@
0000020: 883f 8211 7482 29f4 7239 84be b50b 5aea  .?..t.).r9....Z.
0000030: eaa7 519b 65e8 fa26 a1bb de52 083b 478f  ..Q.e..&...R.;G.

这篇关于如何使 Java 和 Objective-C (iPhone) 之间的 AES 加密相同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆