2016-07-25 60 views
0

我有兩個應用程序:Android和iOS(Objective-C)。我正在嘗試實施和加密系統,以便我可以在兩個應用程序上進行加密並在服務器應用程序中解密。問題是我使用AES128-ECB,但是我從android獲得的base64密鑰與我的目標c密鑰不匹配。我不知道我錯過了什麼。AES 128與Android和Objective C的兼容性

下面是摘錄: IOS

- (NSData*) EncryptAES: (NSString *) key{ 
char keyPtr[kCCKeySizeAES128+1]; 
bzero(keyPtr, sizeof(keyPtr)); 

[key getCString: keyPtr maxLength: sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 
size_t numBytesEncrypted = 0; 

NSUInteger dataLength = [self length]; 

size_t bufferSize = dataLength + kCCBlockSizeAES128; 
void *buffer = malloc(bufferSize); 
const unsigned char iv[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 

CCCryptorStatus result = CCCrypt(kCCEncrypt, 
           kCCAlgorithmAES128, 
           kCCOptionPKCS7Padding, 
           keyPtr, 
           kCCKeySizeAES128, 
           iv, 
           [self bytes], [self length], 
           buffer, bufferSize, 
           &numBytesEncrypted); 

if(result == kCCSuccess) 
    return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 
else { 
    NSLog(@"Failed AES"); 
} 
return nil; 
} 

然後:

NSString *pass = @"WORD_TO_ENCRYPT"; 
NSString *key = @"STRING_KEY"; 

//Encryption - APPROACH 1 
NSData *data = [pass dataUsingEncoding:NSUTF8StringEncoding]; 
NSData *encryptedData = [data EncryptAES:key]; 
NSString* encryptedBase64 = [self Base64Encode:encryptedData]; 

NSLog(@"%@", encryptedBase64); 

這是我的Java功能:

String plainTextKey = "STRING_KEY"; 
    String plainText = "WORD_TO_ENCRYPT"; 
    // Encrypt where jo is input, and query is output and ENCRPYTION_KEy is key 
    //String inputtt = "some clear text data"; 
    byte[] input = new byte[0]; 
    String skyKey; 

    input = plainText.getBytes("utf-8"); 
    MessageDigest md; 
    md = MessageDigest.getInstance("MD5"); 
    byte[] thedigest = md.digest(plainTextKey.getBytes("UTF-8")); 
    SecretKeySpec skc = new SecretKeySpec(thedigest, "AES"); 
    Cipher cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.ENCRYPT_MODE, skc); 
    byte[] cipherText = new byte[cipher.getOutputSize(input.length)]; 
    int ctLength = cipher.update(input, 0, input.length, cipherText, 0); 
    ctLength += cipher.doFinal(cipherText, ctLength); 
    String encode = Base64.encode(cipherText); 
    System.out.println(encode); 

我敲我的頭撞在牆上不知道我錯過了什麼。 在此先感謝您的幫助!

PS:我沒有什麼特別的原因使用AES128-ECB。如果多系統兼容性更簡單,我可以使用任何其他算法。

+0

爲什麼你不使用RNCryptor呢?它具有必要的兼容性,並且比此代碼更安全。 –

+0

在Obj-C中,在我看來你沒有使用ECB模式。您應該將Java代碼更改爲CBC模式。 –

+0

一般建議:**始終使用完全合格的密碼字符串**'Cipher.getInstance(「AES」);'可能導致不同的密碼,具體取決於默認安全提供程序。它很可能會導致''AES/ECB/PKCS5Padding'',但它不一定是。如果它改變,你將失去不同JVM之間的兼容性。 –

回答

0

在Android端,當你初始化密碼實例,則必須提供相應的配套IV。

byte[] iv = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
cipher.init(Cipher.ENCRYPT_MODE, skc, new IvParameterSpec(iv)); 
0

避免使用硬編碼IV作爲加密機制,至少在Android上。建議使用隨機數發生器,但如果不能提供隨機值,則至少應從密鑰構建IV。

在另一方面,你不會有,如果一切從密碼派生良好的安全性; 你需要在每條消息中有一些隨機性。

確保存儲在加密過程中使用,因此你可以正確地運用它放回解密IV。

byte[] iv = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
cipher.init(Cipher.ENCRYPT_MODE, skc, new IvParameterSpec(iv));