gpt4 book ai didi

Android AES 解密和来自 iOS :javax. crypto.BadPaddingException 的数据:填充 block 已损坏

转载 作者:行者123 更新时间:2023-11-29 17:57:36 25 4
gpt4 key购买 nike

我试图在 Android 上解密从 iOS 发送的备份,异常 javax.crypto.BadPaddingException: pad block corrupted 显示在方法 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");
}

key 和 initialVector 以 base64 字符串形式从 iOS 发送。相关代码:

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);

关于 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;
}

感谢任何解决方案。

P.S.这是我们在 iOS 中设置加密的方式:

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

key 和IV推导方法:

(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
}

最佳答案

这是为解密/加密消息生成字符串的 Android 版本,它使用 Cipher 并生成正确的向量以产生与 iOS 相同的结果。对应本帖@亚历山大的iOS版本。

public class MyCrypter {

private static String TAG = "MyCrypter";

public MyCrypter() {

}

/**
* Encodes a String in AES-128 with a given key
*
* @param context
* @param password
* @param text
* @return String Base64 and AES encoded String
* @throws NoPassGivenException
* @throws NoTextGivenException
*/
public String encode(Context context, String password, String text)
throws NoPassGivenException, NoTextGivenException {
if (password.length() == 0 || password == null) {
throw new NoPassGivenException("Please give Password");
}

if (text.length() == 0 || text == null) {
throw new NoTextGivenException("Please give text");
}

try {
SecretKeySpec skeySpec = getKey(password);
byte[] clearText = text.getBytes("UTF8");

//IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
final byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

// Cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);

String encrypedValue = Base64.encodeToString(
cipher.doFinal(clearText), Base64.DEFAULT);
Log.d(TAG, "Encrypted: " + text + " -> " + encrypedValue);
return encrypedValue;

} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return "";
}

/**
* Decodes a String using AES-128 and Base64
*
* @param context
* @param password
* @param text
* @return desoded String
* @throws NoPassGivenException
* @throws NoTextGivenException
*/
public String decode(Context context, String password, String text)
throws NoPassGivenException, NoTextGivenException {

if (password.length() == 0 || password == null) {
throw new NoPassGivenException("Please give Password");
}

if (text.length() == 0 || text == null) {
throw new NoTextGivenException("Please give text");
}

try {
SecretKey key = getKey(password);

//IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
final byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

byte[] encrypedPwdBytes = Base64.decode(text, Base64.DEFAULT);
// cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes));

String decrypedValue = new String(decrypedValueBytes);
Log.d(TAG, "Decrypted: " + text + " -> " + decrypedValue);
return decrypedValue;

} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return "";
}

/**
* Generates a SecretKeySpec for given password
* @param password
* @return SecretKeySpec
* @throws UnsupportedEncodingException
*/
public SecretKeySpec getKey(String password)
throws UnsupportedEncodingException {


int keyLength = 128;
byte[] keyBytes = new byte[keyLength / 8];
// explicitly fill with zeros
Arrays.fill(keyBytes, (byte) 0x0);

// if password is shorter then key length, it will be zero-padded
// to key length
byte[] passwordBytes = password.getBytes("UTF-8");
int length = passwordBytes.length < keyBytes.length ? passwordBytes.length
: keyBytes.length;
System.arraycopy(passwordBytes, 0, keyBytes, 0, length);
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
return key;
}

public class NoTextGivenException extends Exception {
public NoTextGivenException(String message) {
super(message);
}

}

public class NoPassGivenException extends Exception {
public NoPassGivenException(String message) {
super(message);
}

}

}

关于Android AES 解密和来自 iOS :javax. crypto.BadPaddingException 的数据:填充 block 已损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18265503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com