2010-06-22 127 views
4

我尝试解密最初使用Java中的Objective-C加密的数据。解密使用Objective-C与Java进行AES加密的数据

还有其他问题提到这一点,但他们真的很混乱,他们中的许多都还没有解决,因此我会张贴自己的。

这是对数据加密的代码:

- (int) encryptWithKey: (NSString *) key 
    { 
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise 
    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]; 

    // encrypts in-place, since this is a mutable data object 
    size_t numBytesEncrypted = 0; 
    CCCryptorStatus result = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, 
            keyPtr, kCCKeySizeAES128, 
            NULL /* initialization vector (optional) */, 
            [self mutableBytes], [self length], /* input */ 
            [self mutableBytes], [self length]+32, /* output */ 
            &numBytesEncrypted); 
    return numBytesEncrypted; 
} 

我执行此功能,并将所得数据刻录到光盘,此代码写:

NSString* strTest = @"Hallo Welt!"; 
NSLog(@"strTest = %@", strTest); 

NSMutableData *protectedData = [NSMutableData dataWithData:[strTest dataUsingEncoding:NSUTF8StringEncoding]]; 

int laenge = [protectedData encryptWithKey:@"keykeykeykeykeykeykeykey"]; 

NSData* dataOutput = [[NSData alloc] initWithBytes:[protectedData bytes] length:laenge]; 


[dataOutput writeToFile:@"/encryptedFileObjC" atomically:YES]; 

在Java中我使用此代码试图达到相同的行为:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
String keyString = "keykeykeykeykeykeykeykey"; 
byte[] keyBytes = keyString.getBytes("UTF-8"); 

cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), 
     new IvParameterSpec(new byte[16])); 
byte[] resultBytes = cipher.doFinal("Hallo Welt!".getBytes("UTF8")); 

FileOutputStream out = 
     new FileOutputStream(new File("encryptedFileJava")); 
out.write(resultBytes); 
out.close(); 

如果我现在尝试解密文件是e通过Objective-C加密我得到了一个不好的填充异常。如果我用加密的内容打开这两个文件,它们是不同的:

Hallo Welt!用Java加密:96 C5 CB 51 39 B5 27 FB B3 93 BF 92 18 BB 16 9B
Hallo Welt!使用ObjC加密:A3 61 32 8E A5 E6 66 E0 41 64 89 25 62 D3 21 16

文件内容不应该相同吗?我想我没有在两种语言中得到相同算法的所有参数。

我需要修改Java代码以获得与Objective-C代码相同的结果,以便能够解密用Objective-C加密的一些数据。

+0

我很惊讶Java代码可以运行,因为keyBytes数组只有长度15,而不是有效的AES密钥长度。 – 2010-06-22 11:07:35

+0

密钥长度为什么是15?我假设长度是24字节,我对加密非常陌生,所以如果我有一个基本的误解,请纠正我。 – Janusz 2010-06-22 12:10:23

+0

@Janusz你可以帮我拿这个加密/解密的示例代码,我的电子邮件ID是 - [email protected]。我面临同样的问题。谢谢。 – 2013-06-28 08:15:08

回答

2
  1. 我不会假设CCCrypt支持使用相同的数组输入和输出。尝试使用两个不同的数组。
  2. 你必须自己调整输出数组的大小(在调用之后numBytesEncrypted应该等于16)。
  3. 据我所见,一个空IV信号使用ECB加密而不是CBC。只要你的输入小于15字节,它应该没有什么区别,但它仍然是你应该修复的东西。

编辑:另一个问题:

  • 您正在使用24字节密钥。AES-128需要128位= 16字节密钥,AES-192需要192位= 24字节密钥,AES-256需要256位= 32字节密钥。您明确地将AES-128指示为CCCrypt,这意味着它将忽略密钥的最后8个字节。您只是将AES指示为Java,这意味着它会根据密钥大小来决定使用哪种AES变体。由于您提供的是24字节密钥,因此它使用AES-192。修复它,使两端使用相同的算法,你应该是好的。
  • +0

    你是对的我编辑了我关于NSDATA管理的问题。现在我得到正确的长度,但仍然是一个完全不同的加密 – Janusz 2010-06-22 13:15:49

    +0

    也使用Java中没有IV和PKCS5padding的ECB在加密中给出了相同的结果,没有任何附近的ObjC结果。 – Janusz 2010-06-22 13:18:15

    +0

    谢谢,如果我只使用密钥的前16个字节,它就像一个魅力。 – Janusz 2010-06-23 06:57:17

    1

    您可能有一堆问题。

    在做任何加密/解密,你需要确保:

    • 字符串编码是相同的(你使用两个UTF8,这就是好)
    • 填补方案是相同的(你PKCS5上一个和PKCS7另一方面)
    • 初始化向量是相同的(你对其他的一个空和空字节)

    当然..和所述加密方案是相同的。混淆你的加密似乎使用AES128,虽然评论讨论使用AES256。不知道什么Java版本正在使用

    +0

    我的填充问题是它似乎在java中没有可用的pkcs5padding。其他一些网页建议使用pkcs5,因为它几乎相同。 – Janusz 2010-06-22 10:57:29

    +1

    “PKCS#5填充”和“PKCS#7填充”是同义词。 – 2010-06-22 12:51:53

    1

    这可能无助于你的问题,但它是错的呢:

    char * keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused) 
    

    定义kCCKeySizeAES128 + 1个指针,不kCCKeySizeAES128 + 1个的字节数组。碰巧,因为你得到的缓冲区比你需要的大四倍或八倍,这取决于你是在编译32位还是64位。

    +0

    我不能做任何与objc代码的数据已被加密 – Janusz 2010-06-22 12:56:28