Gia*_*ant 1 encryption passwords android cryptography
String text = name1.getText().toString();
// Sending side
byte[] data = null;
try {
data = text.getBytes("UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
String base64 = Base64.encodeToString(data, Base64.DEFAULT);
Run Code Online (Sandbox Code Playgroud)
能够加密密码,并将解密相同的密码,但我有一些想法,我不知道这是我第一次尝试加密密码.以这种方式加密密码是否安全,因为我尝试加密密码:zxc结果只是一个四字母密码(结果是enhj:)所以我想知道它是否是一种加密密码的安全方法.有关如何重新编写代码以使其更安全且不易解码以及如何解密加密密码的想法的任何想法?
更新:这是我在这里找到的加密和解密样本,但我不能让它运行.
加密
String password = "password";
int iterationCount = 1000;
int keyLength = 256;
int saltLength = keyLength / 8; // same size as key output
SecureRandom random = new SecureRandom();
byte[] salt = new byte[saltLength];
randomb.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt,
iterationCount, keyLength);
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
SecretKey key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = new byte[cipher.getBlockSize());
random.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ivParams);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes("UTF-8"));
Run Code Online (Sandbox Code Playgroud)
解密
String[] fields = ciphertext.split("]");
byte[] salt = fromBase64(fields[0]);
byte[] iv = fromBase64(fields[1]);
byte[] cipherBytes = fromBase64(fields[2]);
// as above
SecretKey key = deriveKeyPbkdf2(salt, password);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivParams = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, key, ivParams);
byte[] plaintext = cipher.doFinal(cipherBytes);
String plainrStr = new String(plaintext , "UTF-8");
Run Code Online (Sandbox Code Playgroud)
你已经标记了这个加密,密码和加密,所以我会这样回答它.
首先,Base64实际上不是加密,它只是编码 - 基本上从8位字节变为6位字节,并且您的测试是完美的 - 3*8位字符= 24位.24bits/6bits = 4 Base64个字符.我还验证了enhj确实是我自己的Base64 C实现的 zxc的Base64编码.有关此问题的进一步证据,请注意您未提供任何加密密钥!
其次,对于用户身份验证(我假设你正在做的事情),不要加密密码 - 这是Adobe刚刚犯的一个重大错误.对于用户身份验证,您无需再次查看用户密码 - 您只需要验证他们输入的内容与之前相同.因此,当他们第一次输入密码时,你加盐并哈希.下一次,你检索你第一次使用的盐,并用相同的盐(和迭代次数/工作因子)散列新输入的密码 - 如果结果与你记录的相同,让它们进入,因为提供相同的密码将得到相同的结果.
如何安全地散列密码的三个规范答案?是PBKDF2,Bcrypt和Scrypt.有关Android密码哈希的快速Google搜索出现了:
在Android上使用SHA256的PBKDF2指的是PBKDF2-HMAC-SHA-256的SpongyCastle 1.47+实现以及对PBKDF2-HMAC-SHA-1的引用.
PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(new SHA256Digest());
generator.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password), salt, iterations);
KeyParameter key = (KeyParameter)generator.generateDerivedMacParameters(keySizeInBits);
Run Code Online (Sandbox Code Playgroud)在Android的开发者BlogSpot的文章使用加密安全存储证书还引用PBKDF2-HMAC-SHA-1.
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 = 8000;
// Generate a 160-bit key
final int outputKeyLength = 160;
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations, outputKeyLength);
SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
return secretKey;
Run Code Online (Sandbox Code Playgroud)
}
在所有情况下,选择尽可能高的迭代计数/工作因子,因为您可以忍受延迟(使用所选算法的库,因为您可以遵守许可证).您的salt应该是8到16字节长度范围内的加密随机字节序列.
特别是对于PBKDF2,永远不要使用比本机散列大小更多的outputBytes,或者为攻击者提供比较优势 - SHA-1的本机大小为20字节,SHA-256为32字节,SHA-512本身为64字节.
如果您确实需要加密而不是身份验证,上面的"使用加密技术安全地存储凭据"链接也涵盖了这一点,尽管更好的答案是存储盐和迭代次数/工作因子并简单地从密码重新生成密钥时间 - 如果数据解密,那就很好.如果没有,那么,密码不好.
| 归档时间: |
|
| 查看次数: |
2523 次 |
| 最近记录: |