2013-08-22 136 views
0

我无法解密使用IOS加密的JAVA中的mp3文件。下面是用于IOS文件加密代码:IOS中的AES加密解密为JAVA

- (NSData *)AES256EncryptWithKey:(NSData *) audioData: (NSString *)key{ 
// 'key' should be 32 bytes for AES256, will be null-padded otherwise 
char keyPtr[kCCKeySizeAES256 + 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 = [audioData 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, kCCKeySizeAES256, 
             NULL /* initialization vector (optional) */, 
             [audioData 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; 

}

而下面是我使用解密在Java文件中的代码,我调用这个函数来解密:

private static final byte[] SALT = { 
     (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32, 
     (byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03 
}; 
private static final int ITERATION_COUNT = 65536; 
private static final int KEY_LENGTH = 256; 
public static void encryptOrDecrypt(String key, byte[] is, OutputStream os) throws Throwable { 
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    KeySpec spec = new PBEKeySpec(key.toCharArray(), SALT, ITERATION_COUNT, KEY_LENGTH); 
    SecretKey tmp = factory.generateSecret(spec); 
    SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
    Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 
    IvParameterSpec ivspec = new IvParameterSpec(iv); 
    ecipher.init(Cipher.DECRYPT_MODE, secret, ivspec); 

    byte[] encrypted = ecipher.doFinal(is); 
    os.write(encrypted); 
    os.close(); 

}

而且,这里是我使用在这两个关键:

“3STI 5F2F41608581SO3D8UN346D2E81009THEC7E220RAD9F9C29BPY738956BBE”

当我运行Java应用程序我得到这个错误:

javax.crypto.BadPaddingException: Given final block not properly padded 
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..).... 

任何帮助将不胜感激。

感谢 迈克尔

+0

至少如果你关心你的代码的安全性,它会由加密领域的专家审查,这就是我所做的,我一直在做密码多年。否则,不要试图使用加密。 – zaph

回答

1

简答

你的Java代码使用PBKDF2改变你的钥匙,它看起来像你的OBJ-C代码不是(虽然你还没有给予足够的代码对我们来说是肯定的)。所以关键是不同的,这就是为什么你的解密不起作用。

主动提供免费咨询

看起来你只是切割和来自不同地方粘贴代码并没有真正理解它。如果你想使用加密,你需要明白你在做什么,或者你可以把事情弄糟(即使他们似乎在工作)。如果你不知道密码和密钥之间的区别,或者PBKDF2是什么以及何时使用它,那么你需要做一些基础研究。

+0

感谢您的回应,没有问题我会做更多的研究,您需要确认哪些额外的代码?我可以粘贴这个以供您查看。 –

+0

您需要在Obj-C代码中显示您的密钥。正如我所说的,在使用它之前,Java代码会使用PBKDF2转换密钥。它看起来像Obj-C没有。所以要么在Obj-C代码中使用PBKDF2,要么将其从Java代码中取出。 – zindorsky

+0

或者更简洁地说,请确保'AES256EncryptWithKey' Obj-C函数中的'key'参数与''encryptOrDecrypt' Java函数中'secret'变量的字节序列相同。 – zindorsky