expo-device-crypto 0.1.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/.eslintrc.js +5 -0
- package/README.md +132 -0
- package/android/build.gradle +47 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/expo/modules/devicecrypto/DeviceCryptoModule.kt +385 -0
- package/build/DeviceCrypto.types.d.ts +101 -0
- package/build/DeviceCrypto.types.d.ts.map +1 -0
- package/build/DeviceCrypto.types.js +26 -0
- package/build/DeviceCrypto.types.js.map +1 -0
- package/build/DeviceCryptoModule.d.ts +86 -0
- package/build/DeviceCryptoModule.d.ts.map +1 -0
- package/build/DeviceCryptoModule.js +132 -0
- package/build/DeviceCryptoModule.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +3 -0
- package/build/index.js.map +1 -0
- package/expo-module.config.json +9 -0
- package/ios/DeviceCrypto.podspec +23 -0
- package/ios/DeviceCrypto.swift +404 -0
- package/package.json +55 -0
- package/src/DeviceCrypto.types.ts +106 -0
- package/src/DeviceCryptoModule.ts +171 -0
- package/src/index.ts +2 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export var GenerateKeyPairResult;
|
|
2
|
+
(function (GenerateKeyPairResult) {
|
|
3
|
+
GenerateKeyPairResult["KEY_PAIR_GENERATED"] = "KEY_PAIR_GENERATED";
|
|
4
|
+
GenerateKeyPairResult["KEY_PAIR_ALREADY_EXISTS"] = "KEY_PAIR_ALREADY_EXISTS";
|
|
5
|
+
GenerateKeyPairResult["NOT_AVAILABLE"] = "NOT_AVAILABLE";
|
|
6
|
+
})(GenerateKeyPairResult || (GenerateKeyPairResult = {}));
|
|
7
|
+
export var AuthCheckResult;
|
|
8
|
+
(function (AuthCheckResult) {
|
|
9
|
+
AuthCheckResult["AVAILABLE"] = "AVAILABLE";
|
|
10
|
+
AuthCheckResult["NO_HARDWARE"] = "NO_HARDWARE";
|
|
11
|
+
AuthCheckResult["UNAVAILABLE"] = "UNAVAILABLE";
|
|
12
|
+
})(AuthCheckResult || (AuthCheckResult = {}));
|
|
13
|
+
export var AuthMethod;
|
|
14
|
+
(function (AuthMethod) {
|
|
15
|
+
AuthMethod["PASSCODE"] = "PASSCODE";
|
|
16
|
+
AuthMethod["PASSCODE_OR_BIOMETRIC"] = "PASSCODE_OR_BIOMETRIC";
|
|
17
|
+
})(AuthMethod || (AuthMethod = {}));
|
|
18
|
+
export var SigningAlgorithm;
|
|
19
|
+
(function (SigningAlgorithm) {
|
|
20
|
+
SigningAlgorithm["ECDSA_SECP256R1_SHA256"] = "ECDSA_SECP256R1_SHA256";
|
|
21
|
+
})(SigningAlgorithm || (SigningAlgorithm = {}));
|
|
22
|
+
export var EncryptionAlgorithm;
|
|
23
|
+
(function (EncryptionAlgorithm) {
|
|
24
|
+
EncryptionAlgorithm["RSA_2048_PKCS1"] = "RSA_2048_PKCS1";
|
|
25
|
+
})(EncryptionAlgorithm || (EncryptionAlgorithm = {}));
|
|
26
|
+
//# sourceMappingURL=DeviceCrypto.types.js.map
|
|
@@ -0,0 +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;AAED,MAAM,CAAN,IAAY,mBAEX;AAFD,WAAY,mBAAmB;IAC7B,wDAAiC,CAAA;AACnC,CAAC,EAFW,mBAAmB,KAAnB,mBAAmB,QAE9B","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\nexport enum EncryptionAlgorithm {\n RSA_2048_PKCS1 = \"RSA_2048_PKCS1\",\n}\n\nexport interface 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.\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\ninterface BaseSignDecryptOptions {\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\ninterface BaseSigningOptions {\n /**\n * The algorithm type of the key to use for signing.\n */\n algorithmType?: SigningAlgorithm;\n}\n\ninterface BaseEncryptionOptions {\n /**\n * The algorithm type of the key to use for encrypting.\n */\n algorithmType?: EncryptionAlgorithm;\n}\n\nexport interface SignOptions extends BaseSignDecryptOptions, BaseSigningOptions {}\nexport interface VerifyOptions extends BaseSigningOptions {}\n\nexport interface DecryptOptions extends BaseSignDecryptOptions, BaseEncryptionOptions {}\nexport interface EncryptOptions extends BaseEncryptionOptions {}\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\";\n}\n"]}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { AuthCheckResult, GenerateKeyPairOptions, GenerateKeyPairResult, GetPublicKeyOptions, SignOptions, DecryptOptions, VerifyOptions, EncryptOptions } from "./DeviceCrypto.types";
|
|
2
|
+
declare const _default: {
|
|
3
|
+
/**
|
|
4
|
+
* Checks if the biometric or passcode authentication is available.
|
|
5
|
+
* @returns The result of the operation.
|
|
6
|
+
*/
|
|
7
|
+
isAuthCheckAvailable: () => AuthCheckResult;
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new ECDSA P‑256 key pair for the given alias, if it doesn’t already exist.
|
|
10
|
+
* @param alias - The alias to use for the key pair.
|
|
11
|
+
* @returns The result of the operation.
|
|
12
|
+
*/
|
|
13
|
+
generateKeyPair: (alias: string, options?: GenerateKeyPairOptions) => Promise<GenerateKeyPairResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Returns the public key for the given alias.
|
|
16
|
+
* @param alias - The alias to use for the key pair.
|
|
17
|
+
* @param options - The options for the operation.
|
|
18
|
+
* @returns The public key.
|
|
19
|
+
*/
|
|
20
|
+
getPublicKey: (alias: string, options?: GetPublicKeyOptions) => string | null;
|
|
21
|
+
/**
|
|
22
|
+
* Removes the key pair for the given alias.
|
|
23
|
+
* @param alias - The alias to use for the key pair.
|
|
24
|
+
* @returns True if the key pair was removed, false otherwise.
|
|
25
|
+
*/
|
|
26
|
+
removeKeyPair: (alias: string) => boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Lists the aliases for the key pairs.
|
|
29
|
+
* @returns The aliases.
|
|
30
|
+
*/
|
|
31
|
+
aliases: () => string[];
|
|
32
|
+
/**
|
|
33
|
+
* Signs the given data with the private key for the given alias.
|
|
34
|
+
* @param alias - The alias to use for the key pair.
|
|
35
|
+
* @param data - The data to sign.
|
|
36
|
+
* @param options - The options for the operation.
|
|
37
|
+
* @default {
|
|
38
|
+
* algoType: SigningAlgorithm.ECDSA_SHA256,
|
|
39
|
+
* promptTitle: "Unlock",
|
|
40
|
+
* promptSubtitle: "Enter your PIN to continue",
|
|
41
|
+
* authMethod: AuthMethod.PASSCODE_OR_BIOMETRIC
|
|
42
|
+
* }
|
|
43
|
+
* @returns The signature.
|
|
44
|
+
*/
|
|
45
|
+
sign: (alias: string, data: string, options?: SignOptions) => Promise<string | null>;
|
|
46
|
+
/**
|
|
47
|
+
* Verifies the given data with the signature for the given alias.
|
|
48
|
+
* @param alias - The alias to use for the key pair.
|
|
49
|
+
* @param data - The data to verify.
|
|
50
|
+
* @param signature - The signature to verify.
|
|
51
|
+
* @param options - The options for the operation.
|
|
52
|
+
* @default {
|
|
53
|
+
* algoType: SigningAlgorithm.ECDSA_SHA256,
|
|
54
|
+
* }
|
|
55
|
+
* @returns True if the signature is valid, false otherwise.
|
|
56
|
+
*/
|
|
57
|
+
verify: (alias: string, data: string, signature: string, options?: VerifyOptions) => Promise<boolean | null>;
|
|
58
|
+
/**
|
|
59
|
+
* Signs the given data with the private key for the given alias.
|
|
60
|
+
* @param alias - The alias to use for the key pair.
|
|
61
|
+
* @param data - The data to sign in UTF-8 format.
|
|
62
|
+
* @param options - The options for the operation.
|
|
63
|
+
* @default {
|
|
64
|
+
* algoType: EncryptionAlgorithm.RSA_2048_PKCS1,
|
|
65
|
+
* }
|
|
66
|
+
* @returns The signature.
|
|
67
|
+
*/
|
|
68
|
+
encrypt: (alias: string, data: string, options?: EncryptOptions) => Promise<string | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Decrypts the given data with the private key for the given alias.
|
|
71
|
+
* @param alias - The alias to use for the key pair.
|
|
72
|
+
* @param data - The data to decrypt in Base64 format.
|
|
73
|
+
* @param options - The options for the operation.
|
|
74
|
+
* @default {
|
|
75
|
+
* algoType: EncryptionAlgorithm.RSA_2048_PKCS1,
|
|
76
|
+
* promptTitle: "Unlock",
|
|
77
|
+
* promptSubtitle: "Enter your PIN to continue",
|
|
78
|
+
* authMethod: AuthMethod.PASSCODE_OR_BIOMETRIC
|
|
79
|
+
* }
|
|
80
|
+
* @returns The decrypted data.
|
|
81
|
+
*/
|
|
82
|
+
decrypt: (alias: string, data: string, options?: DecryptOptions) => Promise<string | null>;
|
|
83
|
+
};
|
|
84
|
+
export default _default;
|
|
85
|
+
export type { GenerateKeyPairResult };
|
|
86
|
+
//# sourceMappingURL=DeviceCryptoModule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceCryptoModule.d.ts","sourceRoot":"","sources":["../src/DeviceCryptoModule.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EAEnB,WAAW,EACX,cAAc,EACd,aAAa,EAEb,cAAc,EAEf,MAAM,sBAAsB,CAAC;;IA6B5B;;;OAGG;gCAtBqB,eAAe;IAwBvC;;;;OAIG;6BAC4B,MAAM,YAAY,sBAAsB;IAQvE;;;;;OAKG;0BACmB,MAAM,YAAY,mBAAmB;IAQ3D;;;;OAIG;2BApDkB,MAAM,KAAG,OAAO;IAsDrC;;;OAGG;mBAxDQ,MAAM,EAAE;IA0DnB;;;;;;;;;;;;OAYG;kBACiB,MAAM,QAAQ,MAAM,YAAY,WAAW;IAS/D;;;;;;;;;;OAUG;oBAEM,MAAM,QACP,MAAM,aACD,MAAM,YACP,aAAa;IAOzB;;;;;;;;;OASG;qBACoB,MAAM,QAAQ,MAAM,YAAY,cAAc;IAMrE;;;;;;;;;;;;OAYG;qBACoB,MAAM,QAAQ,MAAM,YAAY,cAAc;;AArHvE,wBA8HE;AAEF,YAAY,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { requireNativeModule } from "expo";
|
|
2
|
+
import { AuthMethod, SigningAlgorithm, EncryptionAlgorithm, } from "./DeviceCrypto.types";
|
|
3
|
+
function base64ToPem(base64, label = "DATA") {
|
|
4
|
+
const normalized = base64.replace(/\s+/g, "");
|
|
5
|
+
const wrapped = normalized.match(/.{1,64}/g)?.join("\n") ?? "";
|
|
6
|
+
return `-----BEGIN ${label}-----\n${wrapped}\n-----END ${label}-----\n`;
|
|
7
|
+
}
|
|
8
|
+
const module = requireNativeModule("DeviceCrypto");
|
|
9
|
+
export default {
|
|
10
|
+
/**
|
|
11
|
+
* Checks if the biometric or passcode authentication is available.
|
|
12
|
+
* @returns The result of the operation.
|
|
13
|
+
*/
|
|
14
|
+
isAuthCheckAvailable: module.isAuthCheckAvailable,
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new ECDSA P‑256 key pair for the given alias, if it doesn’t already exist.
|
|
17
|
+
* @param alias - The alias to use for the key pair.
|
|
18
|
+
* @returns The result of the operation.
|
|
19
|
+
*/
|
|
20
|
+
generateKeyPair: async (alias, options) => {
|
|
21
|
+
const o = {
|
|
22
|
+
algoType: options?.algorithmType,
|
|
23
|
+
reqAuth: options?.requireAuthentication ?? false,
|
|
24
|
+
authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,
|
|
25
|
+
};
|
|
26
|
+
return module.generateKeyPair(alias, o);
|
|
27
|
+
},
|
|
28
|
+
/**
|
|
29
|
+
* Returns the public key for the given alias.
|
|
30
|
+
* @param alias - The alias to use for the key pair.
|
|
31
|
+
* @param options - The options for the operation.
|
|
32
|
+
* @returns The public key.
|
|
33
|
+
*/
|
|
34
|
+
getPublicKey: (alias, options) => {
|
|
35
|
+
const publicKey = module.getPublicKey(alias);
|
|
36
|
+
if (!publicKey)
|
|
37
|
+
return null;
|
|
38
|
+
if (options?.format === "PEM") {
|
|
39
|
+
return base64ToPem(publicKey, "PUBLIC KEY");
|
|
40
|
+
}
|
|
41
|
+
return base64ToPem(publicKey, "PUBLIC KEY");
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* Removes the key pair for the given alias.
|
|
45
|
+
* @param alias - The alias to use for the key pair.
|
|
46
|
+
* @returns True if the key pair was removed, false otherwise.
|
|
47
|
+
*/
|
|
48
|
+
removeKeyPair: module.removeKeyPair,
|
|
49
|
+
/**
|
|
50
|
+
* Lists the aliases for the key pairs.
|
|
51
|
+
* @returns The aliases.
|
|
52
|
+
*/
|
|
53
|
+
aliases: module.aliases,
|
|
54
|
+
/**
|
|
55
|
+
* Signs the given data with the private key for the given alias.
|
|
56
|
+
* @param alias - The alias to use for the key pair.
|
|
57
|
+
* @param data - The data to sign.
|
|
58
|
+
* @param options - The options for the operation.
|
|
59
|
+
* @default {
|
|
60
|
+
* algoType: SigningAlgorithm.ECDSA_SHA256,
|
|
61
|
+
* promptTitle: "Unlock",
|
|
62
|
+
* promptSubtitle: "Enter your PIN to continue",
|
|
63
|
+
* authMethod: AuthMethod.PASSCODE_OR_BIOMETRIC
|
|
64
|
+
* }
|
|
65
|
+
* @returns The signature.
|
|
66
|
+
*/
|
|
67
|
+
sign: async (alias, data, options) => {
|
|
68
|
+
const o = {
|
|
69
|
+
title: options?.promptTitle ?? "Unlock",
|
|
70
|
+
subtitle: options?.promptSubtitle ?? "Enter your PIN to continue",
|
|
71
|
+
authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,
|
|
72
|
+
algoType: options?.algorithmType ?? SigningAlgorithm.ECDSA_SECP256R1_SHA256,
|
|
73
|
+
};
|
|
74
|
+
return module.sign(alias, data, o);
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* Verifies the given data with the signature for the given alias.
|
|
78
|
+
* @param alias - The alias to use for the key pair.
|
|
79
|
+
* @param data - The data to verify.
|
|
80
|
+
* @param signature - The signature to verify.
|
|
81
|
+
* @param options - The options for the operation.
|
|
82
|
+
* @default {
|
|
83
|
+
* algoType: SigningAlgorithm.ECDSA_SHA256,
|
|
84
|
+
* }
|
|
85
|
+
* @returns True if the signature is valid, false otherwise.
|
|
86
|
+
*/
|
|
87
|
+
verify: async (alias, data, signature, options) => {
|
|
88
|
+
const o = {
|
|
89
|
+
algoType: options?.algorithmType ?? SigningAlgorithm.ECDSA_SECP256R1_SHA256,
|
|
90
|
+
};
|
|
91
|
+
return module.verify(alias, data, signature, o);
|
|
92
|
+
},
|
|
93
|
+
/**
|
|
94
|
+
* Signs the given data with the private key for the given alias.
|
|
95
|
+
* @param alias - The alias to use for the key pair.
|
|
96
|
+
* @param data - The data to sign in UTF-8 format.
|
|
97
|
+
* @param options - The options for the operation.
|
|
98
|
+
* @default {
|
|
99
|
+
* algoType: EncryptionAlgorithm.RSA_2048_PKCS1,
|
|
100
|
+
* }
|
|
101
|
+
* @returns The signature.
|
|
102
|
+
*/
|
|
103
|
+
encrypt: async (alias, data, options) => {
|
|
104
|
+
const o = {
|
|
105
|
+
algoType: options?.algorithmType ?? EncryptionAlgorithm.RSA_2048_PKCS1,
|
|
106
|
+
};
|
|
107
|
+
return module.encrypt(alias, data, o);
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Decrypts the given data with the private key for the given alias.
|
|
111
|
+
* @param alias - The alias to use for the key pair.
|
|
112
|
+
* @param data - The data to decrypt in Base64 format.
|
|
113
|
+
* @param options - The options for the operation.
|
|
114
|
+
* @default {
|
|
115
|
+
* algoType: EncryptionAlgorithm.RSA_2048_PKCS1,
|
|
116
|
+
* promptTitle: "Unlock",
|
|
117
|
+
* promptSubtitle: "Enter your PIN to continue",
|
|
118
|
+
* authMethod: AuthMethod.PASSCODE_OR_BIOMETRIC
|
|
119
|
+
* }
|
|
120
|
+
* @returns The decrypted data.
|
|
121
|
+
*/
|
|
122
|
+
decrypt: async (alias, data, options) => {
|
|
123
|
+
const o = {
|
|
124
|
+
title: options?.promptTitle ?? "Unlock",
|
|
125
|
+
subtitle: options?.promptSubtitle ?? "Enter your PIN to continue",
|
|
126
|
+
authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,
|
|
127
|
+
algoType: options?.algorithmType ?? EncryptionAlgorithm.RSA_2048_PKCS1,
|
|
128
|
+
};
|
|
129
|
+
return module.decrypt(alias, data, o);
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
//# sourceMappingURL=DeviceCryptoModule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceCryptoModule.js","sourceRoot":"","sources":["../src/DeviceCryptoModule.ts"],"names":[],"mappings":"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","sourcesContent":["import { NativeModule, requireNativeModule } from \"expo\";\n\nimport {\n AuthCheckResult,\n GenerateKeyPairOptions,\n GenerateKeyPairResult,\n GetPublicKeyOptions,\n AuthMethod,\n SignOptions,\n DecryptOptions,\n VerifyOptions,\n SigningAlgorithm,\n EncryptOptions,\n EncryptionAlgorithm,\n} from \"./DeviceCrypto.types\";\n\nfunction base64ToPem(base64: string, label = \"DATA\") {\n const normalized = base64.replace(/\\s+/g, \"\");\n const wrapped = normalized.match(/.{1,64}/g)?.join(\"\\n\") ?? \"\";\n\n return `-----BEGIN ${label}-----\\n${wrapped}\\n-----END ${label}-----\\n`;\n}\n\ndeclare class DeviceCryptoModule extends NativeModule {\n isAuthCheckAvailable(): AuthCheckResult;\n generateKeyPair(alias: string, o: any): GenerateKeyPairResult;\n getPublicKey(alias: string): string | null;\n removeKeyPair(alias: string): boolean;\n aliases(): string[];\n sign(alias: string, data: string, o: any): Promise<string | null>;\n verify(\n alias: string,\n data: string,\n signature: string,\n o: any\n ): boolean | null;\n encrypt(alias: string, data: string, o: any): Promise<string | null>;\n decrypt(alias: string, data: string, o: any): Promise<string | null>;\n}\n\nconst module = requireNativeModule<DeviceCryptoModule>(\"DeviceCrypto\");\n\nexport default {\n /**\n * Checks if the biometric or passcode authentication is available.\n * @returns The result of the operation.\n */\n isAuthCheckAvailable: module.isAuthCheckAvailable,\n /**\n * Creates a new ECDSA P‑256 key pair for the given alias, if it doesn’t already exist.\n * @param alias - The alias to use for the key pair.\n * @returns The result of the operation.\n */\n generateKeyPair: async (alias: string, options?: GenerateKeyPairOptions) => {\n const o = {\n algoType: options?.algorithmType,\n reqAuth: options?.requireAuthentication ?? false,\n authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,\n };\n return module.generateKeyPair(alias, o);\n },\n /**\n * Returns the public key for the given alias.\n * @param alias - The alias to use for the key pair.\n * @param options - The options for the operation.\n * @returns The public key.\n */\n getPublicKey: (alias: string, options?: GetPublicKeyOptions) => {\n const publicKey = module.getPublicKey(alias);\n if (!publicKey) return null;\n if (options?.format === \"PEM\") {\n return base64ToPem(publicKey, \"PUBLIC KEY\");\n }\n return base64ToPem(publicKey, \"PUBLIC KEY\");\n },\n /**\n * Removes the key pair for the given alias.\n * @param alias - The alias to use for the key pair.\n * @returns True if the key pair was removed, false otherwise.\n */\n removeKeyPair: module.removeKeyPair,\n /**\n * Lists the aliases for the key pairs.\n * @returns The aliases.\n */\n aliases: module.aliases,\n /**\n * Signs the given data with the private key for the given alias.\n * @param alias - The alias to use for the key pair.\n * @param data - The data to sign.\n * @param options - The options for the operation.\n * @default { \n * algoType: SigningAlgorithm.ECDSA_SHA256, \n * promptTitle: \"Unlock\", \n * promptSubtitle: \"Enter your PIN to continue\", \n * authMethod: AuthMethod.PASSCODE_OR_BIOMETRIC \n * }\n * @returns The signature.\n */\n sign: async (alias: string, data: string, options?: SignOptions) => {\n const o = {\n title: options?.promptTitle ?? \"Unlock\",\n subtitle: options?.promptSubtitle ?? \"Enter your PIN to continue\",\n authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,\n algoType: options?.algorithmType ?? SigningAlgorithm.ECDSA_SECP256R1_SHA256,\n };\n return module.sign(alias, data, o);\n },\n /**\n * Verifies the given data with the signature for the given alias.\n * @param alias - The alias to use for the key pair.\n * @param data - The data to verify.\n * @param signature - The signature to verify.\n * @param options - The options for the operation.\n * @default { \n * algoType: SigningAlgorithm.ECDSA_SHA256, \n * }\n * @returns True if the signature is valid, false otherwise.\n */\n verify: async (\n alias: string,\n data: string,\n signature: string,\n options?: VerifyOptions\n ) => {\n const o = {\n algoType: options?.algorithmType ?? SigningAlgorithm.ECDSA_SECP256R1_SHA256,\n };\n return module.verify(alias, data, signature, o);\n },\n /**\n * Signs the given data with the private key for the given alias.\n * @param alias - The alias to use for the key pair.\n * @param data - The data to sign in UTF-8 format.\n * @param options - The options for the operation.\n * @default { \n * algoType: EncryptionAlgorithm.RSA_2048_PKCS1, \n * }\n * @returns The signature.\n */\n encrypt: async (alias: string, data: string, options?: EncryptOptions) => {\n const o = {\n algoType: options?.algorithmType ?? EncryptionAlgorithm.RSA_2048_PKCS1,\n };\n return module.encrypt(alias, data, o);\n },\n /**\n * Decrypts the given data with the private key for the given alias.\n * @param alias - The alias to use for the key pair.\n * @param data - The data to decrypt in Base64 format.\n * @param options - The options for the operation.\n * @default { \n * algoType: EncryptionAlgorithm.RSA_2048_PKCS1, \n * promptTitle: \"Unlock\", \n * promptSubtitle: \"Enter your PIN to continue\", \n * authMethod: AuthMethod.PASSCODE_OR_BIOMETRIC \n * }\n * @returns The decrypted data.\n */\n decrypt: async (alias: string, data: string, options?: DecryptOptions) => {\n const o = {\n title: options?.promptTitle ?? \"Unlock\",\n subtitle: options?.promptSubtitle ?? \"Enter your PIN to continue\",\n authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,\n algoType: options?.algorithmType ?? EncryptionAlgorithm.RSA_2048_PKCS1,\n };\n return module.decrypt(alias, data, o);\n },\n};\n\nexport type { GenerateKeyPairResult };\n"]}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,cAAc,sBAAsB,CAAC"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,cAAc,sBAAsB,CAAC","sourcesContent":["export { default } from './DeviceCryptoModule';\nexport * from './DeviceCrypto.types';\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Pod::Spec.new do |s|
|
|
2
|
+
s.name = 'DeviceCrypto'
|
|
3
|
+
s.version = '0.1.0'
|
|
4
|
+
s.summary = 'Device crypto'
|
|
5
|
+
s.description = 'Device crypto for Expo using device hardware capabilities'
|
|
6
|
+
s.author = 'Piotr Pietras'
|
|
7
|
+
s.homepage = 'https://docs.expo.dev/modules/'
|
|
8
|
+
s.platforms = {
|
|
9
|
+
:ios => '15.1',
|
|
10
|
+
:tvos => '15.1'
|
|
11
|
+
}
|
|
12
|
+
s.source = { git: '' }
|
|
13
|
+
s.static_framework = true
|
|
14
|
+
|
|
15
|
+
s.dependency 'ExpoModulesCore'
|
|
16
|
+
|
|
17
|
+
# Swift/Objective-C compatibility
|
|
18
|
+
s.pod_target_xcconfig = {
|
|
19
|
+
'DEFINES_MODULE' => 'YES',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}"
|
|
23
|
+
end
|