2010-05-06 14 views
0

我正在编写一个应用程序,它根据用户设置的密码对用户便笺进行加密和解密。我用于加密/解密的算法如下 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() 

加密工作良好,但试图解密它给

时例外 - 非法块大小

加密后,我将cipherText转换为HEX并将其存储在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 = "ABCDEF"; 

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)那么这会导致非法块大小例外 我ENV:Eclipse的

+0

请剪切并粘贴实际的代码,而不是尝试输入几个片段。然后我们可以将你的代码复制到我们最喜欢的环境中(Eclipse是我的)并且运用它。 – 2010-05-06 22:24:37

回答

1

的Android 1.6的代码,每当我产生“盐”时,

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

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

1

@Vamsi是正确的,它看起来像一个新的盐生成。这应该生成一次,并作为程序已知的方式存储。如果salt改变,那么加密/解密数据检查不会匹配。