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

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

问题描述

我正在加密目标c中的字符串,并使用AES加密Java中的相同字符串,并看到一些奇怪的问题。结果的第一部分匹配到某一点,但是它是不同的,因此当我将Java的结果解码到iPhone上时,它无法解密它。



我正在使用一个源字符串现在这个废话是什么,你知道吗?
使用1234567890123456的密钥



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

   - (NSData *)AESEncryptWithKey:(NSString * )键{
char keyPtr [kCCKeySizeAES128 + 1]; //用于终结器的空间(未使用)
bzero(keyPtr,sizeof(keyPtr)); //填充零(用于填充)

//获取密钥数据
[key getCString:keyPtr maxLength:sizeof(keyPtr)encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [self length];

//查看文档:对于块密码,输出大小始终小于或等于输入大小加上一个块的大小。
//这就是为什么我们需要在这里添加一个块的大小
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void * buffer = malloc(bufferSize);

size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,kCCAlgorithmAES128,kCCOptionPKCS7Padding,
keyPtr,kCCKeySizeAES128,
NULL / *初始化向量(可选)* /,
[self bytes],dataLength, * input * /
buffer,bufferSize,/ * output * /
& numBytesEncrypted);
if(cryptStatus == kCCSuccess){
//返回的NSData获取缓冲区的所有权,并在释放后释放它
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}

free(buffer); //释放缓冲区;
return nil;
}

Java加密代码是...

  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.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;
}
}

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

  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 

正如你可以看到的一切都是罚款到 -

  7a68ea36 8288c73d f7c45d8d 22432577 

我猜想我有一些不同的设置,但是无法解决什么,我尝试在Java端在ECB和CBC之间切换,并且没有任何效果。



任何人都可以帮忙!请求....

解决方案

由于CCCrypt采用IV,它不使用链接块密码方法(如CBC )?这将与您所看到的一致:第一个块是相同的,但在第二个块中,Java版本应用原始密钥进行加密,但是OSX版本似乎使用其他东西。



编辑:



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

  ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionECBMode,< - 这可以帮助
vkey,//123456789012345678901234,// key
kCCKeySize3DES,
nil,//init Vec,// iv,
vplainText,//Your Name,// plainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
& movedBytes);

编辑2:



用一些命令行来看看哪一个是正确的。我以为我可以做出贡献:

  $ echo现在这个废话是什么,你知道吗? | 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 .. Qe。& ... R.; G。


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.

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

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;
}

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;
    }
}

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

and the java output is -

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

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....

解决方案

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.

EDIT:

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);

EDIT 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.

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

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