xades-bes-signer 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import * as forge from "node-forge";
2
- import { PKCS88Bags } from "./types";
2
+ import { PKCS8Bags } from "./types";
3
3
  export declare function getP12(certificate: Uint8Array<ArrayBufferLike>, certKey: string): forge.pkcs12.Pkcs12Pfx;
4
4
  export declare function getIssuerName(cert: forge.pkcs12.Bag): string | undefined;
5
- export declare function getKeyContainer(pkcs8Bags: PKCS88Bags, friendlyName: string): forge.pkcs12.Bag;
5
+ export declare function getKeyContainer(pkcs8Bags: PKCS8Bags, friendlyName: string): forge.pkcs12.Bag;
6
6
  export declare function getKey(pckcs8: forge.pkcs12.Bag): forge.pki.rsa.PrivateKey;
7
7
  export declare function getCertificate(certBag: forge.pkcs12.Bag[]): forge.pkcs12.Bag;
8
8
  export declare function isCerticateValid(certficate: forge.pki.Certificate): boolean;
@@ -22,7 +22,7 @@ export declare function getPCK12CertInfo(certificate: Uint8Array<ArrayBufferLike
22
22
  certInfo: {
23
23
  digestValue: string;
24
24
  issuerName: string | undefined;
25
- issuerSerialNumber: number;
25
+ issuerSerialNumber: string;
26
26
  signingTime: string;
27
27
  certificateX509: string;
28
28
  modulus: string;
@@ -54,7 +54,7 @@ function getIssuerName(cert) {
54
54
  const issuerTributes = (_a = cert.cert) === null || _a === void 0 ? void 0 : _a.issuer.attributes;
55
55
  let issuerName = issuerTributes === null || issuerTributes === void 0 ? void 0 : issuerTributes.reverse().map((attr) => {
56
56
  return `${attr.shortName}=${attr.value}`;
57
- }).join(", ");
57
+ }).join(",");
58
58
  return issuerName;
59
59
  }
