TOTP 算法是目前手机令牌客户端动态密码采用的算法,算法实现起来比较简单:
/**
* @param key 密钥,如用户名等
* @param length 需要的长度
* @param step 步长(有效期)
* @param timestamp 时间戳
* @return 动态密码
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static String generateTOTP(String key, int length, long step, long timestamp) throws NoSuchAlgorithmException, InvalidKeyException {
SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "RAW");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
// 将当前时间除步长作为消息文本进行hmac-sha1加密
String message = String.valueOf(timestamp / step);
byte[] hash = mac.doFinal(message.getBytes());
// 取最低四位组成的数字作为偏移量offset
int offset = hash[hash.length - 1] & 0xf;
// 取从最高为开始偏移offset的4字节同时去掉最高位组成的数字
int num = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
// 将得到的数字十进制形式最后几位作为最终的结果,如果位数不足高位用0补齐
String finalKey = String.format(String.format("%%0%dd", length), num);
if (finalKey.length() > length) {
finalKey = finalKey.substring(finalKey.length() - length);
}
return finalKey;
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于