加密解密算法可以使用AES128 加上salt来进行处理。
需要产生随机盐以提高安全性。同时为了解密,需要把随机盐+加密后的密码拼串存储到数据库或硬盘文件。可以把salt作为prefix or postfix.
记住密码功能:
需要在硬盘上指定路径,建立用户登录记录文件,每次登录时,如果用户选择记住密码,就把username, pass加密后存储到文件中。
再次登陆时,从该文件读取用户最近一次的输入密码,然后自动填充。可以使用linkedhashmap构建类似于cache的结构,方便按登录次序对登录的用户进行快速查找。
当用户更改密码时,需要删除硬盘上的登录记录文件,然后重新写入新用户名,密码,使用append to file方式。保证每次读取该文件时获取的都是最新的用户密码。
=================================
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package fm.Util;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.SecureRandom;
/**
*
* @author WeiZhang
*/
public class SecurityUtil {
private static final String ALGO = "AES";
private static final int ITERATIONS = 2;
//16 bytes make 128 bits key size
private static final byte[] keyValue =
new byte[] { 'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };
//18 bytes output salt with length 24 with no padding
private static final int saltSize = 24;
//AES 128 bits encryption with salt
public static String encryptPassword(String data) throws Exception
{
String salt = generateSalt();
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
String valueToEnc = null;
String eValue = data;
for (int i = 0; i < ITERATIONS; i++) {
valueToEnc = salt + eValue;
byte[] encValue = c.doFinal(valueToEnc.getBytes());
eValue = Base64.getEncoder().encodeToString(encValue);
}
return salt + eValue;
}
//AES 128 bits decryption with salt
public static String decryptPassword(String encryptedData) throws Exception
{
String salt = encryptedData.substring(0, saltSize);
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
String dValue = null;
String valueToDecrypt = encryptedData.substring(saltSize);
for (int i = 0; i < ITERATIONS; i++)
{
byte[] decordedValue = Base64.getDecoder().decode(valueToDecrypt);
byte[] decValue = c.doFinal(decordedValue);
dValue = new String(decValue).substring(salt.length());
valueToDecrypt = dValue;
}
return dValue;
}
private static Key generateKey() throws Exception
{
Key key = new SecretKeySpec(keyValue, ALGO);
return key;
}
//generate random salt with 18 bytes, output has length 24 in base64 with no padding
public static String generateSalt()
{
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[18];
random.nextBytes(bytes);
String salt = Base64.getEncoder().encodeToString(bytes);
return salt;
}
}