前端实现TOTP加密


6位TOTP密码

import CryptoJS from 'crypto-js/crypto-js'
function generateTOTP(secret) {
	const timeStep = 30; // 时间步长(秒)
	const currentTimestamp = Math.floor(Date.now() / 1000); // 获取当前时间的时间戳(秒)
	let timeStepCount = Math.floor(currentTimestamp / timeStep); // 计算当前时间步数
	// 将时间步数转换为字节数组
	const timeStepBytes = new Array(8);
	for (let i = 7; i >= 0; i--) {
		timeStepBytes[i] = timeStepCount & 0xff;
		timeStepCount >>>= 8;
	}

	// 通过 CryptoJS 计算 HMAC-SHA1
	const hmacDigest = CryptoJS.HmacSHA1(CryptoJS.lib.WordArray.create(Uint8Array.from(timeStepBytes)), CryptoJS.enc.Hex.parse(secret));

	// 截取哈希的最后4位,得到偏移值
	const offset = hmacDigest.words[hmacDigest.words.length - 1] & 0xf;

	// 从偏移值开始的4个字节中提取动态密码
	const dynamicPasswordBytes = hmacDigest.words.slice(offset, offset + 4);

	// 将动态密码的字节数组转换为整数
	let dynamicPasswordInt = ((dynamicPasswordBytes[0] & 0x7f) << 24 |
		(dynamicPasswordBytes[1] & 0xff) << 16 |
		(dynamicPasswordBytes[2] & 0xff) << 8 |
		(dynamicPasswordBytes[3] & 0xff)) % 1000000;

	// 将密码转换为6位数字的字符串
	let formattedPassword = dynamicPasswordInt.toString().padStart(6, '0');

	return formattedPassword;
}

function convertToHex(secret) {
	const byteArray = [];
	for (let i = 0; i < secret.length; i++) {
		byteArray.push(secret.charCodeAt(i));
	}
	let hexString = byteArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
	return hexString;
}

//使用16进制的密钥调用 generateTOTP 函数
const secret = '你的密钥';  // 替换为你的密钥
const TOTP = generateTOTP(convertToHex(secret));
console.log('TOTP:', TOTP);

目前前端实现了,后端好像解密不了。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