iOS上的Java和OpenSSL之间的不同AES256结果

时间:2017-03-19 06:03:47

标签: java ios security openssl aes

我有一个Java Web服务返回AES字节数组,其他函数返回带有此密钥的加密数据(字节数组),

从另一方面来说,我的ios应用程序调用获取AES密钥,然后调用获取加密数据,我在ios应用程序中包含OpenSSL lib,它将使用之前返回的AES密钥解密加密数据,

我的Java代码:

public static byte[] encryptWithAES(byte[] message, Key AESkey) throws Exception {
    byte[] decryptedMessage = null;
    try {
        Cipher encrypt = Cipher.getInstance("AES");
        encrypt.init(Cipher.ENCRYPT_MODE, AESkey);
        decryptedMessage = encrypt.doFinal(message);
    } catch (Exception ex) {
        System.err.println(ex.getMessage());
        throw ex;
    }
    return decryptedMessage;
}

ios中的代码:

unsigned char* ucKey = (unsigned char*)[self.AESKeyByte bytes];
AES_KEY wctx;
AES_set_encrypt_key(ucKey, 256, &wctx);
unsigned char* dataDec = (unsigned char *)calloc(size, sizeof(unsigned char*));
unsigned char* encryptedData = (unsigned char*)[value bytes];
AES_decrypt(encryptedData, dataDec, &wctx);
int sizeoddatadec = (int)strlen((char*)dataDec);
NSData* decryptedData = [NSData dataWithBytes:(const void *)dataDec length:sizeof(unsigned char)*sizeoddatadec];
NSString* stringDec = [NSString stringWithUTF8String:[decryptedData bytes]];

java上的AES密钥是:

  

ec d6 55 8b 43 70 e9 e4 9f 8c 62 d4 42 b2 c7 46 19 ff 13 c8 10 bb d0 04 ed e4 5b 78 11 1d c7 5d

     

纯文本是:“AChamieh”

ios上的self.AESKeyByte是:

  

ec d6 55 8b 43 70 e9 e4 9f 8c 62 d4 42 b2 c7 46 19 ff 13 c8 10 bb d0 04 ed e4 5b 78 11 1d c7 5d

     

解密数据:64 ee 6a b8 2c 29 16 17 9f 78 cf cb b6 ad e5 cd

请问这个问题有什么帮助吗?

2 个答案:

答案 0 :(得分:1)

对于ECB:

java代码将是

public static byte[] encryptWithAES(byte[] message, Key AESkey) throws Exception {
byte[] decryptedMessage = null;
try {
    Cipher encrypt = Cipher.getInstance("AES/ECB/PKCS5Padding"); // here is the change
    encrypt.init(Cipher.ENCRYPT_MODE, AESkey);
    decryptedMessage = encrypt.doFinal(message);
} catch (Exception ex) {
    System.err.println(ex.getMessage());
    throw ex;
}
return decryptedMessage;
}

对于CBC:

java代码将是

    public static byte[] encryptWithAES(byte[] message, Key AESkey, byte[] iv) throws Exception {
byte[] decryptedMessage = null;
try {
    Cipher encrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");  // here is the change
    encrypt.init(Cipher.ENCRYPT_MODE, AESkey,new IvParameterSpec(iv)); // and I add the iv for cbc
    decryptedMessage = encrypt.doFinal(message);
} catch (Exception ex) {
    System.err.println(ex.getMessage());
    throw ex;
}
return decryptedMessage;
}

修改(2):

取决于@zaph说先前的目标c将需要两次处理,

我更新了目标c代码:

- (NSData *) AESECB : (NSData *) data withKey :(NSData *) key : (CCOperation) operation{

CCCryptorStatus ccStatus = kCCSuccess;
NSUInteger dataLength = data.length;
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );

size_t numBytes = 0;

ccStatus = CCCrypt(operation,  // will pass kCCDecrypt or kCCEncrypt
                   kCCAlgorithmAES,
                   kCCOptionECBMode | kCCOptionPKCS7Padding,
                   [key bytes],
                   [key length],
                   nil,
                   [data bytes],
                   [data length],
                   buffer,
                   bufferSize,
                   &numBytes);

