expo-device-crypto 0.3.1 → 0.3.3

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,12 @@ 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
+ - `SHA256withRSA`
37
+
38
+ **Key size:** 2048 bits. </br>
39
+ **Padding:** PKCS#1 v1.5. </br>
40
+ **Hash:** SHA-256. </br>
41
+
36
42
  ### šŸ” Encryption Algorithms
37
43
 
38
44
  - `RSA_2048_PKCS1`
@@ -103,9 +109,9 @@ const decrypted = await DeviceCrypto.decrypt(alias, encrypted, {
103
109
 
104
110
  ### šŸ“š More examples
105
111
 
106
- You can find additional usage examples in the [`examples` directory](https://github.com/piotr-pietras/expo-device-crypto/tree/master/examples) of the main repository.
112
+ **You can find additional usage examples in the [`examples` directory](https://github.com/piotr-pietras/expo-device-crypto/tree/master/examples) of the main repository.**
107
113
 
108
- ### šŸ› ļø Methods
114
+ ## Methods
109
115
 
110
116
  - `isAuthCheckAvailable(): AuthCheckResult`
111
117
  - Returns device authentication availability (`AVAILABLE`, `NO_HARDWARE`, `UNAVAILABLE`).
@@ -148,7 +154,7 @@ You can find additional usage examples in the [`examples` directory](https://git
148
154
  - `isStrongBoxAvailable(): boolean`
149
155
  - Returns `true` if StrongBox Keystore is supported on the device.
150
156
 
151
- ## āš ļø Important
157
+ ## Important
152
158
 
153
159
  ### Enable Strong Box on Android
154
160
 
@@ -1,7 +1,7 @@
1
1
  apply plugin: 'com.android.library'
2
2
 
3
3
  group = 'expo.modules.devicecrypto'
4
- version = '0.3.1'
4
+ version = '0.3.3'
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.1"
38
+ versionName "0.3.3"
39
39
  }
40
40
  lintOptions {
41
41
  abortOnError false
@@ -10,6 +10,7 @@ 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
13
14
  import android.security.keystore.KeyProperties.KEY_ALGORITHM_EC
14
15
  import android.security.keystore.KeyProperties.KEY_ALGORITHM_RSA
15
16
  import android.security.keystore.KeyProperties.PURPOSE_DECRYPT
@@ -65,6 +66,12 @@ enum class AlgorithmType {
65
66
  RSA_2048_PKCS1,
66
67
  RSA_2048_OAEP_SHA1,
67
68
  ECIES_P256_AES256_GCM,
69
+ SHA256withRSA
70
+ }
71
+
72
+ enum class Purpose {
73
+ ENCRYPT,
74
+ SIGN,
68
75
  }
69
76
 
70
77
  class DeviceCryptoModule : Module() {
@@ -74,6 +81,7 @@ class DeviceCryptoModule : Module() {
74
81
  AlgorithmType.RSA_2048_PKCS1 -> "RSA/ECB/PKCS1Padding"
75
82
  AlgorithmType.RSA_2048_OAEP_SHA1 -> "RSA/ECB/OAEPwithSHA-1AndMGF1Padding"
76
83
  AlgorithmType.ECIES_P256_AES256_GCM -> "AES/GCM/NoPadding"
84
+ AlgorithmType.SHA256withRSA -> "SHA256withRSA"
77
85
  else -> throw Exception("INVALID_ALGORITHM_TYPE")
78
86
  }
79
87
  }
@@ -183,7 +191,8 @@ class DeviceCryptoModule : Module() {
183
191
  private fun buildRSA(
184
192
  alias: String,
185
193
  digest: String?,
186
- padding: String,
194
+ purpose: Purpose,
195
+ padding: String?,
187
196
  reqAuth: Boolean,
188
197
  strongBox: Boolean): KeyPairGenerator {
189
198
  val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
@@ -193,12 +202,20 @@ class DeviceCryptoModule : Module() {
193
202
 
194
203
  val parameterSpec: KeyGenParameterSpec = KeyGenParameterSpec.Builder(
195
204
  alias,
196
- PURPOSE_ENCRYPT or PURPOSE_DECRYPT
205
+ when (purpose) {
206
+ Purpose.ENCRYPT -> PURPOSE_ENCRYPT or PURPOSE_DECRYPT
207
+ Purpose.SIGN -> PURPOSE_SIGN or PURPOSE_VERIFY
208
+ }
197
209
  ).run {
198
210
  if (digest != null) {
199
211
  setDigests(digest)
200
212
  }
201
- setEncryptionPaddings(padding)
213
+ if (padding != null && purpose == Purpose.ENCRYPT) {
214
+ setEncryptionPaddings(padding)
215
+ }
216
+ if (padding != null && purpose == Purpose.SIGN) {
217
+ setSignaturePaddings(padding)
218
+ }
202
219
  setIsStrongBoxBacked(strongBox)
203
220
  setUserAuthenticationRequired(reqAuth)
204
221
  if (reqAuth) {
@@ -323,10 +340,42 @@ class DeviceCryptoModule : Module() {
323
340
  val strongBox = preferStrongBox && isStrongBoxAvailable()
324
341
 
325
342
  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)
343
+ AlgorithmType.ECDSA_SECP256R1_SHA256 -> buildECDSA(
344
+ alias = alias,
345
+ digest = DIGEST_SHA256,
346
+ reqAuth = reqAuth,
347
+ strongBox = strongBox
348
+ )
349
+ AlgorithmType.RSA_2048_PKCS1 -> buildRSA(
350
+ alias = alias,
351
+ digest = null,
352
+ purpose = Purpose.ENCRYPT,
353
+ padding = ENCRYPTION_PADDING_RSA_PKCS1,
354
+ reqAuth = reqAuth,
355
+ strongBox = strongBox
356
+ )
357
+ AlgorithmType.RSA_2048_OAEP_SHA1 -> buildRSA(
358
+ alias = alias,
359
+ digest = DIGEST_SHA1,
360
+ purpose = Purpose.ENCRYPT,
361
+ padding = ENCRYPTION_PADDING_RSA_OAEP,
362
+ reqAuth = reqAuth,
363
+ strongBox = strongBox
364
+ )
365
+ AlgorithmType.ECIES_P256_AES256_GCM -> buildECIES(
366
+ alias = alias,
367
+ digest = null,
368
+ reqAuth = reqAuth,
369
+ strongBox = strongBox
370
+ )
371
+ AlgorithmType.SHA256withRSA -> buildRSA(
372
+ alias = alias,
373
+ digest = DIGEST_SHA256,
374
+ purpose = Purpose.SIGN,
375
+ padding = SIGNATURE_PADDING_RSA_PKCS1,
376
+ reqAuth = reqAuth,
377
+ strongBox = strongBox
378
+ )
330
379
  else -> throw Exception("INVALID_ALGORITHM_TYPE")
331
380
  }
332
381
 
@@ -13,7 +13,8 @@ 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
+ SHA256withRSA = "SHA256withRSA"
17
18
  }
18
19
  type EciesAlgorithm = "ECIES_P256_AES256_GCM";
19
20
  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,aAAa,kBAAkB;CAChC;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,7 @@ export var AuthMethod;
18
18
  export var SigningAlgorithm;
19
19
  (function (SigningAlgorithm) {
20
20
  SigningAlgorithm["ECDSA_SECP256R1_SHA256"] = "ECDSA_SECP256R1_SHA256";
21
+ SigningAlgorithm["SHA256withRSA"] = "SHA256withRSA";
21
22
  })(SigningAlgorithm || (SigningAlgorithm = {}));
22
23
  export var EncryptionAlgorithm;
23
24
  (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,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,qEAAiD,CAAA;IACjD,mDAA+B,CAAA;AACjC,CAAC,EAHW,gBAAgB,KAAhB,gBAAgB,QAG3B;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 SHA256withRSA = \"SHA256withRSA\",\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.1'
3
+ s.version = '0.3.3'
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,7 @@ 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 SHA256withRSA = "SHA256withRSA"
29
30
  }
30
31
 
31
32
  public class DeviceCryptoModule: Module {
@@ -39,6 +40,8 @@ public class DeviceCryptoModule: Module {
39
40
  return .rsaEncryptionOAEPSHA1
40
41
  case .ECIES_P256_AES256_GCM:
41
42
  return .eciesEncryptionCofactorX963SHA256AESGCM
43
+ case .SHA256withRSA:
44
+ return .rsaSignatureMessagePKCS1v15SHA256
42
45
  }
43
46
  }
44
47
 
@@ -309,7 +312,7 @@ public class DeviceCryptoModule: Module {
309
312
  )
310
313
  }
311
314
 
312
- let secKey = self.getSecKeyByAlias(alias, keyClass: kSecAttrKeyClassPrivate)
315
+ let secKey = self.getSecKeyByAlias(alias, keyClass: kSecAttrKeyClassPublic)
313
316
  if secKey != nil {
314
317
  return SecureSigningModuleResult.KEY_PAIR_ALREADY_EXISTS.rawValue
315
318
  }
@@ -323,6 +326,8 @@ public class DeviceCryptoModule: Module {
323
326
  self.buildRSA(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
324
327
  case .ECIES_P256_AES256_GCM:
325
328
  self.buildECIES(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
329
+ case .SHA256withRSA:
330
+ self.buildRSA(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
326
331
  default:
327
332
  throw NSError(
328
333
  domain: "DeviceCrypto",
@@ -418,7 +423,7 @@ public class DeviceCryptoModule: Module {
418
423
  }
419
424
 
420
425
  private func verify(alias: String, data: String, signature: String, o: [String: Any]) -> Bool? {
421
- let secKey = self.getSecKeyByAlias(alias, keyClass: kSecAttrKeyClassPrivate)
426
+ let secKey = self.getSecKeyByAlias(alias, keyClass: kSecAttrKeyClassPublic)
422
427
  guard let secKey else { return nil }
423
428
 
424
429
  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.1",
3
+ "version": "0.3.3",
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,7 @@ export enum AuthMethod {
17
17
 
18
18
  export enum SigningAlgorithm {
19
19
  ECDSA_SECP256R1_SHA256 = "ECDSA_SECP256R1_SHA256",
20
+ SHA256withRSA = "SHA256withRSA",
20
21
  }
21
22
 
22
23
  type EciesAlgorithm = "ECIES_P256_AES256_GCM";