UNPKG

@dioxide-js/silas

Version:

RPC utility for Silas

176 lines (144 loc) 4.27 kB
import { __require as requireJsbn } from '../../../jsbn/index.mjs'; /* eslint-disable class-methods-use-this */ var asn1; var hasRequiredAsn1; function requireAsn1 () { if (hasRequiredAsn1) return asn1; hasRequiredAsn1 = 1; const {BigInteger} = requireJsbn(); function bigintToValue(bigint) { let h = bigint.toString(16); if (h[0] !== '-') { // 正数 if (h.length % 2 === 1) h = '0' + h; // 补齐到整字节 else if (!h.match(/^[0-7]/)) h = '00' + h; // 非0开头,则补一个全0字节 } else { // 负数 h = h.substr(1); let len = h.length; if (len % 2 === 1) len += 1; // 补齐到整字节 else if (!h.match(/^[0-7]/)) len += 2; // 非0开头,则补一个全0字节 let mask = ''; for (let i = 0; i < len; i++) mask += 'f'; mask = new BigInteger(mask, 16); // 对绝对值取反,加1 h = mask.xor(bigint).add(BigInteger.ONE); h = h.toString(16).replace(/^-/, ''); } return h } class ASN1Object { constructor() { this.tlv = null; this.t = '00'; this.l = '00'; this.v = ''; } /** * 获取 der 编码比特流16进制串 */ getEncodedHex() { if (!this.tlv) { this.v = this.getValue(); this.l = this.getLength(); this.tlv = this.t + this.l + this.v; } return this.tlv } getLength() { const n = this.v.length / 2; // 字节数 let nHex = n.toString(16); if (nHex.length % 2 === 1) nHex = '0' + nHex; // 补齐到整字节 if (n < 128) { // 短格式,以 0 开头 return nHex } else { // 长格式,以 1 开头 const head = 128 + nHex.length / 2; // 1(1位) + 真正的长度占用字节数(7位) + 真正的长度 return head.toString(16) + nHex } } getValue() { return '' } } class DERInteger extends ASN1Object { constructor(bigint) { super(); this.t = '02'; // 整型标签说明 if (bigint) this.v = bigintToValue(bigint); } getValue() { return this.v } } class DERSequence extends ASN1Object { constructor(asn1Array) { super(); this.t = '30'; // 序列标签说明 this.asn1Array = asn1Array; } getValue() { this.v = this.asn1Array.map(asn1Object => asn1Object.getEncodedHex()).join(''); return this.v } } /** * 获取 l 占用字节数 */ function getLenOfL(str, start) { if (+str[start + 2] < 8) return 1 // l 以0开头,则表示短格式,只占一个字节 return +str.substr(start + 2, 2) & 0x7f + 1 // 长格式,取第一个字节后7位作为长度真正占用字节数,再加上本身 } /** * 获取 l */ function getL(str, start) { // 获取 l const len = getLenOfL(str, start); const l = str.substr(start + 2, len * 2); if (!l) return -1 const bigint = +l[0] < 8 ? new BigInteger(l, 16) : new BigInteger(l.substr(2), 16); return bigint.intValue() } /** * 获取 v 的位置 */ function getStartOfV(str, start) { const len = getLenOfL(str, start); return start + (len + 1) * 2 } asn1 = { /** * ASN.1 der 编码,针对 sm2 签名 */ encodeDer(r, s) { const derR = new DERInteger(r); const derS = new DERInteger(s); const derSeq = new DERSequence([derR, derS]); return derSeq.getEncodedHex() }, /** * 解析 ASN.1 der,针对 sm2 验签 */ decodeDer(input) { // 结构: // input = | tSeq | lSeq | vSeq | // vSeq = | tR | lR | vR | tS | lS | vS | const start = getStartOfV(input, 0); const vIndexR = getStartOfV(input, start); const lR = getL(input, start); const vR = input.substr(vIndexR, lR * 2); const nextStart = vIndexR + vR.length; const vIndexS = getStartOfV(input, nextStart); const lS = getL(input, nextStart); const vS = input.substr(vIndexS, lS * 2); const r = new BigInteger(vR, 16); const s = new BigInteger(vS, 16); return {r, s} } }; return asn1; } export { requireAsn1 as __require }; //# sourceMappingURL=asn1.mjs.map