【问题标题】:Exception - Illegal Block size during decryption(Android)例外 - 解密期间非法块大小(Android)
【发布时间】:2010-05-06 09:49:44
【问题描述】:

我正在编写一个应用程序,它根据用户设置的密码加密和解密用户笔记。我使用以下算法进行加密/解密 1. PBEWithSHA256And256BitAES-CBC-BC 2. PBEWithMD5And128BitAES-CBC-OpenSSL

    e_Cipher = Cipher.getInstance(PBEWithSHA256And256BitAES-CBC-BC);
    d_Cipher = Cipher.getInstance(PBEWithSHA256And256BitAES-CBC-BC);
    e_Cipher.init()
    d_Cipher.init()

加密运行良好,但在尝试解密时会给出

例外 - 非法块大小

加密后,我将密文转换为十六进制并将其存储在 sqlite 数据库中。我在解密期间从 sqlite 数据库中检索正确的值,但是在调用 d_Cipher.dofinal() 时会引发异常。

我以为我错过了指定填充并试图检查其他可用的密码算法,但我找不到。

所以请您提供一些有关 Android 支持的密码算法和填充的知识?如果我使用的算法可以用于填充,我应该如何指定填充机制? 我对加密还很陌生,所以尝试了BouncyCastle.java 中提供的几种算法,但没有成功。

这里要求的是代码

public class CryptoHelper {
private static final String TAG = "CryptoHelper";
//private static final String PBEWithSHA256And256BitAES = "PBEWithSHA256And256BitAES-CBC-BC";
//private static final String PBEWithSHA256And256BitAES = "PBEWithMD5And128BitAES-CBC-OpenSSL";
private static final String PBEWithSHA256And256BitAES = "PBEWithMD5And128BitAES-CBC-OpenSSLPBEWITHSHA1AND3-KEYTRIPLEDES-CB";
private static final String randomAlgorithm = "SHA1PRNG";
public static final int SALT_LENGTH = 8;
public static final int SALT_GEN_ITER_COUNT = 20;
private final static String HEX = "0123456789ABCDEF";

private Cipher e_Cipher; 
private Cipher d_Cipher;
private SecretKey secretKey;
private byte salt[];

public CryptoHelper(String password) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeySpecException {
    char[] cPassword = password.toCharArray();
    PBEKeySpec pbeKeySpec = new PBEKeySpec(cPassword);
    PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, SALT_GEN_ITER_COUNT);
    SecretKeyFactory keyFac = SecretKeyFactory.getInstance(PBEWithSHA256And256BitAES);
    secretKey = keyFac.generateSecret(pbeKeySpec);

    SecureRandom saltGen = SecureRandom.getInstance(randomAlgorithm);
    this.salt = new byte[SALT_LENGTH];
    saltGen.nextBytes(this.salt);

    e_Cipher = Cipher.getInstance(PBEWithSHA256And256BitAES);
    d_Cipher = Cipher.getInstance(PBEWithSHA256And256BitAES);

    e_Cipher.init(Cipher.ENCRYPT_MODE, secretKey, pbeParamSpec);
    d_Cipher.init(Cipher.DECRYPT_MODE, secretKey, pbeParamSpec);
}

public String encrypt(String cleartext) throws IllegalBlockSizeException, BadPaddingException {
    byte[] encrypted = e_Cipher.doFinal(cleartext.getBytes());

    return convertByteArrayToHex(encrypted);
}

public String decrypt(String cipherString) throws IllegalBlockSizeException {
    byte[] plainText = decrypt(convertStringtobyte(cipherString));

    return(new String(plainText));
}

public byte[] decrypt(byte[] ciphertext) throws IllegalBlockSizeException {        
    byte[] retVal = {(byte)0x00};
    try {
        retVal = d_Cipher.doFinal(ciphertext);
    } catch (BadPaddingException e) {
        Log.e(TAG, e.toString()); 
    }
    return retVal;
}


public String convertByteArrayToHex(byte[] buf) {
    if (buf == null)  
        return "";
    StringBuffer result = new StringBuffer(2*buf.length);  

    for (int i = 0; i < buf.length; i++) {
        appendHex(result, buf[i]);  
    }
    return result.toString();
}

private static void appendHex(StringBuffer sb, byte b) {
    sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}

private static byte[] convertStringtobyte(String hexString) {
    int len = hexString.length()/2;
    byte[] result = new byte[len];
    for (int i = 0; i < len; i++) {
        result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
    }
    return result;
}

public byte[] getSalt() {
    return salt;
}

public SecretKey getSecretKey() {
    return secretKey;
}

public static SecretKey createSecretKey(char[] password) throws NoSuchAlgorithmException, InvalidKeySpecException {
    PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
    SecretKeyFactory keyFac = SecretKeyFactory.getInstance(PBEWithSHA256And256BitAES);
    return keyFac.generateSecret(pbeKeySpec);
}

}

我将调用mCryptoHelper.decrypt(String str) 然后这会导致非法块大小异常 我的环境:Eclipse 上的 Android 1.6

【问题讨论】:

  • 请剪切并粘贴实际代码,而不是尝试输入一些片段。然后我们可以将你的代码复制到我们最喜欢的环境中(Eclipse 是我的)并进行练习。

标签: android encryption


【解决方案1】:

在代码中,每次我生成“盐”时,

SecureRandom saltGen = SecureRandom.getInstance(randomAlgorithm);
this.salt = new byte[SALT_LENGTH];
saltGen.nextBytes(this.salt);

因此加密和解密密码之间存在差异。所以它给出了错误 Bad Pad block 或 Padding block 损坏。 如果我将 Salt 声明为某个已知值,则它工作正常。

【讨论】:

    【解决方案2】:

    @Vamsi 是正确的,看起来正在生成新的 Salt。这应该生成一次,并存储为程序已知的。如果盐值发生变化,则加密/解密数据检查将不匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-15
      • 2019-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-17
      • 2011-04-21
      • 1970-01-01
      相关资源
      最近更新 更多