P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
HMAC_hash(secret, A(2) + seed) +
HMAC_hash(secret, A(3) + seed) + ...
其中 A(0) = seed A(i) = HMAC_hash(secret, A(i-1))
hash 为 md5,SHA128,SHA256...
PRF(secret, label, seed) = P_<hash>(secret, label + seed)
JAVA实现
/**
* PRF算法
* @param secretKey MAC加密秘钥 new SecretKeySpec(秘钥字节, "HmacSHA256")
* @param label 标签
* @param seed 种子
* @param outPutLen 输出的长度
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static byte[] prf(SecretKey secretKey, byte[] label, byte[] seed, int outPutLen) throws NoSuchAlgorithmException, InvalidKeyException {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(secretKey);
byte[] labelSeed = ByteArrayUtil.byteMergerAll(label, seed);
byte[] output = new byte[outPutLen];
int offset = 0;
// 先获取一次A(1)
byte[] A0 = mac.doFinal(labelSeed);
while (offset < outPutLen) {
// 第一次循环得到 temp = HMAC_hash(secret, A(1) + seed)
byte[] temp = mac.doFinal(ByteArrayUtil.byteMergerAll(A0, labelSeed));
System.arraycopy(temp, 0, output, offset, Math.min(temp.length, outPutLen - offset));
offset += temp.length;
// 对A0加密一次得到A1 关键就是不停的对A0进行加密
A0 = mac.doFinal(A0);
}
return output;
}