1import java.nio.charset.Charset; 2import java.security.NoSuchAlgorithmException; 3import java.security.spec.InvalidKeySpecException; 4import java.security.spec.KeySpec; 5import java.util.Base64; 6import java.util.Random; 7 8import javax.crypto.SecretKey; 9import javax.crypto.SecretKeyFactory; 10import javax.crypto.spec.PBEKeySpec; 11 12/** 13 * pbkdf2_sha256加密验证算法 14 * @author Administrator 15 * 16 */ 17import org.slf4j.Logger; 18import org.slf4j.LoggerFactory; 19public class Pbkdf2Sha256 { 20 21 private static final Logger logger=LoggerFactory.getLogger(Pbkdf2Sha256.class); 22 //默认迭代计数为 20000 23 private static final Integer DEFAULT_ITERATIONS = 20000; 24 //算法名称 25 private static final String algorithm = "pbkdf2_sha256"; 26 27 /** 28 * 获取密文 29 * @param password 密码明文 30 * @param salt 加盐 31 * @param iterations 迭代计数 32 * @return 33 */ 34 private static String getEncodedHash(String password, String salt, int iterations) { 35 // Returns only the last part of whole encoded password 36 SecretKeyFactory keyFactory = null; 37 try { 38 keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); 39 } catch (NoSuchAlgorithmException e) { 40 logger.error("Could NOT retrieve PBKDF2WithHmacSHA256 algorithm",e); 41 } 42 KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt.getBytes(Charset.forName("UTF-8")), iterations, 256); 43 SecretKey secret = null; 44 try { 45 secret = keyFactory.generateSecret(keySpec); 46 } catch (InvalidKeySpecException e) { 47 logger.error("Could NOT generate secret key",e); 48 } 49 byte[] rawHash = secret.getEncoded(); 50 byte[] hashBase64 = Base64.getEncoder().encode(rawHash); 51 52 return new String(hashBase64); 53 } 54 /** 55 * 密文加盐 56 * @return String 57 */ 58 private static String getsalt(){ 59 int length = 12; 60 Random rand = new Random(); 61 char[] rs = new char[length]; 62 for(int i = 0; i < length; i++){ 63 int t = rand.nextInt(3); 64 if (t == 0) { 65 rs[i] = (char)(rand.nextInt(10)+48); 66 } else if (t == 1) { 67 rs[i] = (char)(rand.nextInt(26)+65); 68 } else { 69 rs[i] = (char)(rand.nextInt(26)+97); 70 } 71 } 72 return new String(rs); 73 } 74 /** 75 * rand salt 76 * iterations is default 20000 77 * @param password 78 * @return 79 */ 80 public static String encode(String password) { 81 return encode(password, getsalt()); 82 } 83 /** 84 * rand salt 85 * @param password 86 * @return 87 */ 88 public static String encode(String password,int iterations) { 89 return encode(password, getsalt(),iterations); 90 } 91 /** 92 * iterations is default 20000 93 * @param password 94 * @param salt 95 * @return 96 */ 97 public static String encode(String password, String salt) { 98 return encode(password, salt, DEFAULT_ITERATIONS); 99 } 100 101 /** 102 * 103 * @param password 密码明文 104 * @param salt 加盐 105 * @param iterations 迭代计数 106 * @return 107 */ 108 public static String encode(String password, String salt, int iterations) { 109 // returns hashed password, along with algorithm, number of iterations and salt 110 String hash = getEncodedHash(password, salt, iterations); 111 return String.format("%s$%d$%s$%s", algorithm, iterations, salt, hash); 112 } 113 114 /** 115 * 校验密码是否合法 116 * @param password 明文 117 * @param hashedPassword 密文 118 * @return 119 */ 120 public static boolean verification(String password, String hashedPassword) { 121 // hashedPassword consist of: ALGORITHM, ITERATIONS_NUMBER, SALT and 122 // HASH; parts are joined with dollar character ("$") 123 String[] parts = hashedPassword.split("\\$"); 124 if (parts.length != 4) { 125 // wrong hash format 126 return false; 127 } 128 Integer iterations = Integer.parseInt(parts[1]); 129 String salt = parts[2]; 130 String hash = encode(password, salt, iterations); 131 return hash.equals(hashedPassword); 132 }
java 实现 pbkdf2_sha256加密验证算法
Wesley13
2021-10-11
949 1 0
点赞
收藏
评论区
加载中...