react-native-security-suite 1.0.0-rc.1 → 1.0.0-rc.2

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.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
  [![Downloads](https://img.shields.io/npm/dm/react-native-security-suite.svg)](https://www.npmjs.com/package/react-native-security-suite)
6
6
 
7
- **Comprehensive security solutions for React Native applications** — Protect your mobile apps with root/jailbreak detection, SSL certificate pinning, RFC 7515 JWS request signing, hardware-backed secure storage, X25519 key exchange, screenshot protection, and network monitoring.
7
+ **Comprehensive security solutions for React Native applications** — Protect your mobile apps with root/jailbreak detection, SSL certificate pinning, RFC 7515 JWS request signing, hardware-backed secure storage, configurable ECDH key exchange, screenshot protection, and network monitoring.
8
8
 
9
9
  <div style="display: flex; flex-direction: row; justify-content: center; align-items: center; gap: 20px;">
10
10
  <img src="https://raw.githubusercontent.com/mohamadnavabi/react-native-security-suite/master/pulse.gif" alt="iOS Pulse Network Monitor" width="200" />
@@ -24,7 +24,7 @@
24
24
  ### Data Security & Encryption
25
25
 
26
26
  - **Secure Storage**: Hardware-backed encrypted storage (Keychain on iOS, EncryptedSharedPreferences on Android)
27
- - **Diffie-Hellman / X25519 Key Exchange**: Configurable key agreement with `CryptoOptions`
27
+ - **Diffie-Hellman Key Exchange**: Application-defined algorithms and GCM parameters via `CryptoOptions`
28
28
  - **Shared-Key Encryption**: AES-GCM encrypt/decrypt using a derived shared secret
29
29
  - **Obfuscation**: Local string obfuscation with an explicit secret (not for credentials at rest)
30
30
 
@@ -200,37 +200,87 @@ const handleSecureStorage = async () => {
200
200
 
201
201
  If a native read/write fails (for example, KeyStore initialization errors on Android), the Promise rejects with a clear `Secure storage operation failed` error.
202
202
 
203
- ### 5. Diffie-Hellman / X25519 Key Exchange
203
+ ### 5. Diffie-Hellman Key Exchange
204
204
 
205
- Implement secure key exchange with optional `CryptoOptions` (defaults: X25519 key agreement, AES-256-GCM, HMAC-SHA-512):
205
+ Derive a shared encryption key from the client and server public keys. **All cryptographic algorithms and GCM lengths must be supplied by your application** — the native layer does not apply defaults.
206
206
 
207
- ```javascript
207
+ Use **`Crypto.establishSharedKey()`** so the derived key stays in native memory. Pass the same `cryptoOptions` to `encryptBySharedKey` / `decryptBySharedKey`.
208
+
209
+ ```typescript
208
210
  import {
211
+ Crypto,
209
212
  getPublicKey,
210
- getSharedKey,
211
213
  encryptBySharedKey,
212
214
  decryptBySharedKey,
215
+ type CryptoOptions,
213
216
  } from 'react-native-security-suite';
214
217
 
215
- const cryptoOptions = {
216
- keyAgreementAlgorithm: 'X25519',
217
- keyType: 'OKP',
218
- encryptionKeyAlgorithm: 'AES-256',
219
- hmacAlgorithm: 'HMAC-SHA-512',
220
- cipher: 'AES-GCM',
218
+ /**
219
+ * Pick one value per field. Unions match exported package types.
220
+ * Use JCA names (e.g. 'HmacSHA256', 'AES/GCM/NoPadding') for native crypto.
221
+ */
222
+ const cryptoOptions: CryptoOptions = {
223
+ keyAgreementAlgorithm: 'X25519', // 'X25519' | 'ECDH'
224
+ keyType: 'EC', // 'OKP' | 'EC'
225
+ encryptionKeyAlgorithm: 'AES-256', // 'AES-256' | 'AES'
226
+ hmacAlgorithm: 'HmacSHA256', // 'HmacSHA256' | 'HmacSHA384' | 'HmacSHA512' | 'HMAC-SHA-256' | 'HMAC-SHA-384' | 'HMAC-SHA-512'
227
+ cipher: 'AES-GCM', // 'AES-GCM' | 'AES/GCM/NoPadding'
228
+ tagLength: 256, // GCM auth tag size in bits
229
+ ivLength: 12, // GCM IV size in bytes
221
230
  };
222
231
 
223
232
  const handleKeyExchange = async () => {
224
233
  const clientPublicKey = await getPublicKey();
225
234
  const serverPublicKey = 'SERVER_PUBLIC_KEY_FROM_API';
226
235
 
227
- await getSharedKey(serverPublicKey, cryptoOptions);
236
+ // Keeps the shared key in native memory (recommended)
237
+ await Crypto.establishSharedKey(serverPublicKey, cryptoOptions);
228
238
 
229
239
  const encryptedMessage = await encryptBySharedKey('Secret message', cryptoOptions);
230
240
  const decryptedMessage = await decryptBySharedKey(encryptedMessage, cryptoOptions);
231
241
  };
232
242
  ```
233
243
 
244
+ **Legacy API** (returns the derived key to JavaScript — avoid in production):
245
+
246
+ ```javascript
247
+ import { getSharedKey } from 'react-native-security-suite';
248
+
249
+ const sharedKeyBase64 = await getSharedKey(serverPublicKey, cryptoOptions);
250
+ ```
251
+
252
+ #### Algorithm and length options
253
+
254
+ | Option | Required | Allowed values | Description |
255
+ |--------|----------|----------------|-------------|
256
+ | `keyAgreementAlgorithm` | yes | `'X25519' \| 'ECDH'` | Key-agreement algorithm passed to native `KeyAgreement` |
257
+ | `keyType` | yes* | `'OKP' \| 'EC'` | Key-factory algorithm for the server public key (`keyFactoryAlgorithm` alias) |
258
+ | `encryptionKeyAlgorithm` | yes | `'AES-256' \| 'AES'` | Symmetric key algorithm for the derived encryption key |
259
+ | `hmacAlgorithm` | yes* | `'HmacSHA256' \| 'HmacSHA384' \| 'HmacSHA512' \| 'HMAC-SHA-256' \| 'HMAC-SHA-384' \| 'HMAC-SHA-512'` | HMAC for HKDF and MAC key material (`hmacKeyAlgorithm` alias) |
260
+ | `cipher` | yes* | `'AES-GCM' \| 'AES/GCM/NoPadding'` | Cipher transformation for encrypt/decrypt (`cipherTransformation` alias) |
261
+ | `tagLength` | yes* | `number` (e.g. `128`) | GCM authentication tag length in **bits** (`gcmTagLength` alias) |
262
+ | `ivLength` | yes* | `number` (e.g. `12`) | GCM IV/nonce length in **bytes** (`gcmIvLength` alias) |
263
+
264
+ \*Provide via the preferred name or its deprecated alias (see [API Reference](#cryptooptions)).
265
+
266
+ Use **JCA-style names** on both Android and iOS (e.g. `HmacSHA256`, not `HMAC-SHA-256`). Omitting any required option throws before native code runs.
267
+
268
+ **Typical production profile (P-256 ECDH + AES-256-GCM):**
269
+
270
+ ```typescript
271
+ import type { CryptoOptions } from 'react-native-security-suite';
272
+
273
+ const cryptoOptions: CryptoOptions = {
274
+ keyAgreementAlgorithm: 'ECDH',
275
+ keyType: 'EC',
276
+ encryptionKeyAlgorithm: 'AES',
277
+ hmacAlgorithm: 'HmacSHA256',
278
+ cipher: 'AES/GCM/NoPadding',
279
+ tagLength: 128,
280
+ ivLength: 12,
281
+ };
282
+ ```
283
+
234
284
  ### 6. JWS Generation (RFC 7515)
235
285
 
236
286
  Generate [RFC 7515](https://datatracker.ietf.org/doc/html/rfc7515) compact JWS tokens. Supported algorithms: **HS256**, **HS384**, **HS512**. An explicit `secret` is always required.
@@ -408,22 +458,28 @@ const monitoredRequest = async () => {
408
458
 
409
459
  ### Key Exchange
410
460
 
411
- - `getPublicKey()` — Generate client public key (JWK)
412
- - `getSharedKey(serverPublicKey, options?)` — Derive shared secret; accepts `CryptoOptions`
413
- - `encryptBySharedKey(text, options?)` — AES-GCM encrypt with derived key
414
- - `decryptBySharedKey(encryptedText, options?)` — AES-GCM decrypt with derived key
461
+ - `Crypto.getPublicKey()` — Client public key (base64-encoded SPKI / DER)
462
+ - `Crypto.establishSharedKey(serverPublicKey, options)` — Derive shared key in native memory; **`options` required**
463
+ - `getPublicKey()` — Legacy alias for `Crypto.getPublicKey()`
464
+ - `getSharedKey(serverPublicKey, options)` — **Deprecated**; returns derived key to JS; **`options` required**
465
+ - `encryptBySharedKey(text, options)` — Encrypt with derived key; **`options` required**
466
+ - `decryptBySharedKey(encryptedText, options)` — Decrypt with derived key; **`options` required**
415
467
 
416
468
  #### `CryptoOptions`
417
469
 
418
- | Option | Default | Description |
419
- |--------|---------|-------------|
420
- | `keyAgreementAlgorithm` | `'X25519'` | Key agreement (e.g. `X25519`, `ECDH`) |
421
- | `keyType` | `'OKP'` | JWK key type (`OKP`, `EC`) |
422
- | `encryptionKeyAlgorithm` | `'AES-256'` | Symmetric key algorithm |
423
- | `hmacAlgorithm` | `'HMAC-SHA-512'` | HMAC for signing and key derivation |
424
- | `cipher` | `'AES-GCM'` | AEAD cipher mode |
425
- | `tagLength` | `128` | GCM authentication tag length (bits) |
426
- | `ivLength` | `12` | GCM IV length (bytes) |
470
+ All fields below are **required** on every key-exchange and encrypt/decrypt call. There are no library defaults — define a shared `cryptoOptions` object in your app and reuse it.
471
+
472
+ | Option | Allowed values |
473
+ |--------|----------------|
474
+ | `keyAgreementAlgorithm` | `'X25519' \| 'ECDH'` |
475
+ | `keyType` | `'OKP' \| 'EC'` (alias: `keyFactoryAlgorithm`) |
476
+ | `encryptionKeyAlgorithm` | `'AES-256' \| 'AES'` |
477
+ | `hmacAlgorithm` | `'HmacSHA256' \| 'HmacSHA384' \| 'HmacSHA512' \| 'HMAC-SHA-256' \| 'HMAC-SHA-384' \| 'HMAC-SHA-512'` (alias: `hmacKeyAlgorithm`) |
478
+ | `cipher` | `'AES-GCM' \| 'AES/GCM/NoPadding'` (alias: `cipherTransformation`) |
479
+ | `tagLength` | `number` — GCM tag length in bits (alias: `gcmTagLength`) |
480
+ | `ivLength` | `number` — GCM IV length in bytes (alias: `gcmIvLength`) |
481
+
482
+ Exported types: `CryptoOptions`, `KeyAgreementAlgorithm`, `KeyType`, `EncryptionKeyAlgorithm`, `HmacAlgorithm`, `CipherAlgorithm`.
427
483
 
428
484
  ### JWS
429
485
 
@@ -3,17 +3,9 @@ package com.securitysuite;
3
3
  import com.facebook.react.bridge.ReadableMap;
4
4
 
5
5
  /**
6
- * Configurable cryptographic parameters with secure defaults and whitelist validation.
6
+ * Cryptographic parameters supplied by the application.
7
7
  */
8
8
  public final class CryptoConfig {
9
- public static final String DEFAULT_KEY_AGREEMENT = "ECDH";
10
- public static final String DEFAULT_KEY_FACTORY = "EC";
11
- public static final String DEFAULT_ENCRYPTION_KEY_ALGORITHM = "AES";
12
- public static final String DEFAULT_HMAC_KEY_ALGORITHM = "HmacSHA256";
13
- public static final String DEFAULT_CIPHER_TRANSFORMATION = "AES/GCM/NoPadding";
14
- public static final int DEFAULT_GCM_TAG_LENGTH = 128;
15
- public static final int DEFAULT_GCM_IV_LENGTH = 12;
16
-
17
9
  public final String keyAgreementAlgorithm;
18
10
  public final String keyFactoryAlgorithm;
19
11
  public final String encryptionKeyAlgorithm;
@@ -40,35 +32,19 @@ public final class CryptoConfig {
40
32
  this.gcmIvLength = gcmIvLength;
41
33
  }
42
34
 
43
- public static CryptoConfig defaults() {
44
- return new CryptoConfig(
45
- DEFAULT_KEY_AGREEMENT,
46
- DEFAULT_KEY_FACTORY,
47
- DEFAULT_ENCRYPTION_KEY_ALGORITHM,
48
- DEFAULT_HMAC_KEY_ALGORITHM,
49
- DEFAULT_CIPHER_TRANSFORMATION,
50
- DEFAULT_GCM_TAG_LENGTH,
51
- DEFAULT_GCM_IV_LENGTH
52
- );
53
- }
54
-
55
35
  public static CryptoConfig fromReadableMap(ReadableMap options) {
56
36
  if (options == null) {
57
- return defaults();
37
+ throw new IllegalArgumentException("Crypto options are required");
58
38
  }
59
39
 
60
40
  return new CryptoConfig(
61
- validateKeyAgreement(readString(options, "keyAgreementAlgorithm", DEFAULT_KEY_AGREEMENT)),
62
- validateKeyFactory(readString(options, "keyFactoryAlgorithm", DEFAULT_KEY_FACTORY)),
63
- validateEncryptionKeyAlgorithm(
64
- readString(options, "encryptionKeyAlgorithm", DEFAULT_ENCRYPTION_KEY_ALGORITHM)
65
- ),
66
- validateHmacKeyAlgorithm(readString(options, "hmacKeyAlgorithm", DEFAULT_HMAC_KEY_ALGORITHM)),
67
- validateCipherTransformation(
68
- readString(options, "cipherTransformation", DEFAULT_CIPHER_TRANSFORMATION)
69
- ),
70
- options.hasKey("gcmTagLength") ? options.getInt("gcmTagLength") : DEFAULT_GCM_TAG_LENGTH,
71
- options.hasKey("gcmIvLength") ? options.getInt("gcmIvLength") : DEFAULT_GCM_IV_LENGTH
41
+ requireString(options, "keyAgreementAlgorithm"),
42
+ requireString(options, "keyFactoryAlgorithm"),
43
+ requireString(options, "encryptionKeyAlgorithm"),
44
+ requireString(options, "hmacKeyAlgorithm"),
45
+ requireString(options, "cipherTransformation"),
46
+ requireInt(options, "gcmTagLength"),
47
+ requireInt(options, "gcmIvLength")
72
48
  );
73
49
  }
74
50
 
@@ -110,49 +86,21 @@ public final class CryptoConfig {
110
86
  return map;
111
87
  }
112
88
 
113
- private static String readString(ReadableMap map, String key, String defaultValue) {
114
- if (map.hasKey(key) && map.getString(key) != null) {
115
- return map.getString(key).trim();
116
- }
117
- return defaultValue;
118
- }
119
-
120
- private static String validateKeyAgreement(String algorithm) {
121
- if ("ECDH".equals(algorithm)) {
122
- return algorithm;
89
+ private static String requireString(ReadableMap map, String key) {
90
+ if (!map.hasKey(key) || map.getString(key) == null) {
91
+ throw new IllegalArgumentException("Missing required crypto option: " + key);
123
92
  }
124
- throw new IllegalArgumentException("Unsupported keyAgreementAlgorithm: " + algorithm);
125
- }
126
-
127
- private static String validateKeyFactory(String algorithm) {
128
- if ("EC".equals(algorithm)) {
129
- return algorithm;
130
- }
131
- throw new IllegalArgumentException("Unsupported keyFactoryAlgorithm: " + algorithm);
132
- }
133
-
134
- private static String validateEncryptionKeyAlgorithm(String algorithm) {
135
- if ("AES".equals(algorithm)) {
136
- return algorithm;
137
- }
138
- throw new IllegalArgumentException("Unsupported encryptionKeyAlgorithm: " + algorithm);
139
- }
140
-
141
- private static String validateHmacKeyAlgorithm(String algorithm) {
142
- switch (algorithm) {
143
- case "HmacSHA256":
144
- case "HmacSHA384":
145
- case "HmacSHA512":
146
- return algorithm;
147
- default:
148
- throw new IllegalArgumentException("Unsupported hmacKeyAlgorithm: " + algorithm);
93
+ String value = map.getString(key).trim();
94
+ if (value.isEmpty()) {
95
+ throw new IllegalArgumentException("Missing required crypto option: " + key);
149
96
  }
97
+ return value;
150
98
  }
151
99
 
152
- private static String validateCipherTransformation(String transformation) {
153
- if ("AES/GCM/NoPadding".equals(transformation)) {
154
- return transformation;
100
+ private static int requireInt(ReadableMap map, String key) {
101
+ if (!map.hasKey(key)) {
102
+ throw new IllegalArgumentException("Missing required crypto option: " + key);
155
103
  }
156
- throw new IllegalArgumentException("Unsupported cipherTransformation: " + transformation);
104
+ return map.getInt(key);
157
105
  }
158
106
  }
@@ -11,8 +11,8 @@ import java.security.SecureRandom;
11
11
  import java.util.regex.Pattern;
12
12
 
13
13
  /**
14
- * Shared cryptographic utilities. HKDF-SHA256 (RFC 5869) is used instead of raw
15
- * ECDH output or single-pass SHA-256 to derive independent symmetric keys.
14
+ * Shared cryptographic utilities. HKDF (RFC 5869) is used instead of raw
15
+ * key-agreement output or single-pass SHA-256 to derive independent symmetric keys.
16
16
  */
17
17
  public final class CryptoUtils {
18
18
  public static final String HKDF_SALT = "react-native-security-suite";
@@ -24,18 +24,19 @@ public final class CryptoUtils {
24
24
 
25
25
  private CryptoUtils() {}
26
26
 
27
- /** RFC 5869 HKDF-SHA256 expand/extract. */
28
- public static byte[] hkdfSha256(byte[] ikm, byte[] salt, byte[] info, int length) throws Exception {
27
+ /** RFC 5869 HKDF expand/extract using the configured HMAC algorithm. */
28
+ public static byte[] hkdf(byte[] ikm, byte[] salt, byte[] info, int length, String macAlgorithm)
29
+ throws Exception {
29
30
  byte[] actualSalt = (salt == null || salt.length == 0)
30
31
  ? new byte[32]
31
32
  : salt;
32
33
 
33
- Mac extractMac = Mac.getInstance("HmacSHA256");
34
- extractMac.init(new SecretKeySpec(actualSalt, "HmacSHA256"));
34
+ Mac extractMac = Mac.getInstance(macAlgorithm);
35
+ extractMac.init(new SecretKeySpec(actualSalt, macAlgorithm));
35
36
  byte[] prk = extractMac.doFinal(ikm);
36
37
 
37
- Mac expandMac = Mac.getInstance("HmacSHA256");
38
- expandMac.init(new SecretKeySpec(prk, "HmacSHA256"));
38
+ Mac expandMac = Mac.getInstance(macAlgorithm);
39
+ expandMac.init(new SecretKeySpec(prk, macAlgorithm));
39
40
 
40
41
  byte[] result = new byte[length];
41
42
  byte[] previous = new byte[0];
@@ -59,21 +60,23 @@ public final class CryptoUtils {
59
60
  return result;
60
61
  }
61
62
 
62
- public static byte[] deriveEncryptionKey(byte[] sharedSecret) throws Exception {
63
- return hkdfSha256(
63
+ public static byte[] deriveEncryptionKey(byte[] sharedSecret, String macAlgorithm) throws Exception {
64
+ return hkdf(
64
65
  sharedSecret,
65
66
  HKDF_SALT.getBytes(StandardCharsets.UTF_8),
66
67
  HKDF_INFO_ENCRYPTION.getBytes(StandardCharsets.UTF_8),
67
- 32
68
+ 32,
69
+ macAlgorithm
68
70
  );
69
71
  }
70
72
 
71
- public static byte[] deriveHmacKey(byte[] sharedSecret) throws Exception {
72
- return hkdfSha256(
73
+ public static byte[] deriveHmacKey(byte[] sharedSecret, String macAlgorithm) throws Exception {
74
+ return hkdf(
73
75
  sharedSecret,
74
76
  HKDF_SALT.getBytes(StandardCharsets.UTF_8),
75
77
  HKDF_INFO_HMAC.getBytes(StandardCharsets.UTF_8),
76
- 32
78
+ 32,
79
+ macAlgorithm
77
80
  );
78
81
  }
79
82
 
@@ -42,7 +42,7 @@ public class SecuritySuiteModule extends ReactContextBaseJavaModule {
42
42
 
43
43
  private SecretKey encryptionKey;
44
44
  private SecretKey hmacKey;
45
- private CryptoConfig cryptoConfig = CryptoConfig.defaults();
45
+ private CryptoConfig cryptoConfig;
46
46
 
47
47
  public SecuritySuiteModule(ReactApplicationContext reactContext) {
48
48
  super(reactContext);
@@ -80,8 +80,8 @@ public class SecuritySuiteModule extends ReactContextBaseJavaModule {
80
80
  keyAgree.doPhase(serverPublicKey, true);
81
81
  byte[] sharedSecret = keyAgree.generateSecret();
82
82
 
83
- byte[] encKeyBytes = CryptoUtils.deriveEncryptionKey(sharedSecret);
84
- byte[] macKeyBytes = CryptoUtils.deriveHmacKey(sharedSecret);
83
+ byte[] encKeyBytes = CryptoUtils.deriveEncryptionKey(sharedSecret, cryptoConfig.hmacKeyAlgorithm);
84
+ byte[] macKeyBytes = CryptoUtils.deriveHmacKey(sharedSecret, cryptoConfig.hmacKeyAlgorithm);
85
85
  encryptionKey = new SecretKeySpec(encKeyBytes, cryptoConfig.encryptionKeyAlgorithm);
86
86
  hmacKey = new SecretKeySpec(macKeyBytes, cryptoConfig.hmacKeyAlgorithm);
87
87
 
@@ -114,8 +114,8 @@ public class SecuritySuiteModule extends ReactContextBaseJavaModule {
114
114
  keyAgree.doPhase(serverPublicKey, true);
115
115
  byte[] sharedSecret = keyAgree.generateSecret();
116
116
 
117
- byte[] encKeyBytes = CryptoUtils.deriveEncryptionKey(sharedSecret);
118
- byte[] macKeyBytes = CryptoUtils.deriveHmacKey(sharedSecret);
117
+ byte[] encKeyBytes = CryptoUtils.deriveEncryptionKey(sharedSecret, cryptoConfig.hmacKeyAlgorithm);
118
+ byte[] macKeyBytes = CryptoUtils.deriveHmacKey(sharedSecret, cryptoConfig.hmacKeyAlgorithm);
119
119
  encryptionKey = new SecretKeySpec(encKeyBytes, cryptoConfig.encryptionKeyAlgorithm);
120
120
  hmacKey = new SecretKeySpec(macKeyBytes, cryptoConfig.hmacKeyAlgorithm);
121
121
 
@@ -133,7 +133,7 @@ public class SecuritySuiteModule extends ReactContextBaseJavaModule {
133
133
  promise.reject("ENCRYPT_ERROR", "Encryption key not established. Call getSharedKey first.");
134
134
  return;
135
135
  }
136
- CryptoConfig config = cryptoConfig.merge(options);
136
+ CryptoConfig config = resolveCryptoConfig(options);
137
137
  byte[] inputByte = input.getBytes(StandardCharsets.UTF_8);
138
138
  Cipher cipher = Cipher.getInstance(config.cipherTransformation);
139
139
  cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
@@ -155,7 +155,7 @@ public class SecuritySuiteModule extends ReactContextBaseJavaModule {
155
155
  promise.reject("DECRYPT_ERROR", "Encryption key not established. Call getSharedKey first.");
156
156
  return;
157
157
  }
158
- CryptoConfig config = cryptoConfig.merge(options);
158
+ CryptoConfig config = resolveCryptoConfig(options);
159
159
  byte[] inputBytes = Base64.decode(input.getBytes(StandardCharsets.UTF_8), Base64.NO_WRAP);
160
160
  int minLength = config.gcmIvLength + (config.gcmTagLength / 8);
161
161
  if (inputBytes.length < minLength) {
@@ -352,6 +352,13 @@ public class SecuritySuiteModule extends ReactContextBaseJavaModule {
352
352
  }
353
353
  }
354
354
 
355
+ private CryptoConfig resolveCryptoConfig(ReadableMap options) {
356
+ if (cryptoConfig != null) {
357
+ return cryptoConfig.merge(options);
358
+ }
359
+ return CryptoConfig.fromReadableMap(options);
360
+ }
361
+
355
362
  private static String secureStorageMessage(Exception error) {
356
363
  String message = error.getMessage();
357
364
  if (message != null && !message.isEmpty()) {
@@ -2,14 +2,6 @@ import Foundation
2
2
 
3
3
  @available(iOS 13.0, *)
4
4
  struct CryptoConfig {
5
- static let defaultKeyAgreement = "ECDH"
6
- static let defaultKeyFactory = "EC"
7
- static let defaultEncryptionKeyAlgorithm = "AES"
8
- static let defaultHmacKeyAlgorithm = "HmacSHA256"
9
- static let defaultCipherTransformation = "AES/GCM/NoPadding"
10
- static let defaultGcmTagLength = 128
11
- static let defaultGcmIvLength = 12
12
-
13
5
  let keyAgreementAlgorithm: String
14
6
  let keyFactoryAlgorithm: String
15
7
  let encryptionKeyAlgorithm: String
@@ -18,41 +10,21 @@ struct CryptoConfig {
18
10
  let gcmTagLength: Int
19
11
  let gcmIvLength: Int
20
12
 
21
- static func defaults() -> CryptoConfig {
22
- CryptoConfig(
23
- keyAgreementAlgorithm: defaultKeyAgreement,
24
- keyFactoryAlgorithm: defaultKeyFactory,
25
- encryptionKeyAlgorithm: defaultEncryptionKeyAlgorithm,
26
- hmacKeyAlgorithm: defaultHmacKeyAlgorithm,
27
- cipherTransformation: defaultCipherTransformation,
28
- gcmTagLength: defaultGcmTagLength,
29
- gcmIvLength: defaultGcmIvLength
30
- )
31
- }
32
-
33
13
  static func from(dictionary: NSDictionary?) throws -> CryptoConfig {
34
14
  guard let dictionary = dictionary else {
35
- return defaults()
15
+ throw NSError(domain: "CryptoConfig", code: 0, userInfo: [
16
+ NSLocalizedDescriptionKey: "Crypto options are required",
17
+ ])
36
18
  }
37
19
 
38
20
  return CryptoConfig(
39
- keyAgreementAlgorithm: try validateKeyAgreement(
40
- dictionary["keyAgreementAlgorithm"] as? String ?? defaultKeyAgreement
41
- ),
42
- keyFactoryAlgorithm: try validateKeyFactory(
43
- dictionary["keyFactoryAlgorithm"] as? String ?? defaultKeyFactory
44
- ),
45
- encryptionKeyAlgorithm: try validateEncryptionKeyAlgorithm(
46
- dictionary["encryptionKeyAlgorithm"] as? String ?? defaultEncryptionKeyAlgorithm
47
- ),
48
- hmacKeyAlgorithm: try validateHmacKeyAlgorithm(
49
- dictionary["hmacKeyAlgorithm"] as? String ?? defaultHmacKeyAlgorithm
50
- ),
51
- cipherTransformation: try validateCipherTransformation(
52
- dictionary["cipherTransformation"] as? String ?? defaultCipherTransformation
53
- ),
54
- gcmTagLength: dictionary["gcmTagLength"] as? Int ?? defaultGcmTagLength,
55
- gcmIvLength: dictionary["gcmIvLength"] as? Int ?? defaultGcmIvLength
21
+ keyAgreementAlgorithm: try requireString(dictionary, key: "keyAgreementAlgorithm"),
22
+ keyFactoryAlgorithm: try requireString(dictionary, key: "keyFactoryAlgorithm"),
23
+ encryptionKeyAlgorithm: try requireString(dictionary, key: "encryptionKeyAlgorithm"),
24
+ hmacKeyAlgorithm: try requireString(dictionary, key: "hmacKeyAlgorithm"),
25
+ cipherTransformation: try requireString(dictionary, key: "cipherTransformation"),
26
+ gcmTagLength: try requireInt(dictionary, key: "gcmTagLength"),
27
+ gcmIvLength: try requireInt(dictionary, key: "gcmIvLength")
56
28
  )
57
29
  }
58
30
 
@@ -75,50 +47,27 @@ struct CryptoConfig {
75
47
  return try CryptoConfig.from(dictionary: merged as NSDictionary)
76
48
  }
77
49
 
78
- private static func validateKeyAgreement(_ algorithm: String) throws -> String {
79
- guard algorithm == "ECDH" else {
80
- throw NSError(domain: "CryptoConfig", code: 1, userInfo: [
81
- NSLocalizedDescriptionKey: "Unsupported keyAgreementAlgorithm: \(algorithm)",
50
+ private static func requireString(_ dictionary: NSDictionary, key: String) throws -> String {
51
+ guard let value = dictionary[key] as? String else {
52
+ throw NSError(domain: "CryptoConfig", code: 0, userInfo: [
53
+ NSLocalizedDescriptionKey: "Missing required crypto option: \(key)",
82
54
  ])
83
55
  }
84
- return algorithm
85
- }
86
-
87
- private static func validateKeyFactory(_ algorithm: String) throws -> String {
88
- guard algorithm == "EC" else {
89
- throw NSError(domain: "CryptoConfig", code: 2, userInfo: [
90
- NSLocalizedDescriptionKey: "Unsupported keyFactoryAlgorithm: \(algorithm)",
91
- ])
92
- }
93
- return algorithm
94
- }
95
-
96
- private static func validateEncryptionKeyAlgorithm(_ algorithm: String) throws -> String {
97
- guard algorithm == "AES" else {
98
- throw NSError(domain: "CryptoConfig", code: 3, userInfo: [
99
- NSLocalizedDescriptionKey: "Unsupported encryptionKeyAlgorithm: \(algorithm)",
100
- ])
101
- }
102
- return algorithm
103
- }
104
-
105
- private static func validateHmacKeyAlgorithm(_ algorithm: String) throws -> String {
106
- switch algorithm {
107
- case "HmacSHA256", "HmacSHA384", "HmacSHA512":
108
- return algorithm
109
- default:
110
- throw NSError(domain: "CryptoConfig", code: 4, userInfo: [
111
- NSLocalizedDescriptionKey: "Unsupported hmacKeyAlgorithm: \(algorithm)",
56
+ let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
57
+ guard !trimmed.isEmpty else {
58
+ throw NSError(domain: "CryptoConfig", code: 0, userInfo: [
59
+ NSLocalizedDescriptionKey: "Missing required crypto option: \(key)",
112
60
  ])
113
61
  }
62
+ return trimmed
114
63
  }
115
64
 
116
- private static func validateCipherTransformation(_ transformation: String) throws -> String {
117
- guard transformation == "AES/GCM/NoPadding" else {
118
- throw NSError(domain: "CryptoConfig", code: 5, userInfo: [
119
- NSLocalizedDescriptionKey: "Unsupported cipherTransformation: \(transformation)",
65
+ private static func requireInt(_ dictionary: NSDictionary, key: String) throws -> Int {
66
+ guard let value = dictionary[key] as? Int else {
67
+ throw NSError(domain: "CryptoConfig", code: 0, userInfo: [
68
+ NSLocalizedDescriptionKey: "Missing required crypto option: \(key)",
120
69
  ])
121
70
  }
122
- return transformation
71
+ return value
123
72
  }
124
73
  }
@@ -13,7 +13,7 @@ class SecuritySuite: NSObject {
13
13
  private var privateKeyData: Data?
14
14
  private var encryptionKeyData: Data?
15
15
  private var hmacKeyData: Data?
16
- private var cryptoConfig = CryptoConfig.defaults()
16
+ private var cryptoConfig: CryptoConfig?
17
17
 
18
18
  private func loadOrCreateECDHKeyPair() throws -> P256.KeyAgreement.PrivateKey {
19
19
  if let stored = try KeychainHelper.shared.loadECDHKeyPair() {
@@ -30,6 +30,43 @@ class SecuritySuite: NSObject {
30
30
  return key
31
31
  }
32
32
 
33
+ private func resolveCryptoConfig(options: NSDictionary?) throws -> CryptoConfig {
34
+ if let cryptoConfig {
35
+ return try cryptoConfig.merged(with: options)
36
+ }
37
+ return try CryptoConfig.from(dictionary: options)
38
+ }
39
+
40
+ private func hkdfHash(for macAlgorithm: String) throws -> any HashFunction.Type {
41
+ switch macAlgorithm {
42
+ case "HmacSHA256", "HMAC-SHA-256":
43
+ return SHA256.self
44
+ case "HmacSHA384", "HMAC-SHA-384":
45
+ return SHA384.self
46
+ case "HmacSHA512", "HMAC-SHA-512":
47
+ return SHA512.self
48
+ default:
49
+ throw NSError(domain: "CryptoConfig", code: 6, userInfo: [
50
+ NSLocalizedDescriptionKey: "Unsupported hkdf mac algorithm: \(macAlgorithm)",
51
+ ])
52
+ }
53
+ }
54
+
55
+ private func deriveSymmetricKey(
56
+ from sharedSecret: SharedSecret,
57
+ macAlgorithm: String,
58
+ info: Data,
59
+ outputByteCount: Int
60
+ ) throws -> Data {
61
+ let hash = try hkdfHash(for: macAlgorithm)
62
+ return sharedSecret.hkdfDerivedSymmetricKey(
63
+ using: hash,
64
+ salt: hkdfSalt,
65
+ sharedInfo: info,
66
+ outputByteCount: outputByteCount
67
+ ).withUnsafeBytes { Data($0) }
68
+ }
69
+
33
70
  @objc(getPublicKey:withRejecter:)
34
71
  func getPublicKey(resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
35
72
  do {
@@ -48,13 +85,8 @@ class SecuritySuite: NSObject {
48
85
  reject: RCTPromiseRejectBlock
49
86
  ) {
50
87
  do {
51
- cryptoConfig = try CryptoConfig.from(dictionary: options)
52
-
53
- guard cryptoConfig.keyAgreementAlgorithm == "ECDH",
54
- cryptoConfig.keyFactoryAlgorithm == "EC" else {
55
- reject("GET_SHARED_KEY_ERROR", "Only ECDH/EC key agreement is supported on iOS", nil)
56
- return
57
- }
88
+ let config = try CryptoConfig.from(dictionary: options)
89
+ cryptoConfig = config
58
90
 
59
91
  let serverKeyString = (serverPK as String).trimmingCharacters(in: .whitespacesAndNewlines)
60
92
  guard !serverKeyString.isEmpty,
@@ -68,19 +100,19 @@ class SecuritySuite: NSObject {
68
100
  with: P256.KeyAgreement.PublicKey(derRepresentation: serverPublicKeyData)
69
101
  )
70
102
 
71
- encryptionKeyData = sharedSecret.hkdfDerivedSymmetricKey(
72
- using: SHA256.self,
73
- salt: hkdfSalt,
74
- sharedInfo: hkdfInfoEncryption,
103
+ encryptionKeyData = try deriveSymmetricKey(
104
+ from: sharedSecret,
105
+ macAlgorithm: config.hmacKeyAlgorithm,
106
+ info: hkdfInfoEncryption,
75
107
  outputByteCount: 32
76
- ).withUnsafeBytes { Data($0) }
108
+ )
77
109
 
78
- hmacKeyData = sharedSecret.hkdfDerivedSymmetricKey(
79
- using: SHA256.self,
80
- salt: hkdfSalt,
81
- sharedInfo: hkdfInfoHmac,
110
+ hmacKeyData = try deriveSymmetricKey(
111
+ from: sharedSecret,
112
+ macAlgorithm: config.hmacKeyAlgorithm,
113
+ info: hkdfInfoHmac,
82
114
  outputByteCount: 32
83
- ).withUnsafeBytes { Data($0) }
115
+ )
84
116
 
85
117
  resolve(nil)
86
118
  } catch {
@@ -96,13 +128,8 @@ class SecuritySuite: NSObject {
96
128
  reject: RCTPromiseRejectBlock
97
129
  ) {
98
130
  do {
99
- cryptoConfig = try CryptoConfig.from(dictionary: options)
100
-
101
- guard cryptoConfig.keyAgreementAlgorithm == "ECDH",
102
- cryptoConfig.keyFactoryAlgorithm == "EC" else {
103
- reject("GET_SHARED_KEY_ERROR", "Only ECDH/EC key agreement is supported on iOS", nil)
104
- return
105
- }
131
+ let config = try CryptoConfig.from(dictionary: options)
132
+ cryptoConfig = config
106
133
 
107
134
  let serverKeyString = (serverPK as String).trimmingCharacters(in: .whitespacesAndNewlines)
108
135
  guard !serverKeyString.isEmpty,
@@ -116,19 +143,19 @@ class SecuritySuite: NSObject {
116
143
  with: P256.KeyAgreement.PublicKey(derRepresentation: serverPublicKeyData)
117
144
  )
118
145
 
119
- encryptionKeyData = sharedSecret.hkdfDerivedSymmetricKey(
120
- using: SHA256.self,
121
- salt: hkdfSalt,
122
- sharedInfo: hkdfInfoEncryption,
146
+ encryptionKeyData = try deriveSymmetricKey(
147
+ from: sharedSecret,
148
+ macAlgorithm: config.hmacKeyAlgorithm,
149
+ info: hkdfInfoEncryption,
123
150
  outputByteCount: 32
124
- ).withUnsafeBytes { Data($0) }
151
+ )
125
152
 
126
- hmacKeyData = sharedSecret.hkdfDerivedSymmetricKey(
127
- using: SHA256.self,
128
- salt: hkdfSalt,
129
- sharedInfo: hkdfInfoHmac,
153
+ hmacKeyData = try deriveSymmetricKey(
154
+ from: sharedSecret,
155
+ macAlgorithm: config.hmacKeyAlgorithm,
156
+ info: hkdfInfoHmac,
130
157
  outputByteCount: 32
131
- ).withUnsafeBytes { Data($0) }
158
+ )
132
159
 
133
160
  resolve(encryptionKeyData?.base64EncodedString())
134
161
  } catch {
@@ -148,12 +175,7 @@ class SecuritySuite: NSObject {
148
175
  return
149
176
  }
150
177
  do {
151
- let config = try cryptoConfig.merged(with: options)
152
- guard config.cipherTransformation == "AES/GCM/NoPadding",
153
- config.encryptionKeyAlgorithm == "AES" else {
154
- reject("ENCRYPT_ERROR", "Only AES/GCM/NoPadding is supported on iOS", nil)
155
- return
156
- }
178
+ _ = try resolveCryptoConfig(options: options)
157
179
 
158
180
  let data = Data((input as String).utf8)
159
181
  let key = SymmetricKey(data: keyData)
@@ -183,12 +205,7 @@ class SecuritySuite: NSObject {
183
205
  return
184
206
  }
185
207
  do {
186
- let config = try cryptoConfig.merged(with: options)
187
- guard config.cipherTransformation == "AES/GCM/NoPadding",
188
- config.encryptionKeyAlgorithm == "AES" else {
189
- reject("DECRYPT_ERROR", "Only AES/GCM/NoPadding is supported on iOS", nil)
190
- return
191
- }
208
+ _ = try resolveCryptoConfig(options: options)
192
209
 
193
210
  let key = SymmetricKey(data: keyData)
194
211
  let output = try AES.GCM.open(AES.GCM.SealedBox(combined: data), using: key)
@@ -5,17 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.Crypto = void 0;
7
7
  var _bridge = require("../native/bridge.js");
8
- function toNativeCryptoOptions(options) {
9
- return {
10
- keyAgreementAlgorithm: options?.keyAgreementAlgorithm ?? 'X25519',
11
- keyFactoryAlgorithm: options?.keyType ?? options?.keyFactoryAlgorithm ?? 'OKP',
12
- encryptionKeyAlgorithm: options?.encryptionKeyAlgorithm ?? 'AES-256',
13
- hmacKeyAlgorithm: options?.hmacAlgorithm ?? options?.hmacKeyAlgorithm ?? 'HMAC-SHA-512',
14
- cipherTransformation: options?.cipher ?? options?.cipherTransformation ?? 'AES-GCM',
15
- gcmTagLength: options?.tagLength ?? options?.gcmTagLength ?? 128,
16
- gcmIvLength: options?.ivLength ?? options?.gcmIvLength ?? 12
17
- };
18
- }
8
+ var _cryptoOptions = require("../legacy/cryptoOptions.js");
19
9
  const Crypto = exports.Crypto = {
20
10
  getPublicKey() {
21
11
  return (0, _bridge.getNativeModule)().getPublicKey();
@@ -26,7 +16,7 @@ const Crypto = exports.Crypto = {
26
16
  */
27
17
  establishSharedKey(serverPublicKey, options) {
28
18
  const native = (0, _bridge.getNativeModule)();
29
- const nativeOptions = toNativeCryptoOptions(options);
19
+ const nativeOptions = (0, _cryptoOptions.toNativeCryptoOptions)(options);
30
20
  if (options?.returnSharedKey) {
31
21
  return native.getSharedKey(serverPublicKey, nativeOptions);
32
22
  }
@@ -1 +1 @@
1
- {"version":3,"names":["_bridge","require","toNativeCryptoOptions","options","keyAgreementAlgorithm","keyFactoryAlgorithm","keyType","encryptionKeyAlgorithm","hmacKeyAlgorithm","hmacAlgorithm","cipherTransformation","cipher","gcmTagLength","tagLength","gcmIvLength","ivLength","Crypto","exports","getPublicKey","getNativeModule","establishSharedKey","serverPublicKey","native","nativeOptions","returnSharedKey","getSharedKey","then","undefined"],"sourceRoot":"../../../src","sources":["crypto/index.ts"],"mappings":";;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAGA,SAASC,qBAAqBA,CAACC,OAA8B,EAAE;EAC7D,OAAO;IACLC,qBAAqB,EAAED,OAAO,EAAEC,qBAAqB,IAAI,QAAQ;IACjEC,mBAAmB,EAAEF,OAAO,EAAEG,OAAO,IAAIH,OAAO,EAAEE,mBAAmB,IAAI,KAAK;IAC9EE,sBAAsB,EAAEJ,OAAO,EAAEI,sBAAsB,IAAI,SAAS;IACpEC,gBAAgB,EAAEL,OAAO,EAAEM,aAAa,IAAIN,OAAO,EAAEK,gBAAgB,IAAI,cAAc;IACvFE,oBAAoB,EAAEP,OAAO,EAAEQ,MAAM,IAAIR,OAAO,EAAEO,oBAAoB,IAAI,SAAS;IACnFE,YAAY,EAAET,OAAO,EAAEU,SAAS,IAAIV,OAAO,EAAES,YAAY,IAAI,GAAG;IAChEE,WAAW,EAAEX,OAAO,EAAEY,QAAQ,IAAIZ,OAAO,EAAEW,WAAW,IAAI;EAC5D,CAAC;AACH;AAOO,MAAME,MAAM,GAAAC,OAAA,CAAAD,MAAA,GAAG;EACpBE,YAAYA,CAAA,EAAoB;IAC9B,OAAO,IAAAC,uBAAe,EAAC,CAAC,CAACD,YAAY,CAAC,CAAC;EACzC,CAAC;EAED;AACF;AACA;AACA;EACEE,kBAAkBA,CAChBC,eAAuB,EACvBlB,OAAmC,EACX;IACxB,MAAMmB,MAAM,GAAG,IAAAH,uBAAe,EAAC,CAAC;IAChC,MAAMI,aAAa,GAAGrB,qBAAqB,CAACC,OAAO,CAAC;IAEpD,IAAIA,OAAO,EAAEqB,eAAe,EAAE;MAC5B,OAAOF,MAAM,CAACG,YAAY,CAACJ,eAAe,EAAEE,aAAa,CAAC;IAC5D;IAEA,IAAI,OAAOD,MAAM,CAACF,kBAAkB,KAAK,UAAU,EAAE;MACnD,OAAOE,MAAM,CAACF,kBAAkB,CAACC,eAAe,EAAEE,aAAa,CAAC;IAClE;IAEA,OAAOD,MAAM,CAACG,YAAY,CAACJ,eAAe,EAAEE,aAAa,CAAC,CAACG,IAAI,CAAC,MAAMC,SAAS,CAAC;EAClF;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_bridge","require","_cryptoOptions","Crypto","exports","getPublicKey","getNativeModule","establishSharedKey","serverPublicKey","options","native","nativeOptions","toNativeCryptoOptions","returnSharedKey","getSharedKey","then","undefined"],"sourceRoot":"../../../src","sources":["crypto/index.ts"],"mappings":";;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,cAAA,GAAAD,OAAA;AAUO,MAAME,MAAM,GAAAC,OAAA,CAAAD,MAAA,GAAG;EACpBE,YAAYA,CAAA,EAAoB;IAC9B,OAAO,IAAAC,uBAAe,EAAC,CAAC,CAACD,YAAY,CAAC,CAAC;EACzC,CAAC;EAED;AACF;AACA;AACA;EACEE,kBAAkBA,CAChBC,eAAuB,EACvBC,OAAmC,EACX;IACxB,MAAMC,MAAM,GAAG,IAAAJ,uBAAe,EAAC,CAAC;IAChC,MAAMK,aAAa,GAAG,IAAAC,oCAAqB,EAACH,OAAO,CAAC;IAEpD,IAAIA,OAAO,EAAEI,eAAe,EAAE;MAC5B,OAAOH,MAAM,CAACI,YAAY,CAACN,eAAe,EAAEG,aAAa,CAAC;IAC5D;IAEA,IAAI,OAAOD,MAAM,CAACH,kBAAkB,KAAK,UAAU,EAAE;MACnD,OAAOG,MAAM,CAACH,kBAAkB,CAACC,eAAe,EAAEG,aAAa,CAAC;IAClE;IAEA,OAAOD,MAAM,CAACI,YAAY,CAACN,eAAe,EAAEG,aAAa,CAAC,CAACI,IAAI,CAAC,MAAMC,SAAS,CAAC;EAClF;AACF,CAAC","ignoreList":[]}
@@ -6,15 +6,24 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.toNativeCryptoOptions = toNativeCryptoOptions;
7
7
  /** Shared crypto option types used by legacy exports and the Crypto namespace. */
8
8
 
9
+ function requireCryptoOption(value, key) {
10
+ if (value === undefined || value === null || value === '') {
11
+ throw new Error(`Missing required crypto option: ${key}`);
12
+ }
13
+ return value;
14
+ }
9
15
  function toNativeCryptoOptions(options) {
16
+ if (!options) {
17
+ throw new Error('Crypto options are required');
18
+ }
10
19
  return {
11
- keyAgreementAlgorithm: options?.keyAgreementAlgorithm ?? 'X25519',
12
- keyFactoryAlgorithm: options?.keyType ?? options?.keyFactoryAlgorithm ?? 'OKP',
13
- encryptionKeyAlgorithm: options?.encryptionKeyAlgorithm ?? 'AES-256',
14
- hmacKeyAlgorithm: options?.hmacAlgorithm ?? options?.hmacKeyAlgorithm ?? 'HMAC-SHA-512',
15
- cipherTransformation: options?.cipher ?? options?.cipherTransformation ?? 'AES-GCM',
16
- gcmTagLength: options?.tagLength ?? options?.gcmTagLength ?? 128,
17
- gcmIvLength: options?.ivLength ?? options?.gcmIvLength ?? 12
20
+ keyAgreementAlgorithm: requireCryptoOption(options.keyAgreementAlgorithm, 'keyAgreementAlgorithm'),
21
+ keyFactoryAlgorithm: requireCryptoOption(options.keyType ?? options.keyFactoryAlgorithm, 'keyFactoryAlgorithm'),
22
+ encryptionKeyAlgorithm: requireCryptoOption(options.encryptionKeyAlgorithm, 'encryptionKeyAlgorithm'),
23
+ hmacKeyAlgorithm: requireCryptoOption(options.hmacAlgorithm ?? options.hmacKeyAlgorithm, 'hmacKeyAlgorithm'),
24
+ cipherTransformation: requireCryptoOption(options.cipher ?? options.cipherTransformation, 'cipherTransformation'),
25
+ gcmTagLength: requireCryptoOption(options.tagLength ?? options.gcmTagLength, 'gcmTagLength'),
26
+ gcmIvLength: requireCryptoOption(options.ivLength ?? options.gcmIvLength, 'gcmIvLength')
18
27
  };
19
28
  }
20
29
  //# sourceMappingURL=cryptoOptions.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["toNativeCryptoOptions","options","keyAgreementAlgorithm","keyFactoryAlgorithm","keyType","encryptionKeyAlgorithm","hmacKeyAlgorithm","hmacAlgorithm","cipherTransformation","cipher","gcmTagLength","tagLength","gcmIvLength","ivLength"],"sourceRoot":"../../../src","sources":["legacy/cryptoOptions.ts"],"mappings":";;;;;;AAAA;;AAsCO,SAASA,qBAAqBA,CAACC,OAA8B,EAAE;EACpE,OAAO;IACLC,qBAAqB,EAAED,OAAO,EAAEC,qBAAqB,IAAI,QAAQ;IACjEC,mBAAmB,EAAEF,OAAO,EAAEG,OAAO,IAAIH,OAAO,EAAEE,mBAAmB,IAAI,KAAK;IAC9EE,sBAAsB,EAAEJ,OAAO,EAAEI,sBAAsB,IAAI,SAAS;IACpEC,gBAAgB,EAAEL,OAAO,EAAEM,aAAa,IAAIN,OAAO,EAAEK,gBAAgB,IAAI,cAAc;IACvFE,oBAAoB,EAAEP,OAAO,EAAEQ,MAAM,IAAIR,OAAO,EAAEO,oBAAoB,IAAI,SAAS;IACnFE,YAAY,EAAET,OAAO,EAAEU,SAAS,IAAIV,OAAO,EAAES,YAAY,IAAI,GAAG;IAChEE,WAAW,EAAEX,OAAO,EAAEY,QAAQ,IAAIZ,OAAO,EAAEW,WAAW,IAAI;EAC5D,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"names":["requireCryptoOption","value","key","undefined","Error","toNativeCryptoOptions","options","keyAgreementAlgorithm","keyFactoryAlgorithm","keyType","encryptionKeyAlgorithm","hmacKeyAlgorithm","hmacAlgorithm","cipherTransformation","cipher","gcmTagLength","tagLength","gcmIvLength","ivLength"],"sourceRoot":"../../../src","sources":["legacy/cryptoOptions.ts"],"mappings":";;;;;;AAAA;;AAsCA,SAASA,mBAAmBA,CAC1BC,KAA2B,EAC3BC,GAAW,EACR;EACH,IAAID,KAAK,KAAKE,SAAS,IAAIF,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAK,EAAE,EAAE;IACzD,MAAM,IAAIG,KAAK,CAAC,mCAAmCF,GAAG,EAAE,CAAC;EAC3D;EACA,OAAOD,KAAK;AACd;AAEO,SAASI,qBAAqBA,CAACC,OAA8B,EAAE;EACpE,IAAI,CAACA,OAAO,EAAE;IACZ,MAAM,IAAIF,KAAK,CAAC,6BAA6B,CAAC;EAChD;EAEA,OAAO;IACLG,qBAAqB,EAAEP,mBAAmB,CACxCM,OAAO,CAACC,qBAAqB,EAC7B,uBACF,CAAC;IACDC,mBAAmB,EAAER,mBAAmB,CACtCM,OAAO,CAACG,OAAO,IAAIH,OAAO,CAACE,mBAAmB,EAC9C,qBACF,CAAC;IACDE,sBAAsB,EAAEV,mBAAmB,CACzCM,OAAO,CAACI,sBAAsB,EAC9B,wBACF,CAAC;IACDC,gBAAgB,EAAEX,mBAAmB,CACnCM,OAAO,CAACM,aAAa,IAAIN,OAAO,CAACK,gBAAgB,EACjD,kBACF,CAAC;IACDE,oBAAoB,EAAEb,mBAAmB,CACvCM,OAAO,CAACQ,MAAM,IAAIR,OAAO,CAACO,oBAAoB,EAC9C,sBACF,CAAC;IACDE,YAAY,EAAEf,mBAAmB,CAC/BM,OAAO,CAACU,SAAS,IAAIV,OAAO,CAACS,YAAY,EACzC,cACF,CAAC;IACDE,WAAW,EAAEjB,mBAAmB,CAC9BM,OAAO,CAACY,QAAQ,IAAIZ,OAAO,CAACW,WAAW,EACvC,aACF;EACF,CAAC;AACH","ignoreList":[]}
@@ -1,17 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import { getNativeModule } from "../native/bridge.js";
4
- function toNativeCryptoOptions(options) {
5
- return {
6
- keyAgreementAlgorithm: options?.keyAgreementAlgorithm ?? 'X25519',
7
- keyFactoryAlgorithm: options?.keyType ?? options?.keyFactoryAlgorithm ?? 'OKP',
8
- encryptionKeyAlgorithm: options?.encryptionKeyAlgorithm ?? 'AES-256',
9
- hmacKeyAlgorithm: options?.hmacAlgorithm ?? options?.hmacKeyAlgorithm ?? 'HMAC-SHA-512',
10
- cipherTransformation: options?.cipher ?? options?.cipherTransformation ?? 'AES-GCM',
11
- gcmTagLength: options?.tagLength ?? options?.gcmTagLength ?? 128,
12
- gcmIvLength: options?.ivLength ?? options?.gcmIvLength ?? 12
13
- };
14
- }
4
+ import { toNativeCryptoOptions } from "../legacy/cryptoOptions.js";
15
5
  export const Crypto = {
16
6
  getPublicKey() {
17
7
  return getNativeModule().getPublicKey();
@@ -1 +1 @@
1
- {"version":3,"names":["getNativeModule","toNativeCryptoOptions","options","keyAgreementAlgorithm","keyFactoryAlgorithm","keyType","encryptionKeyAlgorithm","hmacKeyAlgorithm","hmacAlgorithm","cipherTransformation","cipher","gcmTagLength","tagLength","gcmIvLength","ivLength","Crypto","getPublicKey","establishSharedKey","serverPublicKey","native","nativeOptions","returnSharedKey","getSharedKey","then","undefined"],"sourceRoot":"../../../src","sources":["crypto/index.ts"],"mappings":";;AAAA,SAASA,eAAe,QAAQ,qBAAkB;AAGlD,SAASC,qBAAqBA,CAACC,OAA8B,EAAE;EAC7D,OAAO;IACLC,qBAAqB,EAAED,OAAO,EAAEC,qBAAqB,IAAI,QAAQ;IACjEC,mBAAmB,EAAEF,OAAO,EAAEG,OAAO,IAAIH,OAAO,EAAEE,mBAAmB,IAAI,KAAK;IAC9EE,sBAAsB,EAAEJ,OAAO,EAAEI,sBAAsB,IAAI,SAAS;IACpEC,gBAAgB,EAAEL,OAAO,EAAEM,aAAa,IAAIN,OAAO,EAAEK,gBAAgB,IAAI,cAAc;IACvFE,oBAAoB,EAAEP,OAAO,EAAEQ,MAAM,IAAIR,OAAO,EAAEO,oBAAoB,IAAI,SAAS;IACnFE,YAAY,EAAET,OAAO,EAAEU,SAAS,IAAIV,OAAO,EAAES,YAAY,IAAI,GAAG;IAChEE,WAAW,EAAEX,OAAO,EAAEY,QAAQ,IAAIZ,OAAO,EAAEW,WAAW,IAAI;EAC5D,CAAC;AACH;AAOA,OAAO,MAAME,MAAM,GAAG;EACpBC,YAAYA,CAAA,EAAoB;IAC9B,OAAOhB,eAAe,CAAC,CAAC,CAACgB,YAAY,CAAC,CAAC;EACzC,CAAC;EAED;AACF;AACA;AACA;EACEC,kBAAkBA,CAChBC,eAAuB,EACvBhB,OAAmC,EACX;IACxB,MAAMiB,MAAM,GAAGnB,eAAe,CAAC,CAAC;IAChC,MAAMoB,aAAa,GAAGnB,qBAAqB,CAACC,OAAO,CAAC;IAEpD,IAAIA,OAAO,EAAEmB,eAAe,EAAE;MAC5B,OAAOF,MAAM,CAACG,YAAY,CAACJ,eAAe,EAAEE,aAAa,CAAC;IAC5D;IAEA,IAAI,OAAOD,MAAM,CAACF,kBAAkB,KAAK,UAAU,EAAE;MACnD,OAAOE,MAAM,CAACF,kBAAkB,CAACC,eAAe,EAAEE,aAAa,CAAC;IAClE;IAEA,OAAOD,MAAM,CAACG,YAAY,CAACJ,eAAe,EAAEE,aAAa,CAAC,CAACG,IAAI,CAAC,MAAMC,SAAS,CAAC;EAClF;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["getNativeModule","toNativeCryptoOptions","Crypto","getPublicKey","establishSharedKey","serverPublicKey","options","native","nativeOptions","returnSharedKey","getSharedKey","then","undefined"],"sourceRoot":"../../../src","sources":["crypto/index.ts"],"mappings":";;AAAA,SAASA,eAAe,QAAQ,qBAAkB;AAClD,SACEC,qBAAqB,QAEhB,4BAAyB;AAOhC,OAAO,MAAMC,MAAM,GAAG;EACpBC,YAAYA,CAAA,EAAoB;IAC9B,OAAOH,eAAe,CAAC,CAAC,CAACG,YAAY,CAAC,CAAC;EACzC,CAAC;EAED;AACF;AACA;AACA;EACEC,kBAAkBA,CAChBC,eAAuB,EACvBC,OAAmC,EACX;IACxB,MAAMC,MAAM,GAAGP,eAAe,CAAC,CAAC;IAChC,MAAMQ,aAAa,GAAGP,qBAAqB,CAACK,OAAO,CAAC;IAEpD,IAAIA,OAAO,EAAEG,eAAe,EAAE;MAC5B,OAAOF,MAAM,CAACG,YAAY,CAACL,eAAe,EAAEG,aAAa,CAAC;IAC5D;IAEA,IAAI,OAAOD,MAAM,CAACH,kBAAkB,KAAK,UAAU,EAAE;MACnD,OAAOG,MAAM,CAACH,kBAAkB,CAACC,eAAe,EAAEG,aAAa,CAAC;IAClE;IAEA,OAAOD,MAAM,CAACG,YAAY,CAACL,eAAe,EAAEG,aAAa,CAAC,CAACG,IAAI,CAAC,MAAMC,SAAS,CAAC;EAClF;AACF,CAAC","ignoreList":[]}
@@ -2,15 +2,24 @@
2
2
 
3
3
  /** Shared crypto option types used by legacy exports and the Crypto namespace. */
4
4
 
5
+ function requireCryptoOption(value, key) {
6
+ if (value === undefined || value === null || value === '') {
7
+ throw new Error(`Missing required crypto option: ${key}`);
8
+ }
9
+ return value;
10
+ }
5
11
  export function toNativeCryptoOptions(options) {
12
+ if (!options) {
13
+ throw new Error('Crypto options are required');
14
+ }
6
15
  return {
7
- keyAgreementAlgorithm: options?.keyAgreementAlgorithm ?? 'X25519',
8
- keyFactoryAlgorithm: options?.keyType ?? options?.keyFactoryAlgorithm ?? 'OKP',
9
- encryptionKeyAlgorithm: options?.encryptionKeyAlgorithm ?? 'AES-256',
10
- hmacKeyAlgorithm: options?.hmacAlgorithm ?? options?.hmacKeyAlgorithm ?? 'HMAC-SHA-512',
11
- cipherTransformation: options?.cipher ?? options?.cipherTransformation ?? 'AES-GCM',
12
- gcmTagLength: options?.tagLength ?? options?.gcmTagLength ?? 128,
13
- gcmIvLength: options?.ivLength ?? options?.gcmIvLength ?? 12
16
+ keyAgreementAlgorithm: requireCryptoOption(options.keyAgreementAlgorithm, 'keyAgreementAlgorithm'),
17
+ keyFactoryAlgorithm: requireCryptoOption(options.keyType ?? options.keyFactoryAlgorithm, 'keyFactoryAlgorithm'),
18
+ encryptionKeyAlgorithm: requireCryptoOption(options.encryptionKeyAlgorithm, 'encryptionKeyAlgorithm'),
19
+ hmacKeyAlgorithm: requireCryptoOption(options.hmacAlgorithm ?? options.hmacKeyAlgorithm, 'hmacKeyAlgorithm'),
20
+ cipherTransformation: requireCryptoOption(options.cipher ?? options.cipherTransformation, 'cipherTransformation'),
21
+ gcmTagLength: requireCryptoOption(options.tagLength ?? options.gcmTagLength, 'gcmTagLength'),
22
+ gcmIvLength: requireCryptoOption(options.ivLength ?? options.gcmIvLength, 'gcmIvLength')
14
23
  };
15
24
  }
16
25
  //# sourceMappingURL=cryptoOptions.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["toNativeCryptoOptions","options","keyAgreementAlgorithm","keyFactoryAlgorithm","keyType","encryptionKeyAlgorithm","hmacKeyAlgorithm","hmacAlgorithm","cipherTransformation","cipher","gcmTagLength","tagLength","gcmIvLength","ivLength"],"sourceRoot":"../../../src","sources":["legacy/cryptoOptions.ts"],"mappings":";;AAAA;;AAsCA,OAAO,SAASA,qBAAqBA,CAACC,OAA8B,EAAE;EACpE,OAAO;IACLC,qBAAqB,EAAED,OAAO,EAAEC,qBAAqB,IAAI,QAAQ;IACjEC,mBAAmB,EAAEF,OAAO,EAAEG,OAAO,IAAIH,OAAO,EAAEE,mBAAmB,IAAI,KAAK;IAC9EE,sBAAsB,EAAEJ,OAAO,EAAEI,sBAAsB,IAAI,SAAS;IACpEC,gBAAgB,EAAEL,OAAO,EAAEM,aAAa,IAAIN,OAAO,EAAEK,gBAAgB,IAAI,cAAc;IACvFE,oBAAoB,EAAEP,OAAO,EAAEQ,MAAM,IAAIR,OAAO,EAAEO,oBAAoB,IAAI,SAAS;IACnFE,YAAY,EAAET,OAAO,EAAEU,SAAS,IAAIV,OAAO,EAAES,YAAY,IAAI,GAAG;IAChEE,WAAW,EAAEX,OAAO,EAAEY,QAAQ,IAAIZ,OAAO,EAAEW,WAAW,IAAI;EAC5D,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"names":["requireCryptoOption","value","key","undefined","Error","toNativeCryptoOptions","options","keyAgreementAlgorithm","keyFactoryAlgorithm","keyType","encryptionKeyAlgorithm","hmacKeyAlgorithm","hmacAlgorithm","cipherTransformation","cipher","gcmTagLength","tagLength","gcmIvLength","ivLength"],"sourceRoot":"../../../src","sources":["legacy/cryptoOptions.ts"],"mappings":";;AAAA;;AAsCA,SAASA,mBAAmBA,CAC1BC,KAA2B,EAC3BC,GAAW,EACR;EACH,IAAID,KAAK,KAAKE,SAAS,IAAIF,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAK,EAAE,EAAE;IACzD,MAAM,IAAIG,KAAK,CAAC,mCAAmCF,GAAG,EAAE,CAAC;EAC3D;EACA,OAAOD,KAAK;AACd;AAEA,OAAO,SAASI,qBAAqBA,CAACC,OAA8B,EAAE;EACpE,IAAI,CAACA,OAAO,EAAE;IACZ,MAAM,IAAIF,KAAK,CAAC,6BAA6B,CAAC;EAChD;EAEA,OAAO;IACLG,qBAAqB,EAAEP,mBAAmB,CACxCM,OAAO,CAACC,qBAAqB,EAC7B,uBACF,CAAC;IACDC,mBAAmB,EAAER,mBAAmB,CACtCM,OAAO,CAACG,OAAO,IAAIH,OAAO,CAACE,mBAAmB,EAC9C,qBACF,CAAC;IACDE,sBAAsB,EAAEV,mBAAmB,CACzCM,OAAO,CAACI,sBAAsB,EAC9B,wBACF,CAAC;IACDC,gBAAgB,EAAEX,mBAAmB,CACnCM,OAAO,CAACM,aAAa,IAAIN,OAAO,CAACK,gBAAgB,EACjD,kBACF,CAAC;IACDE,oBAAoB,EAAEb,mBAAmB,CACvCM,OAAO,CAACQ,MAAM,IAAIR,OAAO,CAACO,oBAAoB,EAC9C,sBACF,CAAC;IACDE,YAAY,EAAEf,mBAAmB,CAC/BM,OAAO,CAACU,SAAS,IAAIV,OAAO,CAACS,YAAY,EACzC,cACF,CAAC;IACDE,WAAW,EAAEjB,mBAAmB,CAC9BM,OAAO,CAACY,QAAQ,IAAIZ,OAAO,CAACW,WAAW,EACvC,aACF;EACF,CAAC;AACH","ignoreList":[]}
@@ -1,4 +1,4 @@
1
- import type { CryptoOptions } from '../legacy/cryptoOptions';
1
+ import { type CryptoOptions } from '../legacy/cryptoOptions';
2
2
  export interface EstablishSharedKeyOptions extends CryptoOptions {
3
3
  /** @deprecated Prefer native-only flow; set true only for legacy compatibility. */
4
4
  returnSharedKey?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/crypto/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAc7D,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC9D,mFAAmF;IACnF,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,MAAM;oBACD,OAAO,CAAC,MAAM,CAAC;IAI/B;;;OAGG;wCAEgB,MAAM,YACb,yBAAyB,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAc1B,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/crypto/index.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC9D,mFAAmF;IACnF,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,MAAM;oBACD,OAAO,CAAC,MAAM,CAAC;IAI/B;;;OAGG;wCAEgB,MAAM,YACb,yBAAyB,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAc1B,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
@@ -5,9 +5,9 @@ export type EncryptionKeyAlgorithm = 'AES-256' | 'AES' | (string & {});
5
5
  export type HmacAlgorithm = 'HMAC-SHA-256' | 'HMAC-SHA-384' | 'HMAC-SHA-512' | 'HmacSHA256' | 'HmacSHA384' | 'HmacSHA512' | (string & {});
6
6
  export type CipherAlgorithm = 'AES-GCM' | 'AES/GCM/NoPadding' | (string & {});
7
7
  export interface CryptoOptions {
8
- keyAgreementAlgorithm?: KeyAgreementAlgorithm;
8
+ keyAgreementAlgorithm: KeyAgreementAlgorithm;
9
+ encryptionKeyAlgorithm: EncryptionKeyAlgorithm;
9
10
  keyType?: KeyType;
10
- encryptionKeyAlgorithm?: EncryptionKeyAlgorithm;
11
11
  hmacAlgorithm?: HmacAlgorithm;
12
12
  cipher?: CipherAlgorithm;
13
13
  tagLength?: number;
@@ -24,11 +24,11 @@ export interface CryptoOptions {
24
24
  gcmIvLength?: number;
25
25
  }
26
26
  export declare function toNativeCryptoOptions(options?: CryptoOptions | null): {
27
- keyAgreementAlgorithm: KeyAgreementAlgorithm;
28
- keyFactoryAlgorithm: KeyType;
29
- encryptionKeyAlgorithm: EncryptionKeyAlgorithm;
30
- hmacKeyAlgorithm: HmacAlgorithm;
31
- cipherTransformation: CipherAlgorithm;
27
+ keyAgreementAlgorithm: "X25519" | (string & {}) | "ECDH";
28
+ keyFactoryAlgorithm: (string & {}) | "OKP" | "EC";
29
+ encryptionKeyAlgorithm: (string & {}) | "AES-256" | "AES";
30
+ hmacKeyAlgorithm: (string & {}) | "HMAC-SHA-256" | "HMAC-SHA-384" | "HMAC-SHA-512" | "HmacSHA256" | "HmacSHA384" | "HmacSHA512";
31
+ cipherTransformation: (string & {}) | "AES-GCM" | "AES/GCM/NoPadding";
32
32
  gcmTagLength: number;
33
33
  gcmIvLength: number;
34
34
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cryptoOptions.d.ts","sourceRoot":"","sources":["../../../../../src/legacy/cryptoOptions.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEtE,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEnD,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEvE,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,cAAc,GACd,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,mBAAmB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,aAAa,CAAC;IACjC,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,eAAe,CAAC;IACvC,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI;;;;;;;;EAUnE"}
1
+ {"version":3,"file":"cryptoOptions.d.ts","sourceRoot":"","sources":["../../../../../src/legacy/cryptoOptions.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEtE,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEnD,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEvE,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,cAAc,GACd,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,mBAAmB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,aAAa,CAAC;IACjC,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,eAAe,CAAC;IACvC,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAYD,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI;;;;;;;;EAmCnE"}
@@ -1,4 +1,4 @@
1
- import type { CryptoOptions } from '../legacy/cryptoOptions';
1
+ import { type CryptoOptions } from '../legacy/cryptoOptions';
2
2
  export interface EstablishSharedKeyOptions extends CryptoOptions {
3
3
  /** @deprecated Prefer native-only flow; set true only for legacy compatibility. */
4
4
  returnSharedKey?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/crypto/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAc7D,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC9D,mFAAmF;IACnF,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,MAAM;oBACD,OAAO,CAAC,MAAM,CAAC;IAI/B;;;OAGG;wCAEgB,MAAM,YACb,yBAAyB,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAc1B,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/crypto/index.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC9D,mFAAmF;IACnF,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,MAAM;oBACD,OAAO,CAAC,MAAM,CAAC;IAI/B;;;OAGG;wCAEgB,MAAM,YACb,yBAAyB,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAc1B,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
@@ -5,9 +5,9 @@ export type EncryptionKeyAlgorithm = 'AES-256' | 'AES' | (string & {});
5
5
  export type HmacAlgorithm = 'HMAC-SHA-256' | 'HMAC-SHA-384' | 'HMAC-SHA-512' | 'HmacSHA256' | 'HmacSHA384' | 'HmacSHA512' | (string & {});
6
6
  export type CipherAlgorithm = 'AES-GCM' | 'AES/GCM/NoPadding' | (string & {});
7
7
  export interface CryptoOptions {
8
- keyAgreementAlgorithm?: KeyAgreementAlgorithm;
8
+ keyAgreementAlgorithm: KeyAgreementAlgorithm;
9
+ encryptionKeyAlgorithm: EncryptionKeyAlgorithm;
9
10
  keyType?: KeyType;
10
- encryptionKeyAlgorithm?: EncryptionKeyAlgorithm;
11
11
  hmacAlgorithm?: HmacAlgorithm;
12
12
  cipher?: CipherAlgorithm;
13
13
  tagLength?: number;
@@ -24,11 +24,11 @@ export interface CryptoOptions {
24
24
  gcmIvLength?: number;
25
25
  }
26
26
  export declare function toNativeCryptoOptions(options?: CryptoOptions | null): {
27
- keyAgreementAlgorithm: KeyAgreementAlgorithm;
28
- keyFactoryAlgorithm: KeyType;
29
- encryptionKeyAlgorithm: EncryptionKeyAlgorithm;
30
- hmacKeyAlgorithm: HmacAlgorithm;
31
- cipherTransformation: CipherAlgorithm;
27
+ keyAgreementAlgorithm: "X25519" | (string & {}) | "ECDH";
28
+ keyFactoryAlgorithm: (string & {}) | "OKP" | "EC";
29
+ encryptionKeyAlgorithm: (string & {}) | "AES-256" | "AES";
30
+ hmacKeyAlgorithm: (string & {}) | "HMAC-SHA-256" | "HMAC-SHA-384" | "HMAC-SHA-512" | "HmacSHA256" | "HmacSHA384" | "HmacSHA512";
31
+ cipherTransformation: (string & {}) | "AES-GCM" | "AES/GCM/NoPadding";
32
32
  gcmTagLength: number;
33
33
  gcmIvLength: number;
34
34
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cryptoOptions.d.ts","sourceRoot":"","sources":["../../../../../src/legacy/cryptoOptions.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEtE,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEnD,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEvE,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,cAAc,GACd,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,mBAAmB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,aAAa,CAAC;IACjC,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,eAAe,CAAC;IACvC,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI;;;;;;;;EAUnE"}
1
+ {"version":3,"file":"cryptoOptions.d.ts","sourceRoot":"","sources":["../../../../../src/legacy/cryptoOptions.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEtE,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEnD,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEvE,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,cAAc,GACd,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,mBAAmB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,aAAa,CAAC;IACjC,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,eAAe,CAAC;IACvC,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAYD,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI;;;;;;;;EAmCnE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-security-suite",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.2",
4
4
  "description": "Comprehensive security suite for React Native apps - Root/Jailbreak detection, SSL pinning, encryption, secure storage, screenshot protection, and network monitoring",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/commonjs/index.js",
@@ -1,17 +1,8 @@
1
1
  import { getNativeModule } from '../native/bridge';
2
- import type { CryptoOptions } from '../legacy/cryptoOptions';
3
-
4
- function toNativeCryptoOptions(options?: CryptoOptions | null) {
5
- return {
6
- keyAgreementAlgorithm: options?.keyAgreementAlgorithm ?? 'X25519',
7
- keyFactoryAlgorithm: options?.keyType ?? options?.keyFactoryAlgorithm ?? 'OKP',
8
- encryptionKeyAlgorithm: options?.encryptionKeyAlgorithm ?? 'AES-256',
9
- hmacKeyAlgorithm: options?.hmacAlgorithm ?? options?.hmacKeyAlgorithm ?? 'HMAC-SHA-512',
10
- cipherTransformation: options?.cipher ?? options?.cipherTransformation ?? 'AES-GCM',
11
- gcmTagLength: options?.tagLength ?? options?.gcmTagLength ?? 128,
12
- gcmIvLength: options?.ivLength ?? options?.gcmIvLength ?? 12,
13
- };
14
- }
2
+ import {
3
+ toNativeCryptoOptions,
4
+ type CryptoOptions,
5
+ } from '../legacy/cryptoOptions';
15
6
 
16
7
  export interface EstablishSharedKeyOptions extends CryptoOptions {
17
8
  /** @deprecated Prefer native-only flow; set true only for legacy compatibility. */
@@ -17,9 +17,9 @@ export type HmacAlgorithm =
17
17
  export type CipherAlgorithm = 'AES-GCM' | 'AES/GCM/NoPadding' | (string & {});
18
18
 
19
19
  export interface CryptoOptions {
20
- keyAgreementAlgorithm?: KeyAgreementAlgorithm;
20
+ keyAgreementAlgorithm: KeyAgreementAlgorithm;
21
+ encryptionKeyAlgorithm: EncryptionKeyAlgorithm;
21
22
  keyType?: KeyType;
22
- encryptionKeyAlgorithm?: EncryptionKeyAlgorithm;
23
23
  hmacAlgorithm?: HmacAlgorithm;
24
24
  cipher?: CipherAlgorithm;
25
25
  tagLength?: number;
@@ -36,14 +36,49 @@ export interface CryptoOptions {
36
36
  gcmIvLength?: number;
37
37
  }
38
38
 
39
+ function requireCryptoOption<T>(
40
+ value: T | undefined | null,
41
+ key: string
42
+ ): T {
43
+ if (value === undefined || value === null || value === '') {
44
+ throw new Error(`Missing required crypto option: ${key}`);
45
+ }
46
+ return value;
47
+ }
48
+
39
49
  export function toNativeCryptoOptions(options?: CryptoOptions | null) {
50
+ if (!options) {
51
+ throw new Error('Crypto options are required');
52
+ }
53
+
40
54
  return {
41
- keyAgreementAlgorithm: options?.keyAgreementAlgorithm ?? 'X25519',
42
- keyFactoryAlgorithm: options?.keyType ?? options?.keyFactoryAlgorithm ?? 'OKP',
43
- encryptionKeyAlgorithm: options?.encryptionKeyAlgorithm ?? 'AES-256',
44
- hmacKeyAlgorithm: options?.hmacAlgorithm ?? options?.hmacKeyAlgorithm ?? 'HMAC-SHA-512',
45
- cipherTransformation: options?.cipher ?? options?.cipherTransformation ?? 'AES-GCM',
46
- gcmTagLength: options?.tagLength ?? options?.gcmTagLength ?? 128,
47
- gcmIvLength: options?.ivLength ?? options?.gcmIvLength ?? 12,
55
+ keyAgreementAlgorithm: requireCryptoOption(
56
+ options.keyAgreementAlgorithm,
57
+ 'keyAgreementAlgorithm'
58
+ ),
59
+ keyFactoryAlgorithm: requireCryptoOption(
60
+ options.keyType ?? options.keyFactoryAlgorithm,
61
+ 'keyFactoryAlgorithm'
62
+ ),
63
+ encryptionKeyAlgorithm: requireCryptoOption(
64
+ options.encryptionKeyAlgorithm,
65
+ 'encryptionKeyAlgorithm'
66
+ ),
67
+ hmacKeyAlgorithm: requireCryptoOption(
68
+ options.hmacAlgorithm ?? options.hmacKeyAlgorithm,
69
+ 'hmacKeyAlgorithm'
70
+ ),
71
+ cipherTransformation: requireCryptoOption(
72
+ options.cipher ?? options.cipherTransformation,
73
+ 'cipherTransformation'
74
+ ),
75
+ gcmTagLength: requireCryptoOption(
76
+ options.tagLength ?? options.gcmTagLength,
77
+ 'gcmTagLength'
78
+ ),
79
+ gcmIvLength: requireCryptoOption(
80
+ options.ivLength ?? options.gcmIvLength,
81
+ 'gcmIvLength'
82
+ ),
48
83
  };
49
84
  }