seckit/src/utils/algorithm/sm3.ts
2026-04-15 19:14:08 +08:00

96 lines
2.6 KiB
TypeScript

import { sumHex, fromHex } from 'gmsm-sm3js'
// 验证是否为有效的 hex 字符串
const isValidHex = (hex: string): boolean => {
return /^[0-9a-fA-F]*$/.test(hex) && hex.length % 2 === 0
}
// SM3 计算
export const sm3Digest = (message: string): string => {
try {
// 验证消息是否为有效的 hex 字符串
if (!isValidHex(message)) {
throw new Error('Invalid message: must be hex string')
}
console.log('Input hex message:', message)
// 将 hex 字符串转换为 Uint8Array
const messageBytes = fromHex(message)
// 使用 gmsm-sm3js 计算 SM3
const result = sumHex(messageBytes)
console.log('SM3 result:', result)
return result
} catch (error) {
console.error('SM3 digest error:', error)
throw error
}
}
// HMAC-SM3 计算
export const sm3Hmac = (key: string, message: string): string => {
try {
// 验证 key 和 message 是否为有效的 hex 字符串
if (!isValidHex(key)) {
throw new Error('Invalid key: must be hex string')
}
if (!isValidHex(message)) {
throw new Error('Invalid message: must be hex string')
}
console.log('Input key:', key)
console.log('Input message:', message)
// 将 hex 字符串转换为 Uint8Array
const keyBytes = fromHex(key)
const messageBytes = fromHex(message)
// 实现 HMAC-SM3 算法
const blockSize = 64 // SM3 块大小为 512 位 = 64 字节
// 处理密钥
let k: Uint8Array
if (keyBytes.length > blockSize) {
// 如果密钥长度超过块大小,对密钥进行 SM3 哈希
k = fromHex(sumHex(keyBytes))
} else {
// 否则,用 0 填充到块大小
k = new Uint8Array(blockSize)
k.set(keyBytes)
}
// 计算 inner padding
const ipad = new Uint8Array(blockSize)
for (let i = 0; i < blockSize; i++) {
ipad[i] = k[i] ^ 0x36
}
// 计算 outer padding
const opad = new Uint8Array(blockSize)
for (let i = 0; i < blockSize; i++) {
opad[i] = k[i] ^ 0x5c
}
// 计算 inner hash: SM3(ipad || message)
const innerData = new Uint8Array(ipad.length + messageBytes.length)
innerData.set(ipad)
innerData.set(messageBytes, ipad.length)
const innerHash = fromHex(sumHex(innerData))
// 计算 outer hash: SM3(opad || innerHash)
const outerData = new Uint8Array(opad.length + innerHash.length)
outerData.set(opad)
outerData.set(innerHash, opad.length)
const result = sumHex(outerData)
console.log('SM3 HMAC result:', result)
return result
} catch (error) {
console.error('SM3 HMAC error:', error)
throw error
}
}