适用于Android 4.2及更早版本的PBKDF2WithHmacSHA1和DESede / CBC / PKCS5Padding

时间:2015-02-05 15:06:19

标签: java android security hash pbkdf2

在我的Android应用程序中,我想使用DESede / CBC / PKCS5Padding加密密码,我的解决方案适用于Lollipop(5.x),Android KitKat(4.4.x)和Android Jelly Bean(4.3.x)

private static final String KEY = "a2[..]";
private static final String SALT = "t[..]";
private static final String IV = "u[..]";
private static final String DES_EDE_PKCS5 = "DESede/CBC/PKCS5Padding"

public static String encrypt(String password) {
    byte[] byteSalt = Base64.decode(SALT, Base64.DEFAULT);
    byte[] bytesIv = Base64.decode(IV, Base64.DEFAULT);
    String mdp = "";        
    try {           
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");          
        KeySpec spec = new PBEKeySpec(KEY.toCharArray(), byteSalt, NB_ITER_RFC, SIZE_KEY);          
        SecretKey secretKey = factory.generateSecret(spec);             
        Cipher c = Cipher.getInstance(DES_EDE_PKCS5);           
        IvParameterSpec ivParam = new IvParameterSpec(bytesIv);         
        c.init(Cipher.ENCRYPT_MODE, secretKey, ivParam);                
        byte[] encrypted = c.doFinal(password.getBytes("UTF-8"));
        mdp = Base64.encodeToString(encrypted, Base64.DEFAULT);                 
    }
    catch [..]
    return mdp;
}

但它不适用于以下版本(4.2.x及以下版本),此加密密码似乎随机更改为例:

D/andro-Chiffrement-encrypt(10739): password chiffré = P7vWc+7hFuUaWQghVeO+zA==
D/andro-Chiffrement-encrypt(10739): password chiffré = jGr6nlvnYLd/AK/d7nkUrA==
D/andro-Chiffrement-encrypt(10739): password chiffré = I2weyEddIav7EulAiuQDbg==
D/andro-Chiffrement-encrypt(10739): password chiffré = HF7OFpUXYuwOm81WekReDg==

如何解决Android 4.2.x的这个问题呢?

我发现有图书馆Bouncy Castle,但我还没有找到如何实施' IV' (发电机矢量)。你有什么想法吗?

PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
gen.init(PBEParametersGenerator.PKCS12PasswordToBytes(passCharArray), byteSalt, NB_ITER_RFC);
KeyParameter params = (KeyParameter) gen.generateDerivedParameters(SIZE_KEY);
String password2 = Base64.encodeToString(params.getKey(), Base64.DEFAULT);

2 个答案:

答案 0 :(得分:0)

从Android 4.4开始,SecretKeyFactory API发生了变化。也许这可能会有所帮助:

  

在Android 4.3及更早版本的平台版本中,PBKDF2WithHmacSHA1密钥生成算法的javax.crypto.SecretKeyFactory实现仅使用密码中较低的8位Java字符。在Android 4.4中,算法被更改为使用Unicode字符中的所有可用位,符合PCKS#5中的建议。

     

此更改可能会影响使用对称加密并满足以下所有条件的应用程序:   1.使用SecretKeyFactory生成对称密钥,和   2.使用PBKDF2WithHmacSHA1作为SecretKeyFactory的密钥生成算法,   3.允许用于密码短语的Unicode输入

这里是原始文章:

https://plus.google.com/+AndroidDevelopers/posts/fTY97ekzn6Z

在这里,您可以阅读有关SecretKeyFactory Api的更改:

http://android-developers.blogspot.it/2013/12/changes-to-secretkeyfactory-api-in.html

答案 1 :(得分:0)

我已经测试了这个解决方案:http://android-developers.blogspot.fr/2013/08/some-securerandom-thoughts.html

这是由于PRNG(伪随机数发生器),但这个解决方案没有效果......

public class CustomApplication extends Application {    

    @Override
    public void onCreate() {        
        PRNGFixes.apply(); [..]
    }
}