方案3:(针对使用了应用锁、文件锁等功能,需要用户输入密码才能访问的功能)
存储密钥最安全的方式,无疑是存储在用户的脑子里。对于一些特殊功能的应用,比如文件锁、应用锁等,可以使用PBKDF2函数,把用户输入的密码做为参数来生成加密密钥。如果用户的密码足够复杂,那么这个方案应该是很安全的。谷歌实现了这个方案。
http://android-developers.blogspot.com/2013/02/using-cryptography-to-store-credentials.html
代码:
public static SecretKey generateKey(char[] passphraseOrPin, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
// Number of PBKDF2 hardening rounds to use. Larger values increase
// computation time. You should select a value that causes computation
// to take >100ms.
final int iterations = 1000;
// Generate a 256-bit key
final int outputKeyLength = 256;
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(“PBKDF2WithHmacSHA1″);
KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations, outputKeyLength);
SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
return secretKey;
}
Note:这个salt是一个随机的数,可以和需要加密的数据一块存储在应用私有目录。
关于SecureRandom的使用
Android 4.2之前使用的SecureRandom是由Bouncy Castle-based 实现的,4.2开始默认由OpenSSL提供。下面这段代码在4.2之前的系统上,调用secureRandom.nextInt()生成的数字是相同的,随机性被破坏。
SecureRandom secureRandom = new SecureRandom();
byte[] b = new byte[] { (byte) 1 };
secureRandom.setSeed(b);
// Prior to Android 4.2, the next line would always return the same number!
System.out.println(secureRandom.nextInt());
建议在使用SecureRandom时不要使用setSeed()来设置seed。
最安全的方案:http://android-developers.blogspot.co.uk/2013/08/some-securerandom-thoughts.html