feat(crypto): 新增 RSA 验签工具

This commit is contained in:
2026-03-19 16:16:07 +08:00
parent b5490085bd
commit e3e3caed6a
3 changed files with 44 additions and 0 deletions

View File

@@ -4,3 +4,4 @@ export { hkdfSha256 } from './hkdf'
export { hmacSha256, hmacSha256Base64 } from './hmac'
export { generatePgpKeyPair, pgpSignDetached, pgpVerifyDetached, validatePgpPrivateKey } from './pgp'
export { rsaOaepEncrypt } from './rsa-oaep'
export { rsaVerifySignature, validateRsaPublicKey } from './rsa-signature'

View File

@@ -0,0 +1,24 @@
import { describe, expect, it } from 'bun:test'
import { constants, createSign, generateKeyPairSync } from 'node:crypto'
import { rsaVerifySignature, validateRsaPublicKey } from './rsa-signature'
describe('rsaVerifySignature', () => {
it('verifies SHA256withRSA signatures over raw payload bytes', () => {
const { privateKey, publicKey } = generateKeyPairSync('rsa', { modulusLength: 2048 })
const payload = Buffer.from('eyJsaWNlbmNlX2lkIjoiTElDLTAwMSIsImV4cGlyZV90aW1lIjoiMjAyNy0wMy0xOSJ9', 'utf-8')
const signer = createSign('RSA-SHA256')
signer.update(payload)
signer.end()
const signature = signer.sign({ key: privateKey, padding: constants.RSA_PKCS1_PADDING })
const publicKeyBase64 = publicKey.export({ format: 'der', type: 'spki' }).toString('base64')
expect(rsaVerifySignature(payload, signature, publicKeyBase64)).toBe(true)
expect(rsaVerifySignature(Buffer.from(`${payload}x`, 'utf-8'), signature, publicKeyBase64)).toBe(false)
})
it('rejects malformed SPKI public keys', () => {
expect(() => validateRsaPublicKey('not-a-public-key')).toThrow()
})
})

View File

@@ -0,0 +1,19 @@
import { constants, createPublicKey, verify } from 'node:crypto'
const createSpkiPublicKey = (publicKeyBase64: string) => {
return createPublicKey({
key: Buffer.from(publicKeyBase64, 'base64'),
format: 'der',
type: 'spki',
})
}
export const validateRsaPublicKey = (publicKeyBase64: string): void => {
createSpkiPublicKey(publicKeyBase64)
}
export const rsaVerifySignature = (data: Uint8Array, signature: Uint8Array, publicKeyBase64: string): boolean => {
const publicKey = createSpkiPublicKey(publicKeyBase64)
return verify('RSA-SHA256', data, { key: publicKey, padding: constants.RSA_PKCS1_PADDING }, signature)
}