60
60
  function getKeyContainer(pkcs8Bags, friendlyName) {
@@ -133,15 +133,26 @@ function getPCK12CertInfo(certificate, certKey) {
133
133
  let key = getKey(pckcs8);
134
134
  const pem = certX509ToPem(cert);
135
135
  let certificateX509 = pem.substring(pem.indexOf("\n") + 1, pem.indexOf("-----END CERTIFICATE-----"));
136
- certificateX509 = certificateX509.replace(/\r?\n|\r/g, "").replace(/([^\0]{76})/g, "$1\n");
137
- const ISODateTime = new Date().toISOString().slice(0, 19);
136
+ certificateX509 = certificateX509
137
+ .replace(/\r?\n|\r/g, "")
138
+ .replace(/([^\0]{76})/g, "$1\n");
139
+ const currentDate = new Date();
140
+ const timeZone = (currentDate.getTimezoneOffset() / 60) * -1;
141
+ const signingTime = `${currentDate.getFullYear()}-` +
142
+ `${(currentDate.getMonth() + 1).toString().padStart(2, "0")}-` +
143
+ `${currentDate.getDate().toString().padStart(2, "0")}T` +
144
+ `${currentDate.getHours().toString().padStart(2, "0")}:` +
145
+ `${currentDate.getMinutes().toString().padStart(2, "0")}:` +
146
+ `${currentDate.getSeconds().toString().padStart(2, "0")}` +
147
+ `${timeZone > 0 ? "+" : "-"}` +
148
+ `${(timeZone > 0 ? timeZone.toString() : timeZone.toString().substring(1)).padStart(2, "0")}:00`;
138
149
  const certificateANS1 = certX509ToASN1(cert);
139
150
  const certificateDER = forge.asn1.toDer(certificateANS1).getBytes();
140
- const hashCErtificateX509DER = (0, security_1.sha1ToBase64)(certificateDER, "utf-8");
141
- const certificateX509SN = parseInt(cert === null || cert === void 0 ? void 0 : cert.serialNumber, 16);
151
+ const hashCertificateX509DER = (0, security_1.sha1ToBase64)(certificateDER);
152
+ const certificateX509SN = BigInt(`0x${cert.serialNumber}`).toString(10);
142
153
  const exponent = (0, security_1.hexToBase64)(key.e.data[0].toString(16));
143
154
  let modulus = (0, security_1.bigintToBase64)(BigInt(key.n.toString()));
144
- modulus = modulus.replace(/\r?\n|\r/g, '').replace(/([^\0]{76})/g, '$1\n');
155
+ modulus = modulus.replace(/\r?\n|\r/g, "").replace(/([^\0]{76})/g, "$1\n");
145
156
  const certificateNumber = (0, security_1.getRandomValues)(999990, 9999999);
146
157
  const signatureNumber = (0, security_1.getRandomValues)(99990, 999999);
147
158
  const signedPropertiesNumber = (0, security_1.getRandomValues)(99990, 999999);
@@ -162,10 +173,10 @@ function getPCK12CertInfo(certificate, certKey) {
162
173
  objectNumber,
163
174
  },
164
175
  certInfo: {
165
- digestValue: hashCErtificateX509DER,
176
+ digestValue: hashCertificateX509DER,
166
177
  issuerName,
167
178
  issuerSerialNumber: certificateX509SN,
168
- signingTime: ISODateTime,
179
+ signingTime: signingTime,
169
180
  certificateX509,
170
181
  modulus,
171
182
  exponent,
@@ -1,6 +1,5 @@
1
- import { Encoding } from "node:crypto";
2
1
  import * as forge from "node-forge";
3
- export declare function sha1ToBase64(text: string, encoding: Encoding): string;
2
+ export declare function sha1ToBase64(text: string, encoding?: forge.Encoding): string;
4
3
  export declare function hexToBase64(hashHex: string): string;
5
4
  export declare function bigintToBase64(param: bigint): string | undefined;
6
5
  export declare function getRandomValues(min?: number, max?: number): number;
@@ -40,12 +40,14 @@ exports.getRandomValues = getRandomValues;
40
40
  exports.isHexString = isHexString;
41
41
  exports.toSha1 = toSha1;
42
42
  exports.toBase64String = toBase64String;
43
- const crypto = __importStar(require("node:crypto"));
44
43
  const forge = __importStar(require("node-forge"));
45
44
  function sha1ToBase64(text, encoding) {
46
- const HASH = crypto.createHash("sha1").update(text, encoding).digest("hex");
47
- const BUFFER = Buffer.from(HASH, "hex");
48
- return BUFFER.toString("base64");
45
+ let md = forge.md.sha1.create();
46
+ forge.util.encode64(forge.sha1.create().update(text).digest().bytes());
47
+ md.update(text, encoding);
48
+ const HASH = md.digest().toHex();
49
+ const BUFFER = Buffer.from(HASH, "hex").toString("base64");
50
+ return BUFFER;
49
51
  }
50
52
  function hexToBase64(hashHex) {
51
53
  if (hashHex.length % 2 !== 0) {
@@ -81,6 +83,5 @@ function toSha1(content, encoding) {
81
83
  return md;
82
84
  }
83
85
  function toBase64String(content) {
84
- const buffer = Buffer.from(content, 'utf-8');
85
- return buffer.toString('base64');
86
+ return forge.util.encode64(content);
86
87
  }
@@ -40,19 +40,20 @@ function getXML(path) {
40
40
  });
41
41
  }
42
42
  function getSignedPropertiesNode(params) {
43
- return (`<etsi:SignedProperties Id="Signature${params.signatureNumber} SignedProperties${params.signedPropertiesNumber}">` +
43
+ return (`<etsi:SignedProperties Id="Signature${params.signatureNumber}-SignedProperties${params.signedPropertiesNumber}">` +
44
44
  `<etsi:SignedSignatureProperties>` +
45
- `<etsi:SignedTime>${params.signingTime}</etsi:SignedTime>` +
45
+ `<etsi:SigningTime>${params.signingTime}</etsi:SigningTime>` +
46
46
  `<etsi:SigningCertificate>` +
47
47
  `<etsi:Cert>` +
48
- `<etsi:CertDigest><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">` +
49
- `<etsi:DigestValue>${params.digestValue}</etsi:DigestValue></etsi:CertDigest>` +
48
+ `<etsi:CertDigest><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>` +
49
+ `<ds:DigestValue>${params.digestValue}</ds:DigestValue></etsi:CertDigest>` +
50
50
  `<etsi:IssuerSerial>` +
51
51
  `<ds:X509IssuerName>${params.issuerName}</ds:X509IssuerName>` +
52
52
  `<ds:X509SerialNumber>${params.issuerSerialNumber}</ds:X509SerialNumber>` +
53
53
  `</etsi:IssuerSerial>` +
54
54
  `</etsi:Cert>` +
55
55
  `</etsi:SigningCertificate>` +
56
+ `</etsi:SignedSignatureProperties>` +
56
57
  `<etsi:SignedDataObjectProperties>` +
57
58
  `<etsi:DataObjectFormat ObjectReference="#Reference-ID-${params.referenceIdNumber}">` +
58
59
  `<etsi:Description>contenido comprobante</etsi:Description>` +
@@ -66,29 +67,29 @@ function getKeyInfoNode(params) {
66
67
  `\n<ds:X509Data>` +
67
68
  `\n<ds:X509Certificate>\n${params.certificateX509}\n</ds:X509Certificate>` +
68
69
  `\n</ds:X509Data>` +
69
- `\n</ds:KeyValue>\n<ds:RSAKeyValue>\n<ds:Modulus>\n${params.modulus}\n</ds:Modulus>` +
70
+ `\n<ds:KeyValue>\n<ds:RSAKeyValue>\n<ds:Modulus>\n${params.modulus}\n</ds:Modulus>` +
70
71
  `\n<ds:Exponent>${params.exponent}</ds:Exponent>` +
71
72
  `\n</ds:RSAKeyValue>` +
73
+ `\n</ds:KeyValue>` +
72
74
  `\n</ds:KeyInfo>`);
73
75
  }
74
76
  function getSignedInfoNode(params) {
75
77
  return (`<ds:SignedInfo Id="Signature-SignedInfo${params.signedInfoNumber}">` +
76
- `\n<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n20010315"></ds:CanonicalizationMethod>` +
77
- `\n<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>` +
78
- `\n<ds:Reference Id="SignedPropertiesID${params.signedPropertiesIdNumber}" `
79
- + `Type="http://uri.etsi.org/01903#SignedProperties" URI="#Signature${params.signatureNumber}-SignedProperties${params.signedPropertiesNumber}">` +
80
- `\n<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>` +
78
+ `\n<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>` +
79
+ `\n<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>` +
80
+ `\n<ds:Reference Id="SignedPropertiesID${params.signedPropertiesIdNumber}" Type="http://uri.etsi.org/01903#SignedProperties" URI="#Signature${params.signatureNumber}-SignedProperties${params.signedPropertiesNumber}">` +
81
+ `\n<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>` +
81
82
  `\n<ds:DigestValue>${params.sha1SignedProperties}</ds:DigestValue>` +
82
83
  `\n</ds:Reference>` +
83
- `\n<ds:Reference URI="Certificate${params.certificateNumber}">` +
84
- `\n<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>` +
84
+ `\n<ds:Reference URI="#Certificate${params.certificateNumber}">` +
85
+ `\n<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>` +
85
86
  `\n<ds:DigestValue>${params.sha1KeyInfo}</ds:DigestValue>` +
86
87
  `\n</ds:Reference>` +
87
88
  `\n<ds:Reference Id="Reference-ID-${params.referenceIdNumber}" URI="#comprobante">` +
88
89
  `\n<ds:Transforms>` +
89
- `\n<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>` +
90
+ `\n<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>` +
90
91
  `\n</ds:Transforms>` +
91
- `\n<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>` +
92
+ `\n<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>` +
92
93
  `\n<ds:DigestValue>${params.sha1Xml}</ds:DigestValue>` +
93
94
  `\n</ds:Reference>` +
94
95
  `\n</ds:SignedInfo>`);
@@ -132,11 +133,12 @@ function sign(params) {
132
133
  .replace(/(?=<\>)(\r?\n)|(\r?\n)(?=\<\/) /g, "")
133
134
  .trim()
134
135
  .replace(/(?=<\>)(\s*)/g, "")
135
- .replace(/\t|\r/g, "");
136
+ .replace(/\t|\r/g, "")
137
+ .replace(/>\s+</g, "><");
136
138
  const arayuint8 = new Uint8Array(p12Buffer === null || p12Buffer === void 0 ? void 0 : p12Buffer.buffer);
137
139
  let certInfo = (0, credentials_1.getPCK12CertInfo)(arayuint8, p12Password);
138
140
  const sha1Xml = (0, security_1.sha1ToBase64)(xmlData.replace(`<?xml version="1.0" encoding="UTF-8"?>`, ""), "utf8");
139
- const namespaces = 'xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:estsi="http://uri.etsi.org/01903/v1.3.2#"';
141
+ const namespaces = 'xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:etsi="http://uri.etsi.org/01903/v1.3.2#"';
140
142
  let signedProperties = getSignedPropertiesNode({
141
143
  signatureNumber: certInfo.radomValues.signatureNumber,
142
144
  signedPropertiesNumber: certInfo.radomValues.signedPropertiesNumber,
@@ -151,7 +153,7 @@ function sign(params) {
151
153
  nodeName: "<etsi:SignedProperties",
152
154
  namespaces,
153
155
  });
154
- const sha1SignedProperties = (0, security_1.sha1ToBase64)(signedPropertiesCanonicalized, "utf8");
156
+ const sha1SignedProperties = (0, security_1.sha1ToBase64)(signedPropertiesCanonicalized);
155
157
  const keyInfo = getKeyInfoNode({
156
158
  certificateNumber: certInfo.radomValues.certificateNumber,
157
159
  certificateX509: certInfo.certInfo.certificateX509,
@@ -163,7 +165,7 @@ function sign(params) {
163
165
  nodeName: "<ds:KeyInfo",
164
166
  namespaces,
165
167
  });
166
- const sha1KeyInfo = (0, security_1.sha1ToBase64)(keyInfoCanonicalized, "utf-8");
168
+ const sha1KeyInfo = (0, security_1.sha1ToBase64)(keyInfoCanonicalized);
167
169
  const signedInfo = getSignedInfoNode({
168
170
  signedInfoNumber: certInfo.radomValues.signedInfoNumber,
169
171
  signedPropertiesIdNumber: certInfo.radomValues.signedPropertiesIdNumber,
@@ -199,7 +201,7 @@ function sign(params) {
199
201
  objectSignarureNode: objectSignature,
200
202
  });
201
203
  return addSignatureNode({
202
- xml: xmlData,
204
+ xml: xmlData.replace(`encoding="UTF-8"?>`, 'encoding="UTF-8"?>\n'),
203
205
  rootElement: params.rootElement,
204
206
  signatureNode,
205
207
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xades-bes-signer",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "XAdES-BES signer utilities for Node.js (TypeScript) — certificate handling and XAdES-BES signature helpers.",
5
5
  "main": "/dist/src/main.js",
6
6
  "types": "/dist/src/main.d.ts",