This commit is contained in:
parent
32626c84a6
commit
045e939dcd
1
package-lock.json
generated
1
package-lock.json
generated
@ -16,6 +16,7 @@
|
||||
"gmsm-sm2js": "^0.7.1",
|
||||
"gmsm-sm3js": "^0.2.0",
|
||||
"gmsm-sm4js": "^0.7.0",
|
||||
"jsrsasign": "^11.1.3",
|
||||
"node-forge": "^1.4.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
"gmsm-sm2js": "^0.7.1",
|
||||
"gmsm-sm3js": "^0.2.0",
|
||||
"gmsm-sm4js": "^0.7.0",
|
||||
"jsrsasign": "^11.1.3",
|
||||
"node-forge": "^1.4.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
||||
180
src/App.tsx
180
src/App.tsx
@ -6,6 +6,7 @@ import { sm4Encrypt, sm4Decrypt } from './utils/algorithm/sm4'
|
||||
import { sm2GenerateKeyPair, sm2GetPublicKeyFromPrivateKey, sm2Encrypt, sm2Decrypt, sm2Sign, sm2Verify } from './utils/algorithm/sm2'
|
||||
import { parseSm2Cert, parseCertFromFile, generateRootCert, generateAppCert } from './utils/algorithm/cert'
|
||||
import { hexToUtf8, utf8ToHex, hexToBase64, base64ToHex } from './utils/convert'
|
||||
import { getInfoFromPKCS7, verifyPKCS7 } from './utils/crypto.js'
|
||||
|
||||
function App() {
|
||||
// 从localStorage读取当前分类,默认sm3
|
||||
@ -179,6 +180,12 @@ function App() {
|
||||
const [appCert, setAppCert] = useState<string>('')
|
||||
const [commonName, setCommonName] = useState<string>('test.example.com')
|
||||
const [certError, setCertError] = useState<string>('')
|
||||
|
||||
// PKCS7 签名工具状态
|
||||
const [pkcs7Signature, setPkcs7Signature] = useState<string>('')
|
||||
const [pkcs7Info, setPkcs7Info] = useState<any>(null)
|
||||
const [originalData, setOriginalData] = useState<string>('')
|
||||
const [verifyResult, setVerifyResult] = useState<string>('')
|
||||
|
||||
|
||||
|
||||
@ -318,6 +325,30 @@ function App() {
|
||||
}
|
||||
}
|
||||
|
||||
// 处理 PKCS7 签名信息提取
|
||||
const handleGetInfoFromPKCS7 = () => {
|
||||
try {
|
||||
const info = getInfoFromPKCS7(pkcs7Signature)
|
||||
setPkcs7Info(info)
|
||||
setCertError('')
|
||||
} catch (error) {
|
||||
setCertError((error as Error).message)
|
||||
setPkcs7Info(null)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理 PKCS7 签名验证
|
||||
const handleVerifyPKCS7 = () => {
|
||||
try {
|
||||
const result = verifyPKCS7(pkcs7Signature, originalData)
|
||||
setVerifyResult(result ? '验证成功' : '验证失败')
|
||||
setCertError('')
|
||||
} catch (error) {
|
||||
setCertError((error as Error).message)
|
||||
setVerifyResult('')
|
||||
}
|
||||
}
|
||||
|
||||
// SM2 生成密钥对
|
||||
const handleGenerateSm2KeyPair = () => {
|
||||
try {
|
||||
@ -1703,6 +1734,155 @@ function App() {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* PKCS7 签名工具 */}
|
||||
<div style={{ backgroundColor: '#2d2d2d', padding: '15px', borderRadius: '8px', marginTop: '20px' }}>
|
||||
<h3 style={{ color: '#f59e0b', marginBottom: '15px' }}>4. PKCS7 签名工具</h3>
|
||||
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>PKCS7 签名数据</label>
|
||||
<textarea
|
||||
value={pkcs7Signature}
|
||||
onChange={(e) => setPkcs7Signature(e.target.value)}
|
||||
onContextMenu={(e) => openMenu(e, pkcs7Signature, setPkcs7Signature, false)}
|
||||
onTouchStart={(e) => {
|
||||
const touchTimer = setTimeout(() => {
|
||||
openMenu(e, pkcs7Signature, setPkcs7Signature, false)
|
||||
}, 500)
|
||||
return () => clearTimeout(touchTimer)
|
||||
}}
|
||||
placeholder="输入 PKCS7 签名数据 (PEM 或 Base64 格式)"
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px',
|
||||
border: '1px solid #333',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: '#3d3d3d',
|
||||
color: '#e0e0e0',
|
||||
fontSize: '14px',
|
||||
resize: 'vertical',
|
||||
minHeight: '150px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>原始数据(可选,仅在签名为 detech 模式时需要)</label>
|
||||
<textarea
|
||||
value={originalData}
|
||||
onChange={(e) => setOriginalData(e.target.value)}
|
||||
onContextMenu={(e) => openMenu(e, originalData, setOriginalData, false)}
|
||||
onTouchStart={(e) => {
|
||||
const touchTimer = setTimeout(() => {
|
||||
openMenu(e, originalData, setOriginalData, false)
|
||||
}, 500)
|
||||
return () => clearTimeout(touchTimer)
|
||||
}}
|
||||
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', marginBottom: '20px' }}>
|
||||
<button
|
||||
onClick={handleGetInfoFromPKCS7}
|
||||
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={handleVerifyPKCS7}
|
||||
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>
|
||||
|
||||
{verifyResult && (
|
||||
<div style={{ marginBottom: '20px', padding: '10px', borderRadius: '4px', backgroundColor: verifyResult === '验证成功' ? '#166534' : '#7f1d1d' }}>
|
||||
<div style={{ color: verifyResult === '验证成功' ? '#dcfce7' : '#fecaca', fontWeight: 'bold' }}>
|
||||
验签结果: {verifyResult}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{pkcs7Info && (
|
||||
<div style={{ backgroundColor: '#3d3d3d', padding: '15px', borderRadius: '8px' }}>
|
||||
<h4 style={{ color: '#f59e0b', marginBottom: '15px' }}>PKCS7 签名信息</h4>
|
||||
|
||||
{pkcs7Info.cert && (
|
||||
<div style={{ marginBottom: '15px' }}>
|
||||
<h5 style={{ color: '#e0e0e0', marginBottom: '10px' }}>证书信息</h5>
|
||||
<div style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0', fontWeight: 'bold' }}>主题 DN:</label>
|
||||
<div style={{ color: '#e0e0e0' }}>{pkcs7Info.cert.subjectDN}</div>
|
||||
</div>
|
||||
<div style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0', fontWeight: 'bold' }}>签发者 DN:</label>
|
||||
<div style={{ color: '#e0e0e0' }}>{pkcs7Info.cert.issuerDN}</div>
|
||||
</div>
|
||||
<div style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0', fontWeight: 'bold' }}>序列号:</label>
|
||||
<div style={{ color: '#e0e0e0', wordBreak: 'break-all' }}>{pkcs7Info.cert.serialNumber}</div>
|
||||
</div>
|
||||
<div style={{ marginBottom: '10px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0', fontWeight: 'bold' }}>有效期:</label>
|
||||
<div style={{ color: '#e0e0e0' }}>
|
||||
<div>开始: {pkcs7Info.cert.notBefore}</div>
|
||||
<div>结束: {pkcs7Info.cert.notAfter}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{pkcs7Info.publicKey && (
|
||||
<div style={{ marginBottom: '15px' }}>
|
||||
<h5 style={{ color: '#e0e0e0', marginBottom: '10px' }}>公钥</h5>
|
||||
<div style={{ color: '#e0e0e0', wordBreak: 'break-all', whiteSpace: 'pre-wrap' }}>{pkcs7Info.publicKey}</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{pkcs7Info.signature && (
|
||||
<div style={{ marginBottom: '15px' }}>
|
||||
<h5 style={{ color: '#e0e0e0', marginBottom: '10px' }}>签名值</h5>
|
||||
<div style={{ color: '#e0e0e0', wordBreak: 'break-all' }}>{pkcs7Info.signature}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
19
src/utils/crypto.d.ts
vendored
Normal file
19
src/utils/crypto.d.ts
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
export function sm4en3(key: string, data: string): string;
|
||||
export function sm4de3(key: string, data: string): string;
|
||||
export function getInfoFromPKCS7(p7sign: Buffer | string): {
|
||||
cert: {
|
||||
subject: Array<{ name: string; value: string }>;
|
||||
subjectDN: string;
|
||||
issuer: Array<{ name: string; value: string }>;
|
||||
issuerDN: string;
|
||||
serialNumber: string;
|
||||
notBefore: string;
|
||||
notAfter: string;
|
||||
pem: string;
|
||||
} | null;
|
||||
publicKey: string | null;
|
||||
publicKeyHex: string | null;
|
||||
signature: string | null;
|
||||
signatureHex: string | null;
|
||||
};
|
||||
export function verifyPKCS7(p7sign: Buffer | string, originalData?: Buffer | string): boolean;
|
||||
354
src/utils/crypto.js
Normal file
354
src/utils/crypto.js
Normal file
@ -0,0 +1,354 @@
|
||||
import sm4 from 'sm-crypto'
|
||||
import sm3 from 'sm-crypto'
|
||||
import sm2 from 'sm-crypto'
|
||||
import forge from 'node-forge'
|
||||
import { KJUR, ASN1HEX, X509,pemtohex } from 'jsrsasign'
|
||||
|
||||
export function sm4en3(key, data) {
|
||||
let sm3key = sm3(key)
|
||||
sm3key = sm3key.substring(0, 32)
|
||||
let encryptData = sm4.encrypt(data, sm3key)
|
||||
return encryptData
|
||||
}
|
||||
|
||||
export function sm4de3(key, data) {
|
||||
let sm3key = sm3(key)
|
||||
sm3key = sm3key.substring(0, 32)
|
||||
let decryptData = sm4.decrypt(data, sm3key)
|
||||
return decryptData
|
||||
}
|
||||
|
||||
export function getInfoFromPKCS7(p7sign) {
|
||||
let base64Data
|
||||
if (Buffer.isBuffer(p7sign)) {
|
||||
base64Data = p7sign.toString('base64')
|
||||
} else if (typeof p7sign === 'string') {
|
||||
if (p7sign.includes('-----BEGIN PKCS7-----')) {
|
||||
base64Data = p7sign
|
||||
.replace(/-----BEGIN PKCS7-----\n?/, '')
|
||||
.replace(/-----END PKCS7-----\n?/, '')
|
||||
.replace(/\n/g, '')
|
||||
} else {
|
||||
base64Data = p7sign
|
||||
}
|
||||
} else {
|
||||
throw new Error('Invalid input type for p7sign')
|
||||
}
|
||||
|
||||
try {
|
||||
const pemData = `-----BEGIN PKCS7-----\n${base64Data}\n-----END PKCS7-----`
|
||||
const p7 = forge.pkcs7.messageFromPem(pemData)
|
||||
return extractInfoFromForgeP7(p7)
|
||||
} catch (forgeError) {
|
||||
try {
|
||||
return extractInfoFromJsrsasignP7(base64Data)
|
||||
} catch (jsrsasignError) {
|
||||
throw new Error(`Failed to parse PKCS7: ${forgeError.message}, ${jsrsasignError.message}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extractInfoFromForgeP7(p7) {
|
||||
function attrsToDN(attrs) {
|
||||
if (!attrs || attrs.length === 0) return ''
|
||||
return attrs.map(attr => `${attr.name}=${attr.value}`).join(', ')
|
||||
}
|
||||
|
||||
let cert = null
|
||||
if (p7.certificates && p7.certificates.length > 0) {
|
||||
const certObj = p7.certificates[0]
|
||||
cert = {
|
||||
subject: certObj.subject.attributes.map(attr => ({
|
||||
name: attr.name,
|
||||
value: attr.value
|
||||
})),
|
||||
subjectDN: attrsToDN(certObj.subject.attributes),
|
||||
issuer: certObj.issuer.attributes.map(attr => ({
|
||||
name: attr.name,
|
||||
value: attr.value
|
||||
})),
|
||||
issuerDN: attrsToDN(certObj.issuer.attributes),
|
||||
serialNumber: certObj.serialNumber,
|
||||
notBefore: certObj.validity.notBefore,
|
||||
notAfter: certObj.validity.notAfter,
|
||||
pem: forge.pki.certificateToPem(certObj)
|
||||
}
|
||||
}
|
||||
|
||||
let publicKey = null
|
||||
let publicKeyHex = null
|
||||
if (p7.certificates && p7.certificates.length > 0) {
|
||||
const certObj = p7.certificates[0]
|
||||
if (certObj.publicKey) {
|
||||
publicKey = forge.pki.publicKeyToPem(certObj.publicKey)
|
||||
const publicKeyAsn1 = forge.pki.publicKeyToAsn1(certObj.publicKey)
|
||||
const publicKeyDer = forge.asn1.toDer(publicKeyAsn1)
|
||||
publicKeyHex = forge.util.bytesToHex(publicKeyDer.getBytes())
|
||||
}
|
||||
}
|
||||
|
||||
let signature = null
|
||||
let signatureHex = null
|
||||
if (p7.rawCapture && p7.rawCapture.signature) {
|
||||
signature = forge.util.encode64(p7.rawCapture.signature)
|
||||
signatureHex = forge.util.bytesToHex(p7.rawCapture.signature)
|
||||
}
|
||||
|
||||
return {
|
||||
cert,
|
||||
publicKey,
|
||||
publicKeyHex,
|
||||
signature,
|
||||
signatureHex
|
||||
}
|
||||
}
|
||||
|
||||
function extractInfoFromJsrsasignP7(base64Data) {
|
||||
const parser = new KJUR.asn1.cms.CMSParser()
|
||||
const p7 = parser.getCMSSignedData(ASN1HEX.b64tohex(base64Data))
|
||||
|
||||
let cert = null
|
||||
let publicKey = null
|
||||
let publicKeyHex = null
|
||||
|
||||
const certs = p7.certs && p7.certs.array ? p7.certs.array : []
|
||||
|
||||
if (certs.length > 0) {
|
||||
const certPem = certs[0]
|
||||
|
||||
const x509 = new X509()
|
||||
x509.readCertPEM(certPem)
|
||||
|
||||
const subjectStr = x509.getSubjectString()
|
||||
const issuerStr = x509.getIssuerString()
|
||||
|
||||
function parseDNString(dnStr) {
|
||||
if (!dnStr || dnStr === '/') return []
|
||||
const parts = dnStr.substring(1).split('/')
|
||||
return parts.map(part => {
|
||||
const [name, value] = part.split('=')
|
||||
return { name, value }
|
||||
})
|
||||
}
|
||||
|
||||
const subjectAttrs = parseDNString(subjectStr)
|
||||
const issuerAttrs = parseDNString(issuerStr)
|
||||
|
||||
function attrsToDN(attrs) {
|
||||
if (!attrs || attrs.length === 0) return ''
|
||||
return attrs.map(attr => `${attr.name}=${attr.value}`).join(', ')
|
||||
}
|
||||
|
||||
cert = {
|
||||
subject: subjectAttrs,
|
||||
subjectDN: attrsToDN(subjectAttrs),
|
||||
issuer: issuerAttrs,
|
||||
issuerDN: attrsToDN(issuerAttrs),
|
||||
serialNumber: x509.getSerialNumberHex(),
|
||||
notBefore: x509.getNotBefore(),
|
||||
notAfter: x509.getNotAfter(),
|
||||
pem: certPem
|
||||
}
|
||||
|
||||
try {
|
||||
const certHex = pemtohex(certPem)
|
||||
const tbsCert = ASN1HEX.getTLVbyList(certHex, 0, [0])
|
||||
const spki = ASN1HEX.getTLVbyList(tbsCert, 0, [6])
|
||||
const publicKeyBitString = ASN1HEX.getTLVbyList(spki, 0, [1])
|
||||
const publicKeyHexContent = publicKeyBitString.substring(6)
|
||||
|
||||
const algorithmSeq = ASN1HEX.getTLVbyList(spki, 0, [0])
|
||||
const oidTlv = ASN1HEX.getTLVbyList(algorithmSeq, 0, [0])
|
||||
const oidHex = oidTlv.substring(4)
|
||||
|
||||
const isSM2 = oidHex.includes('2A811CCF55') || oidHex.includes('2a811ccf55')
|
||||
|
||||
publicKey = KJUR.asn1.ASN1Util.getPEMStringFromHex(spki, 'PUBLIC KEY')
|
||||
publicKeyHex = spki
|
||||
} catch (e) {
|
||||
console.error('提取 SM2 公钥错误:', e.message)
|
||||
publicKey = null
|
||||
publicKeyHex = null
|
||||
}
|
||||
}
|
||||
|
||||
let signature = null
|
||||
let signatureHex = null
|
||||
if (p7.sinfos && p7.sinfos.length > 0) {
|
||||
const signer = p7.sinfos[0]
|
||||
if (signer.sighex) {
|
||||
signatureHex = signer.sighex
|
||||
signature = ASN1HEX.hextob64(signer.sighex)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
cert,
|
||||
publicKey,
|
||||
publicKeyHex,
|
||||
signature,
|
||||
signatureHex
|
||||
}
|
||||
}
|
||||
|
||||
export function verifyPKCS7(p7sign, originalData) {
|
||||
let base64Data
|
||||
if (Buffer.isBuffer(p7sign)) {
|
||||
base64Data = p7sign.toString('base64')
|
||||
} else if (typeof p7sign === 'string') {
|
||||
if (p7sign.includes('-----BEGIN PKCS7-----')) {
|
||||
base64Data = p7sign
|
||||
.replace(/-----BEGIN PKCS7-----\n?/, '')
|
||||
.replace(/-----END PKCS7-----\n?/, '')
|
||||
.replace(/\n/g, '')
|
||||
} else {
|
||||
base64Data = p7sign
|
||||
}
|
||||
} else {
|
||||
throw new Error('Invalid input type for p7sign')
|
||||
}
|
||||
|
||||
let verifyData
|
||||
if (originalData) {
|
||||
if (Buffer.isBuffer(originalData)) {
|
||||
verifyData = originalData
|
||||
} else if (typeof originalData === 'string') {
|
||||
verifyData = Buffer.from(originalData)
|
||||
} else {
|
||||
throw new Error('Invalid input type for originalData')
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const pemData = `-----BEGIN PKCS7-----\n${base64Data}\n-----END PKCS7-----`
|
||||
const p7 = forge.pkcs7.messageFromPem(pemData)
|
||||
|
||||
if (!verifyData) {
|
||||
if (p7.content) {
|
||||
verifyData = Buffer.from(p7.content.getBytes(), 'binary')
|
||||
} else {
|
||||
throw new Error('No content found in PKCS7 signature for attach mode')
|
||||
}
|
||||
}
|
||||
|
||||
if (p7.certificates && p7.certificates.length > 0) {
|
||||
const publicKey = p7.certificates[0].publicKey
|
||||
if (publicKey && p7.rawCapture && p7.rawCapture.signature) {
|
||||
const md = forge.md.sha256.create()
|
||||
md.update(verifyData.toString(), 'utf8')
|
||||
const digest = md.digest().getBytes()
|
||||
|
||||
return publicKey.verify(digest, p7.rawCapture.signature)
|
||||
}
|
||||
}
|
||||
|
||||
return p7.verify()
|
||||
} catch (forgeError) {
|
||||
try {
|
||||
return verifyPKCS7WithJsrsasign(base64Data, verifyData)
|
||||
} catch (jsrsasignError) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function verifyPKCS7WithJsrsasign(base64Data, verifyData) {
|
||||
const parser = new KJUR.asn1.cms.CMSParser()
|
||||
const p7 = parser.getCMSSignedData(ASN1HEX.b64tohex(base64Data))
|
||||
|
||||
if (!verifyData) {
|
||||
if (p7.econtent && p7.econtent.hex) {
|
||||
verifyData = Buffer.from(p7.econtent.hex, 'hex')
|
||||
} else {
|
||||
throw new Error('No content found in PKCS7 signature for attach mode')
|
||||
}
|
||||
}
|
||||
|
||||
if (!p7.sinfos || p7.sinfos.length === 0) {
|
||||
throw new Error('No signer info found in PKCS7')
|
||||
}
|
||||
|
||||
const signer = p7.sinfos[0]
|
||||
|
||||
if (!p7.certs || !p7.certs.array || p7.certs.array.length === 0) {
|
||||
throw new Error('No certificate found in PKCS7')
|
||||
}
|
||||
|
||||
const certPem = p7.certs.array[0]
|
||||
const x509 = new X509()
|
||||
x509.readCertPEM(certPem)
|
||||
|
||||
const sigAlg = signer.sigalg
|
||||
|
||||
if (sigAlg === '1.2.156.10197.1.301.1' || sigAlg === '1.2.156.10197.1.501' || sigAlg.includes('sm2')) {
|
||||
const certHex = pemtohex(certPem)
|
||||
const tbsCert = ASN1HEX.getTLVbyList(certHex, 0, [0])
|
||||
const spki = ASN1HEX.getTLVbyList(tbsCert, 0, [6])
|
||||
const publicKeyBitString = ASN1HEX.getTLVbyList(spki, 0, [1])
|
||||
let publicKeyHex = publicKeyBitString.substring(6)
|
||||
|
||||
if (!publicKeyHex.startsWith('04')) {
|
||||
publicKeyHex = '04' + publicKeyHex
|
||||
}
|
||||
|
||||
const hash = sm3(verifyData.toString())
|
||||
let signatureHex = signer.sighex
|
||||
const userId = '1234567812345678'
|
||||
|
||||
try {
|
||||
const result1 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex, { der: true, hash: true, userId })
|
||||
if (result1) return true
|
||||
|
||||
const result2 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex, { der: true, hash: true })
|
||||
if (result2) return true
|
||||
|
||||
const result3 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex, { der: true })
|
||||
if (result3) return true
|
||||
|
||||
const result4 = sm2.doVerifySignature(hash, signatureHex, publicKeyHex, { der: true, hash: true, userId })
|
||||
if (result4) return true
|
||||
|
||||
const result5 = sm2.doVerifySignature(hash, signatureHex, publicKeyHex, { der: true, hash: true })
|
||||
if (result5) return true
|
||||
|
||||
const result6 = sm2.doVerifySignature(hash, signatureHex, publicKeyHex, { der: true })
|
||||
if (result6) return true
|
||||
|
||||
const result7 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex)
|
||||
if (result7) return true
|
||||
|
||||
const result8 = sm2.doVerifySignature(verifyData.toString(), signatureHex, publicKeyHex, { hash: true, userId })
|
||||
if (result8) return true
|
||||
|
||||
if (signatureHex.startsWith('30')) {
|
||||
try {
|
||||
const rStart = 8
|
||||
const r = signatureHex.substring(rStart, rStart + 64)
|
||||
const sStart = rStart + 64 + 4
|
||||
const s = signatureHex.substring(sStart, sStart + 64)
|
||||
const rawSignature = r + s
|
||||
|
||||
const result9 = sm2.doVerifySignature(verifyData.toString(), rawSignature, publicKeyHex)
|
||||
if (result9) return true
|
||||
|
||||
const result10 = sm2.doVerifySignature(verifyData.toString(), rawSignature, publicKeyHex, { hash: true, userId })
|
||||
if (result10) return true
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
return false
|
||||
} else {
|
||||
try {
|
||||
const pubKey = x509.getPublicKey()
|
||||
const sig = new KJUR.crypto.Signature({ alg: 'SHA256withRSA' })
|
||||
sig.init(pubKey)
|
||||
sig.updateString(verifyData.toString())
|
||||
return sig.verify(signer.sighex)
|
||||
} catch (e) {
|
||||
throw new Error('RSA verification failed: ' + e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1 +1 @@
|
||||
export const VERSION = "V1.0-20260424025112";
|
||||
export const VERSION = "V1.0-20260426034359";
|
||||
Loading…
Reference in New Issue
Block a user