seckit/src/App.tsx
2026-04-15 20:41:32 +08:00

297 lines
8.9 KiB
TypeScript

import { useState } from 'react'
import { sm3Digest, sm3Hmac } from './utils/algorithm/sm3'
import { sm4Encrypt, sm4Decrypt } from './utils/algorithm/sm4'
import { hexToUtf8, utf8ToHex } from './utils/convert'
function App() {
const [activeTab, setActiveTab] = useState('sm3')
// SM3 状态
const [sm3Message, setSm3Message] = useState('')
const [sm3Result, setSm3Result] = useState('')
const [sm3HmacKey, setSm3HmacKey] = useState('')
const [sm3HmacResult, setSm3HmacResult] = useState('')
// SM4 状态
const [sm4Key, setSm4Key] = useState('')
const [sm4Iv, setSm4Iv] = useState('')
const [sm4Message, setSm4Message] = useState('')
const [sm4Mode, setSm4Mode] = useState('ecb')
const [sm4PaddingMode, setSm4PaddingMode] = useState<'pkcs7' | 'none'>('pkcs7')
const [sm4Encrypted, setSm4Encrypted] = useState('')
const [sm4Decrypted, setSm4Decrypted] = useState('')
// 转换工具状态
const [hexInput, setHexInput] = useState('')
const [utf8Input, setUtf8Input] = useState('')
// SM3 计算
const handleCalculateSm3 = () => {
try {
const result = sm3Digest(sm3Message)
setSm3Result(result)
} catch (error) {
alert('计算失败: ' + error)
}
}
// SM3 HMAC 计算
const calculateSm3Hmac = () => {
try {
const result = sm3Hmac(sm3HmacKey, sm3Message)
setSm3HmacResult(result)
} catch (error) {
alert('HMAC 计算失败: ' + (error instanceof Error ? error.message : error))
}
}
// SM4 加密
const handleEncryptSm4 = () => {
try {
const encrypted = sm4Encrypt(sm4Message, sm4Key, sm4Mode, sm4Iv, sm4PaddingMode)
setSm4Encrypted(encrypted)
} catch (error) {
alert('加密失败: ' + (error instanceof Error ? error.message : error))
}
}
// SM4 解密
const handleDecryptSm4 = () => {
try {
const decrypted = sm4Decrypt(sm4Encrypted, sm4Key, sm4Mode, sm4Iv, sm4PaddingMode)
setSm4Decrypted(decrypted)
} catch (error) {
alert('解密失败: ' + (error instanceof Error ? error.message : error))
}
}
// Hex 转 UTF8
const handleHexToUtf8 = () => {
try {
const utf8 = hexToUtf8(hexInput)
setUtf8Input(utf8)
} catch (error) {
alert('转换失败: ' + error)
}
}
// UTF8 转 Hex
const handleUtf8ToHex = () => {
try {
const hex = utf8ToHex(utf8Input)
setHexInput(hex)
} catch (error) {
alert('转换失败: ' + error)
}
}
return (
<div className="app">
<h1></h1>
<div className="tabs">
<button
className={`tab ${activeTab === 'sm3' ? 'active' : ''}`}
onClick={() => setActiveTab('sm3')}
>
SM3
</button>
<button
className={`tab ${activeTab === 'sm4' ? 'active' : ''}`}
onClick={() => setActiveTab('sm4')}
>
SM4
</button>
<button
className={`tab ${activeTab === 'convert' ? 'active' : ''}`}
onClick={() => setActiveTab('convert')}
>
</button>
</div>
{/* SM3 面板 */}
{activeTab === 'sm3' && (
<div className="panel">
<h2>SM3 </h2>
<div className="form-group">
<label></label>
<textarea
value={sm3Message}
onChange={(e) => setSm3Message(e.target.value)}
placeholder="输入要计算的消息"
/>
</div>
<div className="form-group">
<label>SM3 </label>
<textarea
value={sm3Result}
readOnly
placeholder="SM3 计算结果将显示在这里"
/>
</div>
<button onClick={handleCalculateSm3}> SM3</button>
<div className="form-group" style={{ marginTop: '1.5rem' }}>
<label>HMAC </label>
<input
type="text"
value={sm3HmacKey}
onChange={(e) => setSm3HmacKey(e.target.value)}
placeholder="输入 HMAC 密钥 (hex)"
/>
</div>
<div className="form-group">
<label>SM3 HMAC </label>
<textarea
value={sm3HmacResult}
readOnly
placeholder="SM3 HMAC 计算结果将显示在这里"
/>
</div>
<button onClick={calculateSm3Hmac}> SM3 HMAC</button>
</div>
)}
{/* SM4 面板 */}
{activeTab === 'sm4' && (
<div className="panel">
<h2>SM4 </h2>
<div className="form-group">
<label> (16 hex)</label>
<input
type="text"
value={sm4Key}
onChange={(e) => setSm4Key(e.target.value)}
placeholder="输入 16 字节密钥 (32 位 hex)"
/>
</div>
<div className="form-group">
<label>IV (16 hex, CBC/CFB/GCM )</label>
<input
type="text"
value={sm4Iv}
onChange={(e) => setSm4Iv(e.target.value)}
placeholder="输入 16 字节 IV (32 位 hex)"
/>
</div>
<div className="form-group">
<label></label>
<div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
{['ecb', 'cbc', 'gcm'].map(mode => (
<button
key={mode}
className={sm4Mode === mode ? 'primary' : ''}
onClick={() => setSm4Mode(mode)}
>
{mode.toUpperCase()}
</button>
))}
</div>
</div>
<div className="form-group">
<label></label>
<div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
{(['pkcs7', 'none'] as const).map(paddingMode => (
<button
key={paddingMode}
className={sm4PaddingMode === paddingMode ? 'primary' : ''}
onClick={() => setSm4PaddingMode(paddingMode)}
>
{paddingMode}
</button>
))}
</div>
</div>
<div className="form-group">
<label></label>
<textarea
value={sm4Message}
onChange={(e) => setSm4Message(e.target.value)}
placeholder="输入要加密的消息"
/>
</div>
<div className="form-group">
<label></label>
<textarea
value={sm4Encrypted}
onChange={(e) => setSm4Encrypted(e.target.value)}
placeholder="输入加密结果 (hex)"
/>
</div>
<div className="form-group">
<label></label>
<textarea
value={sm4Decrypted}
readOnly
placeholder="解密结果将显示在这里"
/>
</div>
<div className="button-group">
<button onClick={handleEncryptSm4}></button>
<button onClick={handleDecryptSm4}></button>
</div>
</div>
)}
{/* 转换工具面板 */}
{activeTab === 'convert' && (
<div className="panel">
<h2>Hex / UTF8 </h2>
<div style={{ display: 'flex', gap: '1rem', marginBottom: '1rem' }}>
<div className="form-group" style={{ flex: 1 }}>
<label>UTF8 </label>
<textarea
value={utf8Input}
onChange={(e) => setUtf8Input(e.target.value)}
placeholder="输入 UTF8 字符串"
style={{ height: '200px' }}
/>
<button onClick={handleUtf8ToHex} style={{ marginTop: '0.5rem' }}>UTF8 Hex</button>
</div>
<div className="form-group" style={{ flex: 1 }}>
<label>Hex </label>
<textarea
value={hexInput}
onChange={(e) => setHexInput(e.target.value)}
placeholder="输入 hex 字符串"
style={{ height: '200px' }}
/>
<button onClick={handleHexToUtf8} style={{ marginTop: '0.5rem' }}>UTF8 Hex</button>
</div>
</div>
</div>
)}
{/* 页脚 */}
<footer style={{ marginTop: '2rem', padding: '1rem', borderTop: '1px solid #ccc', textAlign: 'center' }}>
<p>© 2026 </p>
<p>版本号: V1.0-{new Date().toISOString().slice(0, 19).replace(/[-:T]/g, '')}</p>
</footer>
</div>
)
}
export default App