expo-device-crypto 0.3.2 → 0.4.0

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
@@ -33,6 +33,18 @@ If you want to allow Face ID on iOS, add this to your app config:
33
33
  **Curve:** P-256 / secp256r1. </br>
34
34
  **Hash:** SHA-256. </br>
35
35
 
36
+ - `RSA_SHA256`
37
+
38
+ **Key size:** 2048 bits. </br>
39
+ **Padding:** PKCS#1 v1.5. </br>
40
+ **Hash:** SHA-256. </br>
41
+
42
+ - `RSA_SHA256_PSS`
43
+
44
+ **Key size:** 2048 bits. </br>
45
+ **Padding:** RSA-PSS (MGF1). </br>
46
+ **Hash:** SHA-256. </br>
47
+
36
48
  ### šŸ” Encryption Algorithms
37
49
 
38
50
  - `RSA_2048_PKCS1`
@@ -1,7 +1,7 @@
1
1
  apply plugin: 'com.android.library'
2
2
 
3
3
  group = 'expo.modules.devicecrypto'
4
- version = '0.3.2'
4
+ version = '0.4.0'
5
5
 
6
6
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
7
7
  apply from: expoModulesCorePlugin
@@ -35,7 +35,7 @@ android {
35
35
  namespace "expo.modules.devicecrypto"
36
36
  defaultConfig {
37
37
  versionCode 1
38
- versionName "0.3.2"
38
+ versionName "0.4.0"
39
39
  }
40
40
  lintOptions {
41
41
  abortOnError false
@@ -10,6 +10,8 @@ import android.security.keystore.KeyProperties.DIGEST_SHA1
10
10
  import android.security.keystore.KeyProperties.DIGEST_SHA256
11
11
  import android.security.keystore.KeyProperties.ENCRYPTION_PADDING_RSA_OAEP
12
12
  import android.security.keystore.KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1
13
+ import android.security.keystore.KeyProperties.SIGNATURE_PADDING_RSA_PKCS1
14
+ import android.security.keystore.KeyProperties.SIGNATURE_PADDING_RSA_PSS
13
15
  import android.security.keystore.KeyProperties.KEY_ALGORITHM_EC
14
16
  import android.security.keystore.KeyProperties.KEY_ALGORITHM_RSA
15
17
  import android.security.keystore.KeyProperties.PURPOSE_DECRYPT
@@ -65,6 +67,13 @@ enum class AlgorithmType {
65
67
  RSA_2048_PKCS1,
66
68
  RSA_2048_OAEP_SHA1,
67
69
  ECIES_P256_AES256_GCM,
70
+ RSA_SHA256,
71
+ RSA_SHA256_PSS
72
+ }
73
+
74
+ enum class Purpose {
75
+ ENCRYPT,
76
+ SIGN,
68
77
  }
69
78
 
70
79
  class DeviceCryptoModule : Module() {
@@ -74,6 +83,8 @@ class DeviceCryptoModule : Module() {
74
83
  AlgorithmType.RSA_2048_PKCS1 -> "RSA/ECB/PKCS1Padding"
75
84
  AlgorithmType.RSA_2048_OAEP_SHA1 -> "RSA/ECB/OAEPwithSHA-1AndMGF1Padding"
76
85
  AlgorithmType.ECIES_P256_AES256_GCM -> "AES/GCM/NoPadding"
86
+ AlgorithmType.RSA_SHA256 -> "SHA256withRSA"
87
+ AlgorithmType.RSA_SHA256_PSS -> "SHA256withRSA/PSS"
77
88
  else -> throw Exception("INVALID_ALGORITHM_TYPE")
78
89
  }
79
90
  }
@@ -183,7 +194,8 @@ class DeviceCryptoModule : Module() {
183
194
  private fun buildRSA(
184
195
  alias: String,
185
196
  digest: String?,
186
- padding: String,
197
+ purpose: Purpose,
198
+ padding: String?,
187
199
  reqAuth: Boolean,
188
200
  strongBox: Boolean): KeyPairGenerator {
189
201
  val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
@@ -193,12 +205,20 @@ class DeviceCryptoModule : Module() {
193
205
 
194
206
  val parameterSpec: KeyGenParameterSpec = KeyGenParameterSpec.Builder(
195
207
  alias,
196
- PURPOSE_ENCRYPT or PURPOSE_DECRYPT
208
+ when (purpose) {
209
+ Purpose.ENCRYPT -> PURPOSE_ENCRYPT or PURPOSE_DECRYPT
210
+ Purpose.SIGN -> PURPOSE_SIGN or PURPOSE_VERIFY
211
+ }
197
212
  ).run {
198
213
  if (digest != null) {
199
214
  setDigests(digest)
200
215
  }
201
- setEncryptionPaddings(padding)
216
+ if (padding != null && purpose == Purpose.ENCRYPT) {
217
+ setEncryptionPaddings(padding)
218
+ }
219
+ if (padding != null && purpose == Purpose.SIGN) {
220
+ setSignaturePaddings(padding)
221
+ }
202
222
  setIsStrongBoxBacked(strongBox)
203
223
  setUserAuthenticationRequired(reqAuth)
204
224
  if (reqAuth) {
@@ -323,10 +343,50 @@ class DeviceCryptoModule : Module() {
323
343
  val strongBox = preferStrongBox && isStrongBoxAvailable()
324
344
 
325
345
  val kpg = when (algoType) {
326
- AlgorithmType.ECDSA_SECP256R1_SHA256 -> buildECDSA(alias, DIGEST_SHA256, reqAuth, strongBox)
327
- AlgorithmType.RSA_2048_PKCS1 -> buildRSA(alias, null, ENCRYPTION_PADDING_RSA_PKCS1, reqAuth, strongBox)
328
- AlgorithmType.RSA_2048_OAEP_SHA1 -> buildRSA(alias, DIGEST_SHA1, ENCRYPTION_PADDING_RSA_OAEP, reqAuth, strongBox)
329
- AlgorithmType.ECIES_P256_AES256_GCM -> buildECIES(alias, null, reqAuth, strongBox)
346
+ AlgorithmType.ECDSA_SECP256R1_SHA256 -> buildECDSA(
347
+ alias = alias,
348
+ digest = DIGEST_SHA256,
349
+ reqAuth = reqAuth,
350
+ strongBox = strongBox
351
+ )
352
+ AlgorithmType.RSA_2048_PKCS1 -> buildRSA(
353
+ alias = alias,
354
+ digest = null,
355
+ purpose = Purpose.ENCRYPT,
356
+ padding = ENCRYPTION_PADDING_RSA_PKCS1,
357
+ reqAuth = reqAuth,
358
+ strongBox = strongBox
359
+ )
360
+ AlgorithmType.RSA_2048_OAEP_SHA1 -> buildRSA(
361
+ alias = alias,
362
+ digest = DIGEST_SHA1,
363
+ purpose = Purpose.ENCRYPT,
364
+ padding = ENCRYPTION_PADDING_RSA_OAEP,
365
+ reqAuth = reqAuth,
366
+ strongBox = strongBox
367
+ )
368
+ AlgorithmType.ECIES_P256_AES256_GCM -> buildECIES(
369
+ alias = alias,
370
+ digest = null,
371
+ reqAuth = reqAuth,
372
+ strongBox = strongBox
373
+ )
374
+ AlgorithmType.RSA_SHA256 -> buildRSA(
375
+ alias = alias,
376
+ digest = DIGEST_SHA256,
377
+ purpose = Purpose.SIGN,
378
+ padding = SIGNATURE_PADDING_RSA_PKCS1,
379
+ reqAuth = reqAuth,
380
+ strongBox = strongBox
381
+ )
382
+ AlgorithmType.RSA_SHA256_PSS -> buildRSA(
383
+ alias = alias,
384
+ digest = DIGEST_SHA256,
385
+ purpose = Purpose.SIGN,
386
+ padding = SIGNATURE_PADDING_RSA_PSS,
387
+ reqAuth = reqAuth,
388
+ strongBox = strongBox
389
+ )
330
390
  else -> throw Exception("INVALID_ALGORITHM_TYPE")
331
391
  }
332
392
 
@@ -13,7 +13,9 @@ export declare enum AuthMethod {
13
13
  PASSCODE_OR_BIOMETRIC = "PASSCODE_OR_BIOMETRIC"
14
14
  }
15
15
  export declare enum SigningAlgorithm {
16
- ECDSA_SECP256R1_SHA256 = "ECDSA_SECP256R1_SHA256"
16
+ ECDSA_SECP256R1_SHA256 = "ECDSA_SECP256R1_SHA256",
17
+ RSA_SHA256 = "RSA_SHA256",
18
+ RSA_SHA256_PSS = "RSA_SHA256_PSS"
17
19
  }
18
20
  type EciesAlgorithm = "ECIES_P256_AES256_GCM";
19
21
  type RsaAlgorithm = "RSA_2048_PKCS1" | "RSA_2048_OAEP_SHA1";
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceCrypto.types.d.ts","sourceRoot":"","sources":["../src/DeviceCrypto.types.ts"],"names":[],"mappings":"AAAA,oBAAY,qBAAqB;IAC/B,kBAAkB,uBAAuB;IACzC,uBAAuB,4BAA4B;IACnD,aAAa,kBAAkB;CAChC;AAED,oBAAY,eAAe;IACzB,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;CAC5B;AAED,oBAAY,UAAU;IACpB,QAAQ,aAAa;IACrB,qBAAqB,0BAA0B;CAChD;AAED,oBAAY,gBAAgB;IAC1B,sBAAsB,2BAA2B;CAClD;AAED,KAAK,cAAc,GAAG,uBAAuB,CAAC;AAC9C,KAAK,YAAY,GAAG,gBAAgB,GAAG,oBAAoB,CAAC;AAC5D,oBAAY,mBAAmB;IAC7B,cAAc,mBAAmB;IACjC,kBAAkB,uBAAuB;IACzC,qBAAqB,0BAA0B;CAChD;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,aAAa,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;IACtD;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAA;AAED,KAAK,eAAe,GAAG;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB;;OAEG;IACH,aAAa,EAAE,gBAAgB,CAAC;CACjC,CAAC;AACF,KAAK,iBAAiB,GAAG,kBAAkB,CAAC;AAE5C,KAAK,wBAAwB,GAAG;IAC9B;;OAEG;IACH,aAAa,EAAE,YAAY,CAAC;CAC7B,CAAC;AACF,KAAK,wBAAwB,GAAG,wBAAwB,CAAC;AAEzD,KAAK,0BAA0B,GAAG;IAChC;;OAEG;IACH,aAAa,EAAE,cAAc,CAAC;IAC9B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AACF,KAAK,0BAA0B,GAAG,0BAA0B,CAAC;AAE7D,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAC/D,MAAM,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAE9C,MAAM,MAAM,cAAc,GACtB,CAAC,eAAe,GAAG,0BAA0B,CAAC,GAC9C,CAAC,eAAe,GAAG,wBAAwB,CAAC,CAAC;AACjD,MAAM,MAAM,cAAc,GACtB,CAAC,eAAe,GAAG,0BAA0B,CAAC,GAC9C,wBAAwB,CAAC;AAE7B,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC3B"}
1
+ {"version":3,"file":"DeviceCrypto.types.d.ts","sourceRoot":"","sources":["../src/DeviceCrypto.types.ts"],"names":[],"mappings":"AAAA,oBAAY,qBAAqB;IAC/B,kBAAkB,uBAAuB;IACzC,uBAAuB,4BAA4B;IACnD,aAAa,kBAAkB;CAChC;AAED,oBAAY,eAAe;IACzB,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;CAC5B;AAED,oBAAY,UAAU;IACpB,QAAQ,aAAa;IACrB,qBAAqB,0BAA0B;CAChD;AAED,oBAAY,gBAAgB;IAC1B,sBAAsB,2BAA2B;IACjD,UAAU,eAAe;IACzB,cAAc,mBAAmB;CAClC;AAED,KAAK,cAAc,GAAG,uBAAuB,CAAC;AAC9C,KAAK,YAAY,GAAG,gBAAgB,GAAG,oBAAoB,CAAC;AAC5D,oBAAY,mBAAmB;IAC7B,cAAc,mBAAmB;IACjC,kBAAkB,uBAAuB;IACzC,qBAAqB,0BAA0B;CAChD;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,aAAa,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;IACtD;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAA;AAED,KAAK,eAAe,GAAG;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB;;OAEG;IACH,aAAa,EAAE,gBAAgB,CAAC;CACjC,CAAC;AACF,KAAK,iBAAiB,GAAG,kBAAkB,CAAC;AAE5C,KAAK,wBAAwB,GAAG;IAC9B;;OAEG;IACH,aAAa,EAAE,YAAY,CAAC;CAC7B,CAAC;AACF,KAAK,wBAAwB,GAAG,wBAAwB,CAAC;AAEzD,KAAK,0BAA0B,GAAG;IAChC;;OAEG;IACH,aAAa,EAAE,cAAc,CAAC;IAC9B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AACF,KAAK,0BAA0B,GAAG,0BAA0B,CAAC;AAE7D,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAC/D,MAAM,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAE9C,MAAM,MAAM,cAAc,GACtB,CAAC,eAAe,GAAG,0BAA0B,CAAC,GAC9C,CAAC,eAAe,GAAG,wBAAwB,CAAC,CAAC;AACjD,MAAM,MAAM,cAAc,GACtB,CAAC,eAAe,GAAG,0BAA0B,CAAC,GAC9C,wBAAwB,CAAC;AAE7B,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC3B"}
@@ -18,6 +18,8 @@ export var AuthMethod;
18
18
  export var SigningAlgorithm;
19
19
  (function (SigningAlgorithm) {
20
20
  SigningAlgorithm["ECDSA_SECP256R1_SHA256"] = "ECDSA_SECP256R1_SHA256";
21
+ SigningAlgorithm["RSA_SHA256"] = "RSA_SHA256";
22
+ SigningAlgorithm["RSA_SHA256_PSS"] = "RSA_SHA256_PSS";
21
23
  })(SigningAlgorithm || (SigningAlgorithm = {}));
22
24
  export var EncryptionAlgorithm;
23
25
  (function (EncryptionAlgorithm) {
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceCrypto.types.js","sourceRoot":"","sources":["../src/DeviceCrypto.types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC/B,kEAAyC,CAAA;IACzC,4EAAmD,CAAA;IACnD,wDAA+B,CAAA;AACjC,CAAC,EAJW,qBAAqB,KAArB,qBAAqB,QAIhC;AAED,MAAM,CAAN,IAAY,eAIX;AAJD,WAAY,eAAe;IACzB,0CAAuB,CAAA;IACvB,8CAA2B,CAAA;IAC3B,8CAA2B,CAAA;AAC7B,CAAC,EAJW,eAAe,KAAf,eAAe,QAI1B;AAED,MAAM,CAAN,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,mCAAqB,CAAA;IACrB,6DAA+C,CAAA;AACjD,CAAC,EAHW,UAAU,KAAV,UAAU,QAGrB;AAED,MAAM,CAAN,IAAY,gBAEX;AAFD,WAAY,gBAAgB;IAC1B,qEAAiD,CAAA;AACnD,CAAC,EAFW,gBAAgB,KAAhB,gBAAgB,QAE3B;AAID,MAAM,CAAN,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,wDAAiC,CAAA;IACjC,gEAAyC,CAAA;IACzC,sEAA+C,CAAA;AACjD,CAAC,EAJW,mBAAmB,KAAnB,mBAAmB,QAI9B","sourcesContent":["export enum GenerateKeyPairResult {\n KEY_PAIR_GENERATED = \"KEY_PAIR_GENERATED\",\n KEY_PAIR_ALREADY_EXISTS = \"KEY_PAIR_ALREADY_EXISTS\",\n NOT_AVAILABLE = \"NOT_AVAILABLE\",\n}\n\nexport enum AuthCheckResult {\n AVAILABLE = \"AVAILABLE\",\n NO_HARDWARE = \"NO_HARDWARE\",\n UNAVAILABLE = \"UNAVAILABLE\",\n}\n\nexport enum AuthMethod {\n PASSCODE = \"PASSCODE\",\n PASSCODE_OR_BIOMETRIC = \"PASSCODE_OR_BIOMETRIC\",\n}\n\nexport enum SigningAlgorithm {\n ECDSA_SECP256R1_SHA256 = \"ECDSA_SECP256R1_SHA256\",\n}\n\ntype EciesAlgorithm = \"ECIES_P256_AES256_GCM\";\ntype RsaAlgorithm = \"RSA_2048_PKCS1\" | \"RSA_2048_OAEP_SHA1\";\nexport enum EncryptionAlgorithm {\n RSA_2048_PKCS1 = \"RSA_2048_PKCS1\",\n RSA_2048_OAEP_SHA1 = \"RSA_2048_OAEP_SHA1\",\n ECIES_P256_AES256_GCM = \"ECIES_P256_AES256_GCM\",\n}\n\nexport type GenerateKeyPairOptions = {\n /**\n * The algorithm type of the key to generate.\n */\n algorithmType: SigningAlgorithm | EncryptionAlgorithm;\n /**\n * Whether to require authentication to sign.\n * Setting this to true will prompt biometric or passcode authentication before signing.\n *\n * Please check the *`isAuthCheckAvailable`* function to see if authentication is available.\n * If authentication is not available, generating a key pair will throw an error.\n * @default false\n */\n requireAuthentication?: boolean;\n /**\n * The method of authentication to use.\n * Note that on Android you have to define it when signing or decrypting.\n *\n * If you want to allow to use Face ID, you need to add the following to your app.json config file:\n * ```json\n * \"ios\": {\n * \"infoPlist\": {\n * \"NSFaceIDUsageDescription\": \"We use Face ID to secure your data.\",\n * }\n * }\n * ```\n * @default AuthMethod.PASSCODE_OR_BIOMETRIC\n * @platform ios šŸ\n */\n authMethod?: AuthMethod;\n /**\n * If the Strong Box is available, it will be used instead of the Trusted Execution Environment (TEE).\n * @default false\n * @platform android šŸ¤–\n */\n preferStrongBox?: boolean;\n}\n\ntype BaseAuthOptions = {\n /**\n * The title of the prompt to show when authentication is required.\n * @default \"Unlock\"\n * @platform android šŸ¤–\n */\n promptTitle?: string;\n /**\n * The subtitle of the prompt to show when authentication is required.\n * @default \"Enter your PIN to continue\"\n * @platform android šŸ¤–\n */\n promptSubtitle?: string;\n /**\n * The method of authentication to use.\n * Note that on iOS you have to define it when generating the key pair.\n * @default AuthMethod.PASSCODE_OR_BIOMETRIC\n * @platform android šŸ¤–\n */\n authMethod?: AuthMethod;\n}\n\ntype BaseSigningOptions = {\n /**\n * The algorithm type of the key to use for signing.\n */\n algorithmType: SigningAlgorithm;\n};\ntype BaseVerifyOptions = BaseSigningOptions;\n\ntype BaseRsaEncryptionOptions = {\n /**\n * The algorithm type of the key to use for encrypting.\n */\n algorithmType: RsaAlgorithm;\n};\ntype BaseRsaDecryptionOptions = BaseRsaEncryptionOptions;\n\ntype BaseEciesEncryptionOptions = {\n /**\n * The algorithm type of the key to use for encrypting.\n */\n algorithmType: EciesAlgorithm;\n /**\n * The peer public key to use for ECIES.\n */\n peerPublicKey: string;\n};\ntype BaseEciesDecryptionOptions = BaseEciesEncryptionOptions;\n\nexport type SignOptions = BaseAuthOptions & BaseSigningOptions;\nexport type VerifyOptions = BaseVerifyOptions;\n\nexport type DecryptOptions =\n | (BaseAuthOptions & BaseEciesDecryptionOptions)\n | (BaseAuthOptions & BaseRsaDecryptionOptions);\nexport type EncryptOptions =\n | (BaseAuthOptions & BaseEciesEncryptionOptions)\n | BaseRsaEncryptionOptions;\n\nexport interface GetPublicKeyOptions {\n /**\n * The format of the public key to return.\n * @default \"PEM\" (Base64 of PEM-encoded SubjectPublicKeyInfo (SPKI) for P‑256)\n */\n format?: \"PEM\" | \"BASE64\";\n}\n"]}
1
+ {"version":3,"file":"DeviceCrypto.types.js","sourceRoot":"","sources":["../src/DeviceCrypto.types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC/B,kEAAyC,CAAA;IACzC,4EAAmD,CAAA;IACnD,wDAA+B,CAAA;AACjC,CAAC,EAJW,qBAAqB,KAArB,qBAAqB,QAIhC;AAED,MAAM,CAAN,IAAY,eAIX;AAJD,WAAY,eAAe;IACzB,0CAAuB,CAAA;IACvB,8CAA2B,CAAA;IAC3B,8CAA2B,CAAA;AAC7B,CAAC,EAJW,eAAe,KAAf,eAAe,QAI1B;AAED,MAAM,CAAN,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,mCAAqB,CAAA;IACrB,6DAA+C,CAAA;AACjD,CAAC,EAHW,UAAU,KAAV,UAAU,QAGrB;AAED,MAAM,CAAN,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,qEAAiD,CAAA;IACjD,6CAAyB,CAAA;IACzB,qDAAiC,CAAA;AACnC,CAAC,EAJW,gBAAgB,KAAhB,gBAAgB,QAI3B;AAID,MAAM,CAAN,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,wDAAiC,CAAA;IACjC,gEAAyC,CAAA;IACzC,sEAA+C,CAAA;AACjD,CAAC,EAJW,mBAAmB,KAAnB,mBAAmB,QAI9B","sourcesContent":["export enum GenerateKeyPairResult {\n KEY_PAIR_GENERATED = \"KEY_PAIR_GENERATED\",\n KEY_PAIR_ALREADY_EXISTS = \"KEY_PAIR_ALREADY_EXISTS\",\n NOT_AVAILABLE = \"NOT_AVAILABLE\",\n}\n\nexport enum AuthCheckResult {\n AVAILABLE = \"AVAILABLE\",\n NO_HARDWARE = \"NO_HARDWARE\",\n UNAVAILABLE = \"UNAVAILABLE\",\n}\n\nexport enum AuthMethod {\n PASSCODE = \"PASSCODE\",\n PASSCODE_OR_BIOMETRIC = \"PASSCODE_OR_BIOMETRIC\",\n}\n\nexport enum SigningAlgorithm {\n ECDSA_SECP256R1_SHA256 = \"ECDSA_SECP256R1_SHA256\",\n RSA_SHA256 = \"RSA_SHA256\",\n RSA_SHA256_PSS = \"RSA_SHA256_PSS\",\n}\n\ntype EciesAlgorithm = \"ECIES_P256_AES256_GCM\";\ntype RsaAlgorithm = \"RSA_2048_PKCS1\" | \"RSA_2048_OAEP_SHA1\";\nexport enum EncryptionAlgorithm {\n RSA_2048_PKCS1 = \"RSA_2048_PKCS1\",\n RSA_2048_OAEP_SHA1 = \"RSA_2048_OAEP_SHA1\",\n ECIES_P256_AES256_GCM = \"ECIES_P256_AES256_GCM\",\n}\n\nexport type GenerateKeyPairOptions = {\n /**\n * The algorithm type of the key to generate.\n */\n algorithmType: SigningAlgorithm | EncryptionAlgorithm;\n /**\n * Whether to require authentication to sign.\n * Setting this to true will prompt biometric or passcode authentication before signing.\n *\n * Please check the *`isAuthCheckAvailable`* function to see if authentication is available.\n * If authentication is not available, generating a key pair will throw an error.\n * @default false\n */\n requireAuthentication?: boolean;\n /**\n * The method of authentication to use.\n * Note that on Android you have to define it when signing or decrypting.\n *\n * If you want to allow to use Face ID, you need to add the following to your app.json config file:\n * ```json\n * \"ios\": {\n * \"infoPlist\": {\n * \"NSFaceIDUsageDescription\": \"We use Face ID to secure your data.\",\n * }\n * }\n * ```\n * @default AuthMethod.PASSCODE_OR_BIOMETRIC\n * @platform ios šŸ\n */\n authMethod?: AuthMethod;\n /**\n * If the Strong Box is available, it will be used instead of the Trusted Execution Environment (TEE).\n * @default false\n * @platform android šŸ¤–\n */\n preferStrongBox?: boolean;\n}\n\ntype BaseAuthOptions = {\n /**\n * The title of the prompt to show when authentication is required.\n * @default \"Unlock\"\n * @platform android šŸ¤–\n */\n promptTitle?: string;\n /**\n * The subtitle of the prompt to show when authentication is required.\n * @default \"Enter your PIN to continue\"\n * @platform android šŸ¤–\n */\n promptSubtitle?: string;\n /**\n * The method of authentication to use.\n * Note that on iOS you have to define it when generating the key pair.\n * @default AuthMethod.PASSCODE_OR_BIOMETRIC\n * @platform android šŸ¤–\n */\n authMethod?: AuthMethod;\n}\n\ntype BaseSigningOptions = {\n /**\n * The algorithm type of the key to use for signing.\n */\n algorithmType: SigningAlgorithm;\n};\ntype BaseVerifyOptions = BaseSigningOptions;\n\ntype BaseRsaEncryptionOptions = {\n /**\n * The algorithm type of the key to use for encrypting.\n */\n algorithmType: RsaAlgorithm;\n};\ntype BaseRsaDecryptionOptions = BaseRsaEncryptionOptions;\n\ntype BaseEciesEncryptionOptions = {\n /**\n * The algorithm type of the key to use for encrypting.\n */\n algorithmType: EciesAlgorithm;\n /**\n * The peer public key to use for ECIES.\n */\n peerPublicKey: string;\n};\ntype BaseEciesDecryptionOptions = BaseEciesEncryptionOptions;\n\nexport type SignOptions = BaseAuthOptions & BaseSigningOptions;\nexport type VerifyOptions = BaseVerifyOptions;\n\nexport type DecryptOptions =\n | (BaseAuthOptions & BaseEciesDecryptionOptions)\n | (BaseAuthOptions & BaseRsaDecryptionOptions);\nexport type EncryptOptions =\n | (BaseAuthOptions & BaseEciesEncryptionOptions)\n | BaseRsaEncryptionOptions;\n\nexport interface GetPublicKeyOptions {\n /**\n * The format of the public key to return.\n * @default \"PEM\" (Base64 of PEM-encoded SubjectPublicKeyInfo (SPKI) for P‑256)\n */\n format?: \"PEM\" | \"BASE64\";\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'DeviceCrypto'
3
- s.version = '0.3.2'
3
+ s.version = '0.4.0'
4
4
  s.summary = 'Device crypto'
5
5
  s.description = 'Device crypto for Expo using device hardware capabilities'
6
6
  s.author = 'Piotr Pietras'
@@ -26,6 +26,8 @@ enum AlgorithmType: String {
26
26
  case RSA_2048_PKCS1 = "RSA_2048_PKCS1"
27
27
  case RSA_2048_OAEP_SHA1 = "RSA_2048_OAEP_SHA1"
28
28
  case ECIES_P256_AES256_GCM = "ECIES_P256_AES256_GCM"
29
+ case RSA_SHA256 = "RSA_SHA256"
30
+ case RSA_SHA256_PSS = "RSA_SHA256_PSS"
29
31
  }
30
32
 
31
33
  public class DeviceCryptoModule: Module {
@@ -39,6 +41,10 @@ public class DeviceCryptoModule: Module {
39
41
  return .rsaEncryptionOAEPSHA1
40
42
  case .ECIES_P256_AES256_GCM:
41
43
  return .eciesEncryptionCofactorX963SHA256AESGCM
44
+ case .RSA_SHA256:
45
+ return .rsaSignatureMessagePKCS1v15SHA256
46
+ case .RSA_SHA256_PSS:
47
+ return .rsaSignatureMessagePSSSHA256
42
48
  }
43
49
  }
44
50
 
@@ -309,7 +315,7 @@ public class DeviceCryptoModule: Module {
309
315
  )
310
316
  }
311
317
 
312
- let secKey = self.getSecKeyByAlias(alias, keyClass: kSecAttrKeyClassPrivate)
318
+ let secKey = self.getSecKeyByAlias(alias, keyClass: kSecAttrKeyClassPublic)
313
319
  if secKey != nil {
314
320
  return SecureSigningModuleResult.KEY_PAIR_ALREADY_EXISTS.rawValue
315
321
  }
@@ -323,6 +329,10 @@ public class DeviceCryptoModule: Module {
323
329
  self.buildRSA(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
324
330
  case .ECIES_P256_AES256_GCM:
325
331
  self.buildECIES(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
332
+ case .RSA_SHA256:
333
+ self.buildRSA(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
334
+ case .RSA_SHA256_PSS:
335
+ self.buildRSA(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
326
336
  default:
327
337
  throw NSError(
328
338
  domain: "DeviceCrypto",
@@ -418,7 +428,7 @@ public class DeviceCryptoModule: Module {
418
428
  }
419
429
 
420
430
  private func verify(alias: String, data: String, signature: String, o: [String: Any]) -> Bool? {
421
- let secKey = self.getSecKeyByAlias(alias, keyClass: kSecAttrKeyClassPrivate)
431
+ let secKey = self.getSecKeyByAlias(alias, keyClass: kSecAttrKeyClassPublic)
422
432
  guard let secKey else { return nil }
423
433
 
424
434
  guard let publicKey = SecKeyCopyPublicKey(secKey) else { return nil }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-device-crypto",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Crypto for Expo using device hardware capabilities",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -19,8 +19,8 @@
19
19
  "expo",
20
20
  "expo-module",
21
21
  "react-native",
22
- "crypto",
23
- "cryptography",
22
+ "encrypt",
23
+ "signature",
24
24
  "device-crypto",
25
25
  "hardware-backed",
26
26
  "secure-enclave",
@@ -17,6 +17,8 @@ export enum AuthMethod {
17
17
 
18
18
  export enum SigningAlgorithm {
19
19
  ECDSA_SECP256R1_SHA256 = "ECDSA_SECP256R1_SHA256",
20
+ RSA_SHA256 = "RSA_SHA256",
21
+ RSA_SHA256_PSS = "RSA_SHA256_PSS",
20
22
  }
21
23
 
22
24
  type EciesAlgorithm = "ECIES_P256_AES256_GCM";