目錄
PBKDF2
輸入?yún)?shù)
輸出參數(shù)
Java實(shí)現(xiàn)
測試結(jié)果
使用隨機(jī)的salt
?使用固定的salt
PBKDF2
PBKDF2 (Password-Based?Key?Derivation?Function?2),基于口令的密鑰派生函數(shù),可以防止字典攻擊和彩虹表攻擊。使用用戶持有的、不需要保存的秘密,比如口令,來推導(dǎo)對稱密鑰(消息的發(fā)送方和接收方持有相同的秘密,使用同樣的算法來推導(dǎo)對稱密鑰)。
key = generateKey(String algorithm, char[] password, byte[] salt, int iterationCount, int keyLength)
輸入?yún)?shù)
algorithm: 算法名,比如:?PBKDF2WithHmacSHA256?
password: 口令,字節(jié)數(shù)組/字符串
salt:鹽,安全生成的隨機(jī)字節(jié),推薦長度為128位
iterationCount:迭代次數(shù)
keyLength:派生密鑰長度
注意:生成密鑰所使用的類為javax.crypto.SecretKeyFactory(私密密鑰工廠類)??梢酝ㄟ^指定以下的算法來請求SecretKeyFactory實(shí)例.
輸出參數(shù)
根據(jù)請求長度派生的密鑰,如32字節(jié)(256位)的密鑰。
Java實(shí)現(xiàn)
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
public class PBKDF2Test {
//字節(jié)數(shù)組轉(zhuǎn)換成十六進(jìn)制字符串
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public static byte[] generateKey(String algorithm, char[] password, byte[] salt, int iterationCount, int keyLength)
throws NoSuchAlgorithmException, InvalidKeySpecException {
KeySpec keySpec = new PBEKeySpec(password, salt, iterationCount, keyLength);
SecretKeyFactory factory = SecretKeyFactory.getInstance(algorithm);
byte[] key = factory.generateSecret(keySpec).getEncoded();
return key;
}
public static void main(String[] args) {
String algorithm = "PBKDF2WithHmacSHA256";
SecureRandom sRandom = new SecureRandom();
byte[] salt = new byte[16];
sRandom.nextBytes(salt);
String pwdText = "password1";
int iterationCount = 50000;
int keyLength = 256;
try {
byte[] hash = PBKDF2Test.generateKey(algorithm,password.toCharArray(), salt, iterationCount, keyLength);
System.out.println("hash字節(jié)數(shù)組長度: " +hash.length);
System.out.println("Hex字符串輸出: "+ bytesToHex(hash));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
}
}
其中,algorithm使用的是PBKDF2WithHmacSHA256
String algorithm = "PBKDF2WithHmacSHA256";
salt是使用強(qiáng)隨機(jī)數(shù)生成器生成的長度為16的字節(jié)數(shù)組
SecureRandom sRandom = new SecureRandom();
byte[] salt = new byte[16];
sRandom.nextBytes(salt);
如果想基于指定的16進(jìn)制字符串來生成salt,需要使用 hexToByte(String hex) 函數(shù)來做轉(zhuǎn)換:
public static byte[] hexToByte(String hex){
int m = 0, n = 0;
int byteLen = hex.length() / 2;
byte[] ret = new byte[byteLen];
for (int i = 0; i < byteLen; i++) {
m = i * 2 + 1;
n = m + 1;
int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n));
ret[i] = Byte.valueOf((byte)intVal);
}
return ret;
}
?byte[] salt = hexToByte("aaef2d3f4d77ac66e9c5a6c3d8f921d1");
iterationCount,設(shè)置迭代次數(shù)為50000:
?int iterationCount = 50000;
?keyLength,設(shè)置派生密鑰長度為32字節(jié)/256位:
int keyLength = 256;
調(diào)用generateKey函數(shù),返回得到字節(jié)數(shù)組,并將其轉(zhuǎn)換成hex16進(jìn)制字符串:
bytesToHex(hash)
測試結(jié)果
使用隨機(jī)的salt
salt值是使用強(qiáng)隨機(jī)數(shù)生成器生成的,每次計(jì)算派生的密鑰是不一樣的。
第一次
?第二次
?使用固定的salt
salt值是基于hex字符串生成的,每次計(jì)算派生的密鑰是一樣的。
第一次和第二次文章來源:http://www.zghlxwxcb.cn/news/detail-611430.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-611430.html
到了這里,關(guān)于PBKDF2算法Java實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!