expo-device-crypto 0.3.3 → 1.0.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 +7 -3
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/devicecrypto/DeviceCryptoModule.kt +14 -3
- package/build/DeviceCrypto.types.d.ts +2 -1
- package/build/DeviceCrypto.types.d.ts.map +1 -1
- package/build/DeviceCrypto.types.js +2 -1
- package/build/DeviceCrypto.types.js.map +1 -1
- package/ios/DeviceCrypto.podspec +1 -1
- package/ios/DeviceCrypto.swift +8 -3
- package/package.json +1 -1
- package/src/DeviceCrypto.types.ts +2 -1
package/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
## `expo-device-crypto`
|
|
2
2
|
|
|
3
|
-
> ⚠️ This module is currently in beta and is not suitable for production use.
|
|
4
|
-
|
|
5
3
|
🔒 Hardware-backed cryptography for Expo apps using [Android Keystore](https://developer.android.com/privacy-and-security/keystore)/[Strong Box](https://developer.android.com/privacy-and-security/keystore#StrongBoxKeyMint) and Apple [Secure Enclave](https://developer.apple.com/documentation/security/protecting-keys-with-the-secure-enclave)/[Keychain](https://developer.apple.com/documentation/security/keychain-services).
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
@@ -33,12 +31,18 @@ If you want to allow Face ID on iOS, add this to your app config:
|
|
|
33
31
|
**Curve:** P-256 / secp256r1. </br>
|
|
34
32
|
**Hash:** SHA-256. </br>
|
|
35
33
|
|
|
36
|
-
- `
|
|
34
|
+
- `RSA_SHA256`
|
|
37
35
|
|
|
38
36
|
**Key size:** 2048 bits. </br>
|
|
39
37
|
**Padding:** PKCS#1 v1.5. </br>
|
|
40
38
|
**Hash:** SHA-256. </br>
|
|
41
39
|
|
|
40
|
+
- `RSA_SHA256_PSS`
|
|
41
|
+
|
|
42
|
+
**Key size:** 2048 bits. </br>
|
|
43
|
+
**Padding:** RSA-PSS (MGF1). </br>
|
|
44
|
+
**Hash:** SHA-256. </br>
|
|
45
|
+
|
|
42
46
|
### 🔐 Encryption Algorithms
|
|
43
47
|
|
|
44
48
|
- `RSA_2048_PKCS1`
|
package/android/build.gradle
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
2
|
|
|
3
3
|
group = 'expo.modules.devicecrypto'
|
|
4
|
-
version = '0.
|
|
4
|
+
version = '1.0.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.
|
|
38
|
+
versionName "1.0.0"
|
|
39
39
|
}
|
|
40
40
|
lintOptions {
|
|
41
41
|
abortOnError false
|
|
@@ -11,6 +11,7 @@ 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
13
|
import android.security.keystore.KeyProperties.SIGNATURE_PADDING_RSA_PKCS1
|
|
14
|
+
import android.security.keystore.KeyProperties.SIGNATURE_PADDING_RSA_PSS
|
|
14
15
|
import android.security.keystore.KeyProperties.KEY_ALGORITHM_EC
|
|
15
16
|
import android.security.keystore.KeyProperties.KEY_ALGORITHM_RSA
|
|
16
17
|
import android.security.keystore.KeyProperties.PURPOSE_DECRYPT
|
|
@@ -66,7 +67,8 @@ enum class AlgorithmType {
|
|
|
66
67
|
RSA_2048_PKCS1,
|
|
67
68
|
RSA_2048_OAEP_SHA1,
|
|
68
69
|
ECIES_P256_AES256_GCM,
|
|
69
|
-
|
|
70
|
+
RSA_SHA256,
|
|
71
|
+
RSA_SHA256_PSS
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
enum class Purpose {
|
|
@@ -81,7 +83,8 @@ class DeviceCryptoModule : Module() {
|
|
|
81
83
|
AlgorithmType.RSA_2048_PKCS1 -> "RSA/ECB/PKCS1Padding"
|
|
82
84
|
AlgorithmType.RSA_2048_OAEP_SHA1 -> "RSA/ECB/OAEPwithSHA-1AndMGF1Padding"
|
|
83
85
|
AlgorithmType.ECIES_P256_AES256_GCM -> "AES/GCM/NoPadding"
|
|
84
|
-
AlgorithmType.
|
|
86
|
+
AlgorithmType.RSA_SHA256 -> "SHA256withRSA"
|
|
87
|
+
AlgorithmType.RSA_SHA256_PSS -> "SHA256withRSA/PSS"
|
|
85
88
|
else -> throw Exception("INVALID_ALGORITHM_TYPE")
|
|
86
89
|
}
|
|
87
90
|
}
|
|
@@ -368,7 +371,7 @@ class DeviceCryptoModule : Module() {
|
|
|
368
371
|
reqAuth = reqAuth,
|
|
369
372
|
strongBox = strongBox
|
|
370
373
|
)
|
|
371
|
-
AlgorithmType.
|
|
374
|
+
AlgorithmType.RSA_SHA256 -> buildRSA(
|
|
372
375
|
alias = alias,
|
|
373
376
|
digest = DIGEST_SHA256,
|
|
374
377
|
purpose = Purpose.SIGN,
|
|
@@ -376,6 +379,14 @@ class DeviceCryptoModule : Module() {
|
|
|
376
379
|
reqAuth = reqAuth,
|
|
377
380
|
strongBox = strongBox
|
|
378
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
|
+
)
|
|
379
390
|
else -> throw Exception("INVALID_ALGORITHM_TYPE")
|
|
380
391
|
}
|
|
381
392
|
|
|
@@ -14,7 +14,8 @@ export declare enum AuthMethod {
|
|
|
14
14
|
}
|
|
15
15
|
export declare enum SigningAlgorithm {
|
|
16
16
|
ECDSA_SECP256R1_SHA256 = "ECDSA_SECP256R1_SHA256",
|
|
17
|
-
|
|
17
|
+
RSA_SHA256 = "RSA_SHA256",
|
|
18
|
+
RSA_SHA256_PSS = "RSA_SHA256_PSS"
|
|
18
19
|
}
|
|
19
20
|
type EciesAlgorithm = "ECIES_P256_AES256_GCM";
|
|
20
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;IACjD,
|
|
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,7 +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["
|
|
21
|
+
SigningAlgorithm["RSA_SHA256"] = "RSA_SHA256";
|
|
22
|
+
SigningAlgorithm["RSA_SHA256_PSS"] = "RSA_SHA256_PSS";
|
|
22
23
|
})(SigningAlgorithm || (SigningAlgorithm = {}));
|
|
23
24
|
export var EncryptionAlgorithm;
|
|
24
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,
|
|
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"]}
|
package/ios/DeviceCrypto.podspec
CHANGED
package/ios/DeviceCrypto.swift
CHANGED
|
@@ -26,7 +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
|
|
29
|
+
case RSA_SHA256 = "RSA_SHA256"
|
|
30
|
+
case RSA_SHA256_PSS = "RSA_SHA256_PSS"
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
public class DeviceCryptoModule: Module {
|
|
@@ -40,8 +41,10 @@ public class DeviceCryptoModule: Module {
|
|
|
40
41
|
return .rsaEncryptionOAEPSHA1
|
|
41
42
|
case .ECIES_P256_AES256_GCM:
|
|
42
43
|
return .eciesEncryptionCofactorX963SHA256AESGCM
|
|
43
|
-
case .
|
|
44
|
+
case .RSA_SHA256:
|
|
44
45
|
return .rsaSignatureMessagePKCS1v15SHA256
|
|
46
|
+
case .RSA_SHA256_PSS:
|
|
47
|
+
return .rsaSignatureMessagePSSSHA256
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
|
|
@@ -326,7 +329,9 @@ public class DeviceCryptoModule: Module {
|
|
|
326
329
|
self.buildRSA(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
|
|
327
330
|
case .ECIES_P256_AES256_GCM:
|
|
328
331
|
self.buildECIES(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
|
|
329
|
-
case .
|
|
332
|
+
case .RSA_SHA256:
|
|
333
|
+
self.buildRSA(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
|
|
334
|
+
case .RSA_SHA256_PSS:
|
|
330
335
|
self.buildRSA(alias: alias, reqAuth: reqAuth, authMethod: authMethod!)
|
|
331
336
|
default:
|
|
332
337
|
throw NSError(
|
package/package.json
CHANGED
|
@@ -17,7 +17,8 @@ export enum AuthMethod {
|
|
|
17
17
|
|
|
18
18
|
export enum SigningAlgorithm {
|
|
19
19
|
ECDSA_SECP256R1_SHA256 = "ECDSA_SECP256R1_SHA256",
|
|
20
|
-
|
|
20
|
+
RSA_SHA256 = "RSA_SHA256",
|
|
21
|
+
RSA_SHA256_PSS = "RSA_SHA256_PSS",
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
type EciesAlgorithm = "ECIES_P256_AES256_GCM";
|