ec-nest/src/common/id-card-cipher.spec.ts
liuyun 394d7a9731 feat(security): id_card_no 存储层 AES-256-GCM 加密 + SHA-256 哈希唯一
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-21 12:03:43 +08:00

39 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, expect, it } from 'vitest';
import { decrypt, decryptIdCard, encrypt, hash } from './id-card-cipher.js';
describe('id-card-cipher', () => {
it('加密后可解密回原文(roundtrip)', () => {
const plain = '530102199001011231';
expect(decrypt(encrypt(plain))).toBe(plain);
});
it('同一明文两次加密产生不同密文(随机 IV)', () => {
const plain = '530102199001011231';
expect(encrypt(plain)).not.toBe(encrypt(plain));
});
it('密文为 base64(iv || authTag || ciphertext),长度稳定且不含明文', () => {
const plain = '530102199001011231';
const enc = encrypt(plain);
const buf = Buffer.from(enc, 'base64');
// 12 IV + 16 authTag + 18 ciphertext(AES-GCM 不增补长度)
expect(buf.length).toBe(12 + 16 + 18);
expect(enc).not.toContain(plain);
});
it('hash 输出 64 位 hex 且稳定', () => {
const plain = '530102199001011231';
const h = hash(plain);
expect(h).toMatch(/^[0-9a-f]{64}$/);
expect(hash(plain)).toBe(h);
expect(hash('530102199001011232')).not.toBe(h);
});
it('decryptIdCard 空值/非法值返回空串而不抛错', () => {
expect(decryptIdCard('')).toBe('');
expect(decryptIdCard(null)).toBe('');
expect(decryptIdCard(undefined)).toBe('');
expect(decryptIdCard('not-base64!!!')).toBe('');
});
});