2016-07-25 35 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));