ismx-nexo-node-app 0.4.194 → 0.4.197

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.
@@ -87,6 +87,30 @@ class CryptoUtils {
87
87
  return decrypted.toString('utf8');
88
88
  });
89
89
  }
90
+ /**
91
+ * Genera un desafío (challenge) aleatorio y seguro.
92
+ * Se recomienda un tamaño de 32 bytes para asegurar suficiente entropía.
93
+ */
94
+ static challenge() {
95
+ return (0, node_crypto_1.randomBytes)(32).toString('hex');
96
+ }
97
+ /**
98
+ * Verifica si el desafío firmado criptográficamente coincide con la clave generadora.
99
+ * @param challenge El desafío original que el servidor generó.
100
+ * @param signature La firma generada por el dispositivo (usualmente en base64 o hex).
101
+ * @param key La clave pública que guardamos en setupBiometry() para este dispositivo.
102
+ * @param format
103
+ */
104
+ static verify(challenge, signature, key, format = 'base64') {
105
+ try {
106
+ const verifier = (0, node_crypto_1.createVerify)('sha256');
107
+ verifier.update(challenge);
108
+ return verifier.verify(key, signature, format);
109
+ }
110
+ catch (error) {
111
+ return false;
112
+ }
113
+ }
90
114
  static sha256Sign(merchantKey, orderId, encodedOrder) {
91
115
  return __awaiter(this, void 0, void 0, function* () {
92
116
  var _a;
@@ -1,4 +1,4 @@
1
- import { KeyLike, RsaPrivateKey } from "crypto";
1
+ import { BinaryToTextEncoding, KeyLike, RsaPrivateKey } from "crypto";
2
2
  export default abstract class CryptoUtils {
3
3
  private static crypto;
4
4
  private static zeroPad;
@@ -8,5 +8,18 @@ export default abstract class CryptoUtils {
8
8
  static asymEncrypt(value: string, publicKey: RsaPrivateKey | KeyLike): Promise<string>;
9
9
  /** Asymmetric decryption (RSA) */
10
10
  static asymDecrypt(hash: string, privateKey: RsaPrivateKey | KeyLike): Promise<string>;
11
+ /**
12
+ * Genera un desafío (challenge) aleatorio y seguro.
13
+ * Se recomienda un tamaño de 32 bytes para asegurar suficiente entropía.
14
+ */
15
+ static challenge(): string;
16
+ /**
17
+ * Verifica si el desafío firmado criptográficamente coincide con la clave generadora.
18
+ * @param challenge El desafío original que el servidor generó.
19
+ * @param signature La firma generada por el dispositivo (usualmente en base64 o hex).
20
+ * @param key La clave pública que guardamos en setupBiometry() para este dispositivo.
21
+ * @param format
22
+ */
23
+ static verify(challenge: string, signature: string, key: string, format?: BinaryToTextEncoding): boolean;
11
24
  private static sha256Sign;
12
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ismx-nexo-node-app",
3
- "version": "0.4.194",
3
+ "version": "0.4.197",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "build": "rm -rf ./dist && npx tsc",
@@ -1,5 +1,5 @@
1
- import {privateDecrypt, publicEncrypt} from "node:crypto";
2
- import {KeyLike, RsaPrivateKey} from "crypto";
1
+ import {createVerify, privateDecrypt, publicEncrypt, randomBytes} from "node:crypto";
2
+ import {BinaryToTextEncoding, KeyLike, RsaPrivateKey} from "crypto";
3
3
 
4
4
  export default abstract class CryptoUtils {
5
5
 
@@ -62,6 +62,31 @@ export default abstract class CryptoUtils {
62
62
  return decrypted.toString('utf8');
63
63
  }
64
64
 
65
+ /**
66
+ * Genera un desafío (challenge) aleatorio y seguro.
67
+ * Se recomienda un tamaño de 32 bytes para asegurar suficiente entropía.
68
+ */
69
+ static challenge() {
70
+ return randomBytes(32).toString('hex');
71
+ }
72
+
73
+ /**
74
+ * Verifica si el desafío firmado criptográficamente coincide con la clave generadora.
75
+ * @param challenge El desafío original que el servidor generó.
76
+ * @param signature La firma generada por el dispositivo (usualmente en base64 o hex).
77
+ * @param key La clave pública que guardamos en setupBiometry() para este dispositivo.
78
+ * @param format
79
+ */
80
+ static verify(challenge: string, signature: string, key: string, format: BinaryToTextEncoding = 'base64'): boolean
81
+ {
82
+ try {
83
+ const verifier = createVerify('sha256');
84
+ verifier.update(challenge);
85
+ return verifier.verify(key, signature, format);
86
+
87
+ } catch (error) { return false; }
88
+ }
89
+
65
90
  private static async sha256Sign(merchantKey: string, orderId: string, encodedOrder: string) {
66
91
  let crypto = this.crypto ?? (await import("crypto")).default;
67
92
  const orderKeyBuf = await CryptoUtils.symEncrypt(merchantKey, orderId);