sm2 改进
This commit is contained in:
parent
c9d66a77b1
commit
20c27b2e5b
397
src/App.tsx
397
src/App.tsx
@ -59,8 +59,10 @@ function App() {
|
||||
const [sm2Message, setSm2Message] = useState('')
|
||||
const [sm2Encrypted, setSm2Encrypted] = useState('')
|
||||
const [sm2Decrypted, setSm2Decrypted] = useState('')
|
||||
const [sm2SignMessage, setSm2SignMessage] = useState('')
|
||||
const [sm2Signature, setSm2Signature] = useState('')
|
||||
const [sm2VerifyResult, setSm2VerifyResult] = useState('')
|
||||
const [sm2ActiveTab, setSm2ActiveTab] = useState('encrypt')
|
||||
|
||||
// 转换工具状态
|
||||
const [hexInput, setHexInput] = useState('')
|
||||
@ -172,8 +174,8 @@ function App() {
|
||||
// SM2 签名
|
||||
const handleSignSm2 = () => {
|
||||
try {
|
||||
console.log('开始签名,消息:', sm2Message, '私钥:', sm2PrivateKey)
|
||||
const signature = sm2Sign(sm2Message, sm2PrivateKey)
|
||||
console.log('开始签名,消息:', sm2SignMessage, '私钥:', sm2PrivateKey)
|
||||
const signature = sm2Sign(sm2SignMessage, sm2PrivateKey)
|
||||
console.log('签名成功,结果:', signature)
|
||||
setSm2Signature(signature)
|
||||
} catch (error) {
|
||||
@ -185,8 +187,8 @@ function App() {
|
||||
// SM2 验证签名
|
||||
const handleVerifySm2 = () => {
|
||||
try {
|
||||
console.log('开始验签,消息:', sm2Message, '签名:', sm2Signature, '公钥:', sm2PublicKey)
|
||||
const result = sm2Verify(sm2Message, sm2Signature, sm2PublicKey)
|
||||
console.log('开始验签,消息:', sm2SignMessage, '签名:', sm2Signature, '公钥:', sm2PublicKey)
|
||||
const result = sm2Verify(sm2SignMessage, sm2Signature, sm2PublicKey)
|
||||
console.log('验签成功,结果:', result)
|
||||
setSm2VerifyResult(result ? '验证成功' : '验证失败')
|
||||
} catch (error) {
|
||||
@ -382,8 +384,8 @@ function App() {
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>公钥</label>
|
||||
<textarea
|
||||
value={sm2PublicKey}
|
||||
readOnly
|
||||
placeholder="公钥将显示在这里"
|
||||
onChange={(e) => setSm2PublicKey(e.target.value)}
|
||||
placeholder="输入公钥 (hex) 或点击生成密钥对"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
@ -399,181 +401,246 @@ function App() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 加密/解密 */}
|
||||
<div style={{ marginBottom: '20px', padding: '15px', backgroundColor: '#2d2d2d', borderRadius: '8px' }}>
|
||||
<h3 style={{ color: '#e0e0e0', marginBottom: '10px' }}>加密/解密</h3>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>消息</label>
|
||||
<textarea
|
||||
value={sm2Message}
|
||||
onChange={(e) => setSm2Message(e.target.value)}
|
||||
placeholder="输入要加密的消息 (hex)"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
resize: 'vertical',
|
||||
minHeight: '100px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>加密结果</label>
|
||||
<textarea
|
||||
value={sm2Encrypted}
|
||||
onChange={(e) => setSm2Encrypted(e.target.value)}
|
||||
placeholder="输入加密结果 (hex)"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
resize: 'vertical',
|
||||
minHeight: '100px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>解密结果</label>
|
||||
<textarea
|
||||
value={sm2Decrypted}
|
||||
readOnly
|
||||
placeholder="解密结果将显示在这里"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
resize: 'vertical',
|
||||
minHeight: '100px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="button-group" style={{ display: 'flex', gap: '10px' }}>
|
||||
{/* SM2 功能选项卡 */}
|
||||
<div style={{ marginBottom: '20px' }}>
|
||||
<div style={{ display: 'flex', borderBottom: '1px solid #333', marginBottom: '20px', backgroundColor: '#2d2d2d', borderRadius: '8px 8px 0 0', overflow: 'hidden' }}>
|
||||
<button
|
||||
onClick={handleEncryptSm2}
|
||||
className={`tab ${sm2ActiveTab === 'encrypt' ? 'active' : ''}`}
|
||||
onClick={() => setSm2ActiveTab('encrypt')}
|
||||
style={{
|
||||
padding: '10px 20px',
|
||||
padding: '12px 24px',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
background: '#f59e0b',
|
||||
color: '#121212',
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
background: sm2ActiveTab === 'encrypt' ? '#333' : '#2d2d2d',
|
||||
cursor: 'pointer',
|
||||
transition: 'background 0.3s ease',
|
||||
flex: 1
|
||||
fontSize: '16px',
|
||||
fontWeight: sm2ActiveTab === 'encrypt' ? 'bold' : 'normal',
|
||||
color: sm2ActiveTab === 'encrypt' ? '#f59e0b' : '#e0e0e0',
|
||||
outline: 'none',
|
||||
transition: 'all 0.3s ease',
|
||||
borderBottom: sm2ActiveTab === 'encrypt' ? '3px solid #f59e0b' : 'none'
|
||||
}}
|
||||
>
|
||||
加密
|
||||
加密/解密
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDecryptSm2}
|
||||
className={`tab ${sm2ActiveTab === 'sign' ? 'active' : ''}`}
|
||||
onClick={() => setSm2ActiveTab('sign')}
|
||||
style={{
|
||||
padding: '10px 20px',
|
||||
padding: '12px 24px',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
background: '#f59e0b',
|
||||
color: '#121212',
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
background: sm2ActiveTab === 'sign' ? '#333' : '#2d2d2d',
|
||||
cursor: 'pointer',
|
||||
transition: 'background 0.3s ease',
|
||||
flex: 1
|
||||
fontSize: '16px',
|
||||
fontWeight: sm2ActiveTab === 'sign' ? 'bold' : 'normal',
|
||||
color: sm2ActiveTab === 'sign' ? '#f59e0b' : '#e0e0e0',
|
||||
outline: 'none',
|
||||
transition: 'all 0.3s ease',
|
||||
borderBottom: sm2ActiveTab === 'sign' ? '3px solid #f59e0b' : 'none'
|
||||
}}
|
||||
>
|
||||
解密
|
||||
签名/验证
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 签名/验证 */}
|
||||
<div style={{ marginBottom: '20px', padding: '15px', backgroundColor: '#2d2d2d', borderRadius: '8px' }}>
|
||||
<h3 style={{ color: '#e0e0e0', marginBottom: '10px' }}>签名/验证</h3>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>签名</label>
|
||||
<textarea
|
||||
value={sm2Signature}
|
||||
onChange={(e) => setSm2Signature(e.target.value)}
|
||||
placeholder="输入签名 (hex)"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
resize: 'vertical',
|
||||
minHeight: '100px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>验证结果</label>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: sm2VerifyResult === '验证成功' ? '#4ade80' : sm2VerifyResult === '验证失败' ? '#f87171' : '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
minHeight: '40px',
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
{sm2VerifyResult || '验证结果将显示在这里'}
|
||||
|
||||
{/* 加密/解密 */}
|
||||
{sm2ActiveTab === 'encrypt' && (
|
||||
<div style={{ padding: '15px', backgroundColor: '#2d2d2d', borderRadius: '8px' }}>
|
||||
<h3 style={{ color: '#e0e0e0', marginBottom: '10px' }}>加密/解密</h3>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>消息</label>
|
||||
<textarea
|
||||
value={sm2Message}
|
||||
onChange={(e) => setSm2Message(e.target.value)}
|
||||
placeholder="输入要加密的消息 (hex)"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
resize: 'vertical',
|
||||
minHeight: '100px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>加密结果</label>
|
||||
<textarea
|
||||
value={sm2Encrypted}
|
||||
onChange={(e) => setSm2Encrypted(e.target.value)}
|
||||
placeholder="输入加密结果 (hex)"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
resize: 'vertical',
|
||||
minHeight: '100px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>解密结果</label>
|
||||
<textarea
|
||||
value={sm2Decrypted}
|
||||
readOnly
|
||||
placeholder="解密结果将显示在这里"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
resize: 'vertical',
|
||||
minHeight: '100px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="button-group" style={{ display: 'flex', gap: '10px' }}>
|
||||
<button
|
||||
onClick={handleEncryptSm2}
|
||||
style={{
|
||||
padding: '10px 20px',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
background: '#f59e0b',
|
||||
color: '#121212',
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
cursor: 'pointer',
|
||||
transition: 'background 0.3s ease',
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
加密
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDecryptSm2}
|
||||
style={{
|
||||
padding: '10px 20px',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
background: '#f59e0b',
|
||||
color: '#121212',
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
cursor: 'pointer',
|
||||
transition: 'background 0.3s ease',
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
解密
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="button-group" style={{ display: 'flex', gap: '10px' }}>
|
||||
<button
|
||||
onClick={handleSignSm2}
|
||||
style={{
|
||||
padding: '10px 20px',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
background: '#f59e0b',
|
||||
color: '#121212',
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
cursor: 'pointer',
|
||||
transition: 'background 0.3s ease',
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
签名
|
||||
</button>
|
||||
<button
|
||||
onClick={handleVerifySm2}
|
||||
style={{
|
||||
padding: '10px 20px',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
background: '#f59e0b',
|
||||
color: '#121212',
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
cursor: 'pointer',
|
||||
transition: 'background 0.3s ease',
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
验证签名
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 签名/验证 */}
|
||||
{sm2ActiveTab === 'sign' && (
|
||||
<div style={{ padding: '15px', backgroundColor: '#2d2d2d', borderRadius: '8px' }}>
|
||||
<h3 style={{ color: '#e0e0e0', marginBottom: '10px' }}>签名/验证</h3>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>消息</label>
|
||||
<textarea
|
||||
value={sm2SignMessage}
|
||||
onChange={(e) => setSm2SignMessage(e.target.value)}
|
||||
placeholder="输入要签名的消息 (hex)"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
resize: 'vertical',
|
||||
minHeight: '100px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>签名</label>
|
||||
<textarea
|
||||
value={sm2Signature}
|
||||
onChange={(e) => setSm2Signature(e.target.value)}
|
||||
placeholder="输入签名 (hex)"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
resize: 'vertical',
|
||||
minHeight: '100px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group" style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>验证结果</label>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: sm2VerifyResult === '验证成功' ? '#4ade80' : sm2VerifyResult === '验证失败' ? '#f87171' : '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
minHeight: '40px',
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
{sm2VerifyResult || '验证结果将显示在这里'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="button-group" style={{ display: 'flex', gap: '10px' }}>
|
||||
<button
|
||||
onClick={handleSignSm2}
|
||||
style={{
|
||||
padding: '10px 20px',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
background: '#f59e0b',
|
||||
color: '#121212',
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
cursor: 'pointer',
|
||||
transition: 'background 0.3s ease',
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
签名
|
||||
</button>
|
||||
<button
|
||||
onClick={handleVerifySm2}
|
||||
style={{
|
||||
padding: '10px 20px',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
background: '#f59e0b',
|
||||
color: '#121212',
|
||||
fontSize: '16px',
|
||||
fontWeight: 'bold',
|
||||
cursor: 'pointer',
|
||||
transition: 'background 0.3s ease',
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
验证签名
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
1
src/types/sm-crypto.d.ts
vendored
1
src/types/sm-crypto.d.ts
vendored
@ -10,6 +10,7 @@ declare module 'sm-crypto' {
|
||||
doDecrypt: (ciphertext: string, privateKey: string) => string;
|
||||
doSignature: (message: string | Uint8Array, privateKey: string, options?: { hash?: boolean, der?: boolean, userId?: string, publicKey?: string, pointPool?: any[] }) => string;
|
||||
doVerifySignature: (message: string | Uint8Array, signature: string, publicKey: string, options?: { hash?: boolean, der?: boolean, userId?: string }) => boolean;
|
||||
getPublicKeyFromPrivateKey: (privateKey: string) => string;
|
||||
};
|
||||
|
||||
export const sm3: {
|
||||
|
||||
@ -15,12 +15,15 @@ export const sm2GenerateKeyPair = (): { privateKey: string; publicKey: string }
|
||||
// SM2 从私钥计算公钥
|
||||
export const sm2GetPublicKeyFromPrivateKey = (privateKey: string): string => {
|
||||
// 验证私钥是否为有效的 hex 字符串
|
||||
if (!privateKey) {
|
||||
throw new Error('Private key is required')
|
||||
}
|
||||
if (!isValidHex(privateKey)) {
|
||||
throw new Error('Invalid private key: must be hex string')
|
||||
}
|
||||
|
||||
const keypair = sm2.generateKeyPairHex(privateKey)
|
||||
return keypair.publicKey
|
||||
const publicKey = sm2.getPublicKeyFromPrivateKey(privateKey)
|
||||
return publicKey
|
||||
}
|
||||
|
||||
// SM2 加密
|
||||
|
||||
@ -1 +1 @@
|
||||
export const VERSION = "V1.0-20260418053331";
|
||||
export const VERSION = "V1.0-20260418065443";
|
||||
Loading…
Reference in New Issue
Block a user