Android的AES解密和数据的iOS:javax.crypto.BadPaddingException:垫块损坏 [英] Android AES decryption and data from iOS:javax.crypto.BadPaddingException: pad block corrupted

查看:1548
本文介绍了Android的AES解密和数据的iOS:javax.crypto.BadPaddingException:垫块损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解密Android上的备份这是从的iOS 发,异常 javax.crypto.BadPaddingException:垫块损坏是在表现方法doFinal。

 公共字符串解密(字节[]的密文,SecretKey的关键,字节[] initialVector)抛出异常{
    密密码= Cipher.getInstance(AES / CBC / PKCS7Padding);
    IvParameterSpec ivParameterSpec =新IvParameterSpec(initialVector);
    cipher.init(Cipher.DECRYPT_MODE,钥匙,ivParameterSpec);
    密文= cipher.doFinal(密文);    返回新的String(密文,UTF-8);
}

键和initialVector从iOS版用base64字符串发送。相关code:

 公共静态的byte []德codeWebSafe(String s)将抛出Base64De $ C $ {crException
    字节[]字节= s.getBytes();
    返回德codeWebSafe(字节,0,bytes.length);
}字节[] IV = Base64.de codeWebSafe(enciv);
字节[] =盐Base64.de codeWebSafe(encsalt);
字节[]数据= Base64.de codeWebSafe(encda​​ta);
SecretKey的关键= Security.getExistingKey(口令,盐);
原字符串= aes.decrypt(数据,键,IV);

和有关Security.getExistingKey:

 公共静态SecretKey的getExistingKey(字符串密码,字节[]盐)抛出​​异常{
    SecretKey的关键= NULL;
    KeySpec keySpec =新PBEKeySpec(password.toCharArray(),盐,10000,256);
    SecretKeyFactory的KeyFactory = SecretKeyFactory.getInstance(PBKDF2WithHmacSHA1);    字节[] = keyBytes新的字节[32];
    keyBytes = keyFactory.generateSecret(keySpec)根据.getEn codeD();
    关键=新SecretKeySpec(keyBytes,AES);    返回键;
}

THX任何解决方案。

P.S.This是我们如何在iOS中设置的加密:

  CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
self.encryptionKey.bytes,kCCKeySizeAES128,
self.encryptionIV.bytes,[RAWDATA字节] DATALENGTH,
/ *输入* /缓冲区,缓冲区大小,/ *输出* /&安培; numBytesEncrypted);

键和IV推导方法:

 (NSData的*)keyForPassword:(* NSString的)密码盐:(NSData的*)盐{
NSMutableData *
derivedKey = [NSMutableData dataWithLength:kCCKeySizeAES128];INT结果= CCKeyDerivati​​onPBKDF(kCCPBKDF2,//算法
                              password.UTF8String,
                              password.length,
                              salt.bytes,//盐
                              salt.length,// saltLen
                              kCCPRFHmacAlgSHA1,// PRF
                              kPBKDFRounds,//发
                              derivedKey.mutableBytes,// derivedKey
                              derivedKey.length); // derivedKeyLen
}


解决方案

我可以看到在路上几个不同你生成密钥:


  • 在iOS上,16字节的键/生成128位;在Android的是256位。

  • 在iOS上,密码为UTF-8 EN codeD而Android无论是采用低8位或每个字符的全16位(我不知道具体算法的细节)。

  • 在iOS上,你传递无效长度的密码(字符数,而不是字节的UTF-8编码数)。

您更好地投入一些时间更好的相匹配的密钥生成和密钥解密前相比。

I tried to decrypt a backup on Android which is sent from iOS, and the exception javax.crypto.BadPaddingException: pad block corrupted is showed at method doFinal.

public  String decrypt(byte[] cipherText, SecretKey key, byte [] initialVector) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
    IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
    cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
    cipherText = cipher.doFinal(cipherText);

    return new String(cipherText, "UTF-8");
}

The key and initialVector are sent from iOS in base64 string. Related code:

public static byte[] decodeWebSafe(String s) throws Base64DecoderException {
    byte[] bytes = s.getBytes();
    return decodeWebSafe(bytes, 0, bytes.length);
}

byte[] iv = Base64.decodeWebSafe(enciv);
byte[] salt = Base64.decodeWebSafe(encsalt);
byte[] data = Base64.decodeWebSafe(encdata);
SecretKey key = Security.getExistingKey(password, salt);
String original = aes.decrypt(data, key, iv);

And about the Security.getExistingKey:

public static SecretKey getExistingKey(String password, byte[] salt) throws Exception{
    SecretKey key= null;
    KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 10000, 256);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

    byte[] keyBytes=new byte[32]; 
    keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
    key= new SecretKeySpec(keyBytes, "AES");

    return key;
}

Thx for any solutions.

P.S.This is how we set the encryption in iOS:

CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
self.encryptionKey.bytes, kCCKeySizeAES128,
self.encryptionIV.bytes, [rawData bytes], dataLength, 
/* input */buffer, bufferSize, /* output */&numBytesEncrypted);

the key and IV derivation method:

(NSData *)keyForPassword:(NSString *)password salt:(NSData *)salt {
NSMutableData *
derivedKey = [NSMutableData dataWithLength:kCCKeySizeAES128];

int result = CCKeyDerivationPBKDF(kCCPBKDF2,            // algorithm
                              password.UTF8String, 
                              password.length,  
                              salt.bytes,           // salt
                              salt.length,          // saltLen
                              kCCPRFHmacAlgSHA1,    // PRF
                              kPBKDFRounds,         // rounds
                              derivedKey.mutableBytes, // derivedKey
                              derivedKey.length); // derivedKeyLen
}

解决方案

I can see several differences in the way you generate the key:

  • In iOS, a key of 16 bytes / 128 bit is generated; in Android it's 256 bits.
  • In iOS, the password is UTF-8 encoded while Android either takes the lower 8 bits or the full 16 bits of each characters (I don't know the details of the specific algorithm).
  • In iOS, you pass an invalid length for the password (the number of characters instead the number of bytes in UTF-8 encoding).

You better invest some time in better matching the key generation and comparing the keys before decryption.

这篇关于Android的AES解密和数据的iOS:javax.crypto.BadPaddingException:垫块损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