96 lines
2.6 KiB
TypeScript
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
|
|
}
|
|
}
|