if( ccStatus == kCCSuccess )
{
    return [NSData dataWithBytes:buffer length:numBytes];
}

free(buffer);
return nil;
}

- (NSData *) AESCBC : (NSData *) data withKey: (NSData *) key : (CCOperation) operation{
CCCryptorStatus ccStatus = kCCSuccess;
NSUInteger dataLength = data.length;
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );

size_t numBytes = 0;

ccStatus = CCCrypt(operation,  // will pass kCCDecrypt or kCCEncrypt
                   kCCAlgorithmAES,
                   kCCOptionPKCS7Padding,
                   [key bytes],
                   [key length],
                   self.IV.bytes,
                   [data bytes],
                   [data length],
                   buffer,
                   bufferSize,
                   &numBytes);

if( ccStatus == kCCSuccess )
{
    return [NSData dataWithBytes:buffer length:numBytes];
}

free(buffer);
return nil;
}

非常感谢@zaph再次征求您的意见。

答案 1 :(得分:-1)

编辑(1)添加CBC:

对于AES 256 ECB:

我改变了我的Java代码如下:

public static byte[] encryptWithAES(byte[] message, Key AESkey) throws Exception {
byte[] decryptedMessage = null;
try {
    Cipher encrypt = Cipher.getInstance("AES/ECB/PKCS5Padding"); // here is the change
    encrypt.init(Cipher.ENCRYPT_MODE, AESkey);
    decryptedMessage = encrypt.doFinal(message);
} catch (Exception ex) {
    System.err.println(ex.getMessage());
    throw ex;
}
return decryptedMessage;
}

目标c如下:

- (NSData *) encryptAESECB:(NSData *) dataToEncrypt withKey:(NSData*) key{

CCCryptorStatus ccStatus = kCCSuccess;
// Begin to calculate bytesNeeded....
size_t bytesNeeded = 0;

ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithmAES, // for AES if you don't know the size
                   kCCOptionECBMode | kCCOptionPKCS7Padding,  // for AES ECB
                   [key bytes],
                   [key length],
                   nil,
                   [dataToEncrypt bytes],
                   [dataToEncrypt length],
                   NULL,   // for AES if  you don't know the size 
                   0,      // for AES if you don't know the size
                   &bytesNeeded); // for AES if you don't know the size, to get it

if(kCCBufferTooSmall != ccStatus){

    NSLog(@"Here it must return BUFFER TOO SMALL !!");
    return nil;
}

// .....End
// Now i do the real Crypting

char* cypherBytes = malloc(bytesNeeded);
size_t bufferLength = bytesNeeded;

if(NULL == cypherBytes)
    NSLog(@"cypherBytes NULL");

ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithmAES,
                   kCCOptionECBMode | kCCOptionPKCS7Padding,
                   [key bytes],
                   [key length],
                   nil,
                   [dataToEncrypt bytes],
                   [dataToEncrypt length],
                   cypherBytes,     // after get the AES size
                   bufferLength,    // after get the AES size
                   &bytesNeeded);   

if(kCCSuccess != ccStatus){
    NSLog(@"kCCSuccess NO!");
    return nil;
}

return [NSData dataWithBytes:cypherBytes length:bufferLength];
}

- (NSData *) decryptAESECB:(NSData *) dataToDecrypt withKey:(NSData*) key{

CCCryptorStatus ccStatus = kCCSuccess;
// Begin to calculate bytesNeeded....
size_t bytesNeeded = 0;

ccStatus = CCCrypt(kCCDecrypt,
                   kCCAlgorithmAES,
                   //0x0000,
                   kCCOptionECBMode | kCCOptionPKCS7Padding,
                   [key bytes],
                   [key length],
                   nil,
                   [dataToDecrypt bytes],
                   [dataToDecrypt length],
                   NULL,
                   0,
                   &bytesNeeded);


if(kCCBufferTooSmall != ccStatus){

    NSLog(@"Here it must return BUFFER TOO SMALL !!");
    return nil;
}

// .....End
// Now i do the real Crypting

char* cypherBytes = malloc(bytesNeeded);
size_t bufferLength = bytesNeeded;

if(NULL == cypherBytes)
    NSLog(@"cypherBytes NULL");

ccStatus = CCCrypt(kCCDecrypt,
                   kCCAlgorithmAES,
                   kCCOptionECBMode | kCCOptionPKCS7Padding,
                   [key bytes],
                   [key length],
                   nil,
                   [dataToDecrypt bytes],
                   [dataToDecrypt length],
                   cypherBytes,
                   bufferLength,
                   &bytesNeeded);

if(kCCSuccess != ccStatus){
    NSLog(@"kCCSuccess NO!");
    return nil;
}

return [NSData dataWithBytes:cypherBytes length:bufferLength];
}

