{"_id":"sm-polyfill","_rev":"4-9d07b8bdbb2593a3f8c1019be441cf80","name":"sm-polyfill","dist-tags":{"latest":"1.3.0"},"versions":{"1.0.0":{"name":"sm-polyfill","version":"1.0.0","keywords":["sm2","sm3","sm4","polyfill","cryptography","chinese","gm","国密","openssl","nodejs16"],"author":{"name":"ZHAO Xudong","email":"zxdong@gmail.com"},"license":"MIT","_id":"sm-polyfill@1.0.0","maintainers":[{"name":"zxdong262","email":"zxdong@gmail.com"}],"homepage":"https://github.com/zxdong262/sm-polyfill#readme","bugs":{"url":"https://github.com/zxdong262/sm-polyfill/issues"},"dist":{"shasum":"f516541d34f16331b851023599cf04a7cdf50570","tarball":"https://registry.npmjs.org/sm-polyfill/-/sm-polyfill-1.0.0.tgz","fileCount":4,"integrity":"sha512-3GZSl/1ZQGysmdf1BJ/bKTFR1d4iTOJNYOJCWqun5bBvcFBMfh/+jhpGC11bVHY4s4tPuYluGMz5C+eRDWlEfg==","signatures":[{"sig":"MEUCIA7SWnGKP1Ky0Wwfj5f2KbuyGdO73Qo6T2nzzkM6kNfNAiEAtuQjXYDmmjAVor2DsFUuGpD30swF317pNtj22S1KGQE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22582},"main":"lib/index.js","type":"commonjs","engines":{"node":">=14.0.0"},"gitHead":"8c975c4d838ff8d31766bc9ffb5a1a8a18f07831","scripts":{"test":"node test/test.js"},"_npmUser":{"name":"zxdong262","email":"zxdong@gmail.com"},"repository":{"url":"git+https://github.com/zxdong262/sm-polyfill.git","type":"git"},"_npmVersion":"11.11.0","description":"SM2/SM3/SM4 polyfill for Node.js 16 and earlier. Provides SM2 signing/verification using sm-crypto when native OpenSSL support is unavailable.","directories":{"lib":"lib","test":"test"},"_nodeVersion":"24.14.1","dependencies":{"sm-crypto":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{},"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/sm-polyfill_1.0.0_1782815224978_0.6734081639278888","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"sm-polyfill","version":"1.1.0","keywords":["sm2","sm3","sm4","polyfill","cryptography","chinese","gm","国密","openssl","nodejs16"],"author":{"name":"ZHAO Xudong","email":"zxdong@gmail.com"},"license":"MIT","_id":"sm-polyfill@1.1.0","maintainers":[{"name":"zxdong262","email":"zxdong@gmail.com"}],"homepage":"https://github.com/zxdong262/sm-polyfill#readme","bugs":{"url":"https://github.com/zxdong262/sm-polyfill/issues"},"dist":{"shasum":"a4070e36abe7dc96ab9ed4bcef4d16bf5c4d501e","tarball":"https://registry.npmjs.org/sm-polyfill/-/sm-polyfill-1.1.0.tgz","fileCount":5,"integrity":"sha512-n2lXhq38KJWWRRdoy1mpwHjFJEohu+fubxcCBh5dcNXtGTYwn1MTZEMKvfXTpvyJ5ZPQLcXyFSgZrO7jD+Pzvw==","signatures":[{"sig":"MEQCIFS1j8yjqUExFcD/6hKIs9fEVwzh6L2uhKjVu3yxc/v3AiBiyTcSh6Afx6ERIs+gYexL4OlxEMBy4o0BbbL1z/Pw6w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34577},"main":"lib/index.js","type":"commonjs","engines":{"node":">=14.0.0"},"gitHead":"88deabd31fda5a591836b795cd32c37c11c29405","scripts":{"test":"node test/test.js"},"_npmUser":{"name":"zxdong262","email":"zxdong@gmail.com"},"repository":{"url":"git+https://github.com/zxdong262/sm-polyfill.git","type":"git"},"_npmVersion":"11.11.0","description":"SM2/SM3/SM4 polyfill for Node.js 16 and earlier. Provides SM2 signing/verification using sm-crypto when native OpenSSL support is unavailable.","directories":{"lib":"lib","test":"test"},"_nodeVersion":"24.14.1","dependencies":{"sm-crypto":"^0.3.0"},"_hasShrinkwrap":false,"devDependencies":{},"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/sm-polyfill_1.1.0_1782817433496_0.5079117636084303","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"sm-polyfill","version":"1.2.0","keywords":["sm2","sm3","sm4","polyfill","cryptography","chinese","gm","国密","openssl","nodejs16"],"author":{"name":"ZHAO Xudong","email":"zxdong@gmail.com"},"license":"MIT","_id":"sm-polyfill@1.2.0","maintainers":[{"name":"zxdong262","email":"zxdong@gmail.com"}],"homepage":"https://github.com/zxdong262/sm-polyfill#readme","bugs":{"url":"https://github.com/zxdong262/sm-polyfill/issues"},"dist":{"shasum":"19b6386322dc7f1f2ce4f3712cd77b117c89c39a","tarball":"https://registry.npmjs.org/sm-polyfill/-/sm-polyfill-1.2.0.tgz","fileCount":5,"integrity":"sha512-12skCVA3ZU7koZq3cNlorXthKIH5EP7tacCkkWwYmEztcZn0b2QugG3ilhAbpUwavByHjPpON2yPLsEXo/OUew==","signatures":[{"sig":"MEUCIEPezIA1/x0iCsII6D0wMXYmHkolzPqaCrHgngFpSLq1AiEA1+KJYijgXwDknulteBTMcfpVi9H1S1FARPeb9/B2CsA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34680},"main":"lib/index.js","type":"commonjs","engines":{"node":">=14.0.0"},"gitHead":"db814a11da373cff5ea7772f1a53642ad12d68c2","scripts":{"test":"node test/test.js"},"_npmUser":{"name":"zxdong262","email":"zxdong@gmail.com"},"repository":{"url":"git+https://github.com/zxdong262/sm-polyfill.git","type":"git"},"_npmVersion":"8.19.4","description":"SM2/SM3/SM4 polyfill for Node.js 16 and earlier. Provides SM2 signing/verification using sm-crypto when native OpenSSL support is unavailable.","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.20.2","dependencies":{"sm-crypto-v2":"^1.15.0"},"_hasShrinkwrap":false,"devDependencies":{},"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/sm-polyfill_1.2.0_1782818008688_0.9894783880692473","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"sm-polyfill","version":"1.3.0","description":"SM2/SM3/SM4 polyfill for Node.js 16 and earlier. Provides SM2 signing/verification using sm-crypto when native OpenSSL support is unavailable.","keywords":["sm2","sm3","sm4","polyfill","cryptography","chinese","gm","国密","openssl","nodejs16"],"homepage":"https://github.com/zxdong262/sm-polyfill#readme","bugs":{"url":"https://github.com/zxdong262/sm-polyfill/issues"},"repository":{"type":"git","url":"git+https://github.com/zxdong262/sm-polyfill.git"},"license":"MIT","author":{"name":"ZHAO Xudong","email":"zxdong@gmail.com"},"type":"commonjs","main":"lib/index.js","directories":{"lib":"lib","test":"test"},"scripts":{"test":"node test/test.js"},"dependencies":{"sm-crypto-v2":"^1.15.0"},"devDependencies":{},"peerDependencies":{},"engines":{"node":">=14.0.0"},"gitHead":"d2020a5a6679ea67cf1b6b33ab31524a1a3f6c59","_id":"sm-polyfill@1.3.0","_nodeVersion":"16.20.2","_npmVersion":"8.19.4","dist":{"integrity":"sha512-enbQbvb7xLQ3lnTSUf0HJkmt5cuRsW1LO9hsq7GWq5TE9Msiyr0VhfmBuYluRNllUsXvHtsuHHOBiD1FGXdVyQ==","shasum":"7723b8b4be0c5206813b04c1d8b35b77890511d2","tarball":"https://registry.npmjs.org/sm-polyfill/-/sm-polyfill-1.3.0.tgz","fileCount":5,"unpackedSize":38006,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDyX5iJFVAWtbLqbaktPz2xk3GPol83P+CC/RCA0u1YjwIhAI8KcUylKhqi2Lp824MAz77N9mYVqhM72KNc3tTtxPZG"}]},"_npmUser":{"name":"zxdong262","email":"zxdong@gmail.com"},"maintainers":[{"name":"zxdong262","email":"zxdong@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sm-polyfill_1.3.0_1782823566718_0.6827462052392177"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-30T10:27:04.913Z","modified":"2026-06-30T12:46:06.954Z","1.0.0":"2026-06-30T10:27:05.098Z","1.1.0":"2026-06-30T11:03:53.631Z","1.2.0":"2026-06-30T11:13:28.831Z","1.3.0":"2026-06-30T12:46:06.860Z"},"bugs":{"url":"https://github.com/zxdong262/sm-polyfill/issues"},"author":{"name":"ZHAO Xudong","email":"zxdong@gmail.com"},"license":"MIT","homepage":"https://github.com/zxdong262/sm-polyfill#readme","keywords":["sm2","sm3","sm4","polyfill","cryptography","chinese","gm","国密","openssl","nodejs16"],"repository":{"type":"git","url":"git+https://github.com/zxdong262/sm-polyfill.git"},"description":"SM2/SM3/SM4 polyfill for Node.js 16 and earlier. Provides SM2 signing/verification using sm-crypto when native OpenSSL support is unavailable.","maintainers":[{"name":"zxdong262","email":"zxdong@gmail.com"}],"readme":"# sm-polyfill\n\n[![NPM Version](https://img.shields.io/npm/v/sm-polyfill.svg)](https://www.npmjs.com/package/sm-polyfill)\n[![Node.js Version](https://img.shields.io/node/v/sm-polyfill.svg)](https://www.npmjs.com/package/sm-polyfill)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/zxdong262/sm-polyfill/blob/master/LICENSE)\n\n**[English](./README.md)** | **[中文](./README_CN.md)**\n\nSM2/SM3/SM4 polyfill for Node.js 16 and earlier. Provides SM2 signing/verification using [sm-crypto-v2](https://www.npmjs.com/package/sm-crypto-v2) when native OpenSSL support is unavailable.\n\n## Background\n\nNode.js 16 (OpenSSL 1.1.1) has **partial** SM algorithm support:\n- ✅ SM2 ECDH key exchange\n- ✅ SM3 hash\n- ✅ SM4 cipher\n- ❌ SM2 sign/verify (requires OpenSSL 3.0+)\n\nNode.js 18+ (OpenSSL 3.0+) has **full** SM algorithm support.\n\nThis polyfill enables SM2 signing/verification on Node.js 16 by falling back to the pure JavaScript `sm-crypto-v2` implementation when native support is unavailable.\n\n## Installation\n\n```bash\nnpm install sm-polyfill\n```\n\n## Usage\n\n### Basic Sign/Verify\n\n```javascript\nconst smPolyfill = require('sm-polyfill');\n\n// Check if polyfill is being used\nif (smPolyfill.needsPolyfill()) {\n  console.log('Using SM2 polyfill (Node.js 16 or earlier)');\n} else {\n  console.log('Using native SM2 (Node.js 18+)');\n}\n\n// Sign data\nconst data = Buffer.from('Hello SM2!');\nconst privateKey = '-----BEGIN OPENSSH PRIVATE KEY-----\\n...';\nconst signature = smPolyfill.sign(data, privateKey, 'sm3');\n\n// Verify signature\nconst publicKey = 'ssh-sm2 AAAA...';\nconst verified = smPolyfill.verify(data, signature, publicKey, 'sm3');\nconsole.log('Verified:', verified);\n```\n\n### PEM Key Format\n\nBoth PEM and OpenSSH key formats are supported for `sign` and `verify`:\n\n```javascript\nconst smPolyfill = require('sm-polyfill');\n\n// Generate a key pair (PEM format)\nconst keys = smPolyfill.generateKeyPair();\n// keys.privateKey => SEC1 PEM (-----BEGIN EC PRIVATE KEY-----)\n// keys.publicKey  => SPKI PEM (-----BEGIN PUBLIC KEY-----)\n\n// Sign with PEM private key\nconst data = Buffer.from('Hello PEM!');\nconst sig = smPolyfill.sign(data, keys.privateKey, 'sm3');\n\n// Verify with PEM public key\nconst ok = smPolyfill.verify(data, sig, keys.publicKey, 'sm3');\nconsole.log('Verified:', ok); // true\n```\n\n### SM3 Hash\n\n```javascript\nconst hash = smPolyfill.sm3('abc');\nconsole.log(hash.toString('hex'));\n// 66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0\n```\n\n### SM4 Cipher\n\n```javascript\nconst crypto = require('crypto');\nconst key = crypto.randomBytes(16);\nconst iv = crypto.randomBytes(16);\n\n// Encrypt\nconst cipher = smPolyfill.createSM4Cipher('sm4-ctr', key, iv);\nconst encrypted = Buffer.concat([cipher.update('Hello SM4!'), cipher.final()]);\n\n// Decrypt\nconst decipher = smPolyfill.createSM4Decipher('sm4-ctr', key, iv);\nconst decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);\n```\n\n### Key Generation\n\n```javascript\nconst keys = smPolyfill.generateKeyPair();\nconsole.log(keys.privateKey); // PEM format (SEC1)\nconsole.log(keys.publicKey);  // PEM format (SPKI)\n```\n\n## API\n\n### `sign(data, privateKey, hashAlgo)`\n\nSign data using SM2 with SM3 hash.\n\n- `data`: Buffer or string - Data to sign\n- `privateKey`: string or Buffer - Private key in **PEM** (SEC1) or **OpenSSH** format\n- `hashAlgo`: string - Must be `'sm3'`\n- Returns: Buffer - Signature in DER format\n\n### `verify(data, signature, publicKey, hashAlgo)`\n\nVerify SM2 signature with SM3 hash.\n\n- `data`: Buffer or string - Original data\n- `signature`: Buffer - Signature in DER format\n- `publicKey`: string or Buffer - Public key in **PEM** (SPKI), **OpenSSH**, or **hex** format\n- `hashAlgo`: string - Must be `'sm3'`\n- Returns: boolean - True if signature is valid\n\n### `sm3(data)`\n\nCompute SM3 hash.\n\n- `data`: Buffer or string - Data to hash\n- Returns: Buffer - 32-byte hash\n\n### `createSM4Cipher(algorithm, key, iv)`\n\nCreate SM4 cipher.\n\n- `algorithm`: string - `'sm4-ctr'`, `'sm4-cbc'`, etc.\n- `key`: Buffer - 16-byte key\n- `iv`: Buffer - Initialization vector\n- Returns: Cipher object\n\n### `createSM4Decipher(algorithm, key, iv)`\n\nCreate SM4 decipher.\n\n- `algorithm`: string - `'sm4-ctr'`, `'sm4-cbc'`, etc.\n- `key`: Buffer - 16-byte key\n- `iv`: Buffer - Initialization vector\n- Returns: Decipher object\n\n### `generateKeyPair()`\n\nGenerate an SM2 key pair in PEM format.\n\n- Returns: `{ privateKey: string, publicKey: string }` - SEC1 private key and SPKI public key in PEM format\n\n### `needsPolyfill()`\n\nCheck if the polyfill is needed (native SM2 doesn't work).\n\n- Returns: boolean\n\n### `checkNativeSM2Support()`\n\nCheck if native SM2 signing works.\n\n- Returns: boolean\n\n### `isSmCryptoAvailable()`\n\nCheck if sm-crypto-v2 package is available.\n\n- Returns: boolean\n\n### `parseOpenSSHPrivateKey(privateKey)`\n\nParse OpenSSH format private key and extract the private key scalar.\n\n- `privateKey`: string or Buffer - OpenSSH format private key\n- Returns: string - Private key scalar as hex string\n\n### `parseOpenSSHPublicKey(publicKey)`\n\nParse OpenSSH format public key and extract the public key point.\n\n- `publicKey`: string or Buffer - OpenSSH format public key\n- Returns: string - Public key point (with 0x04 prefix) as hex string\n\n### `signatureToDER(sigHex)`\n\nConvert sm-crypto-v2 signature format to DER.\n\n- `sigHex`: string - Signature as hex (r + s concatenated)\n- Returns: Buffer - DER-encoded signature\n\n### `signatureFromDER(derSig)`\n\nConvert DER signature to sm-crypto-v2 format.\n\n- `derSig`: Buffer - DER-encoded signature\n- Returns: string - Signature as hex (r + s concatenated)\n\n## How It Works\n\n1. **Detection**: The library first checks if native SM2 signing works by attempting to sign and verify test data.\n\n2. **Native Path**: If native SM2 works AND the key is in PEM/DER format, it uses Node.js's built-in `crypto.sign()` and `crypto.verify()`.\n\n3. **Polyfill Path**: If native SM2 doesn't work OR the key is in OpenSSH format, it:\n   - Detects the key format (PEM or OpenSSH) automatically\n   - For PEM keys: parses ASN.1 DER to extract raw key material (SEC1 for private, SPKI for public)\n   - For OpenSSH keys: parses the OpenSSH key format to extract raw key material\n   - Uses `sm-crypto-v2` for the actual signing/verification\n   - Converts between DER and sm-crypto-v2 signature formats\n\n## Key Format Support\n\nThe polyfill supports multiple key formats:\n\n| Format | Private Key | Public Key |\n|--------|------------|------------|\n| **PEM** (SEC1/SPKI) | `-----BEGIN EC PRIVATE KEY-----` | `-----BEGIN PUBLIC KEY-----` |\n| **OpenSSH** | `-----BEGIN OPENSSH PRIVATE KEY-----` | `ssh-sm2 AAAA...` |\n| **Hex** | — | Raw hex string |\n\n## Requirements\n\n- Node.js >= 14.0.0\n- `sm-crypto-v2` package (installed automatically)\n\n## License\n\n[MIT](./LICENSE)\n","readmeFilename":"README.md"}