对于AES 256 CBC:

我改变了我的Java代码如下:

public static byte[] encryptWithAES(byte[] message, Key AESkey, byte[] iv) throws Exception {
byte[] decryptedMessage = null;
try {
    Cipher encrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");  // here is the change
    encrypt.init(Cipher.ENCRYPT_MODE, AESkey,new IvParameterSpec(iv)); // and I add the iv for cbc
    decryptedMessage = encrypt.doFinal(message);
} catch (Exception ex) {
    System.err.println(ex.getMessage());
    throw ex;
}
return decryptedMessage;
}

目标c如下:

- (NSData *) encryptAESCBC:(NSData *) dataToEncrypt withKey:(NSData*) key{

CCCryptorStatus ccStatus = kCCSuccess;
// Begin to calculate bytesNeeded....
size_t bytesNeeded = 0;

ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithmAES,
                   kCCOptionPKCS7Padding, // for AES CBC
                   [key bytes],
                   [key length],
                   self.IV.bytes,   // You need to add the IV array
                   [dataToEncrypt bytes],
                   [dataToEncrypt length],
                   NULL,
                   0,
                   &bytesNeeded);

if(kCCBufferTooSmall != ccStatus){

    NSLog(@"Here it must return BUFFER TOO SMALL !!");
    return nil;
}

// .....End
// Now i do the real Crypting

char* cypherBytes = malloc(bytesNeeded);
size_t bufferLength = bytesNeeded;

if(NULL == cypherBytes)
    NSLog(@"cypherBytes NULL");

ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithmAES,
                   kCCOptionPKCS7Padding,  // for AES CBC
                   [key bytes],
                   [key length],
                   self.IV.bytes,    // You need to add the IV array
                   [dataToEncrypt bytes],
                   [dataToEncrypt length],
                   cypherBytes,
                   bufferLength,
                   &bytesNeeded);

if(kCCSuccess != ccStatus){
    NSLog(@"kCCSuccess NO!");
    return nil;
}

return [NSData dataWithBytes:cypherBytes length:bufferLength];
}

- (NSData *) decryptAESCBC:(NSData *) dataToDecrypt withKey:(NSData*) key{

CCCryptorStatus ccStatus = kCCSuccess;
// Begin to calculate bytesNeeded....
size_t bytesNeeded = 0;

ccStatus = CCCrypt(kCCDecrypt,
                   kCCAlgorithmAES,
                   kCCOptionPKCS7Padding,
                   [key bytes],
                   [key length],
                   self.IV.bytes,
                   [dataToDecrypt bytes],
                   [dataToDecrypt length],
                   NULL,
                   0,
                   &bytesNeeded);


if(kCCBufferTooSmall != ccStatus){

    NSLog(@"Here it must return BUFFER TOO SMALL !!");
    return nil;
}

// .....End
// Now i do the real Crypting

char* cypherBytes = malloc(bytesNeeded);
size_t bufferLength = bytesNeeded;

if(NULL == cypherBytes)
    NSLog(@"cypherBytes NULL");

ccStatus = CCCrypt(kCCDecrypt,
                   kCCAlgorithmAES,
                   kCCOptionPKCS7Padding,
                   [key bytes],
                   [key length],
                   self.IV.bytes,
                   [dataToDecrypt bytes],
                   [dataToDecrypt length],
                   cypherBytes,
                   bufferLength,
                   &bytesNeeded);

if(kCCSuccess != ccStatus){
    NSLog(@"kCCSuccess NO!");
    return nil;
}

return [NSData dataWithBytes:cypherBytes length:bufferLength];
}

我尝试了与此答案相关的内容:

Encrypting data with Objective-C and decrypt it with Java Problem

我尝试了这个解决方案,但它对我很好。