1- import { NativeModules } from 'react-native' ;
21import { hasProperty , isPlainObject , Json } from '@metamask/utils' ;
32import {
43 SALT_BYTES_COUNT ,
5- SHA256_DIGEST_LENGTH ,
64 ENCRYPTION_LIBRARY ,
75 KEY_DERIVATION_LEGACY_OPTIONS ,
86 KeyDerivationIteration ,
@@ -13,9 +11,7 @@ import type {
1311 EncryptionResult ,
1412 KeyDerivationOptions ,
1513} from './types' ;
16-
17- const Aes = NativeModules . Aes ;
18- const AesForked = NativeModules . AesForked ;
14+ import { getEncryptionLibrary } from './lib' ;
1915
2016/**
2117 * Checks if the provided object is a `KeyDerivationOptions`.
@@ -96,17 +92,6 @@ class Encryptor implements WithKeyEncryptor<EncryptionKey, Json> {
9692 return btoa ( String . fromCharCode . apply ( null , view as unknown as number [ ] ) ) ;
9793 } ;
9894
99- /**
100- * Generates a random IV.
101- *
102- * @param size - The number of bytes for the IV.
103- * @returns The generated IV.
104- */
105- private generateIV = async ( size : number ) : Promise < unknown > =>
106- // Naming isn't perfect here, but this is how the library generates random IV (and encodes it the right way)
107- // See: https://www.npmjs.com/package/react-native-aes-crypto#example
108- await Aes . randomKey ( size ) ;
109-
11095 /**
11196 * Generate an encryption key from a password and random salt, specifying
11297 * key derivation options.
@@ -123,15 +108,7 @@ class Encryptor implements WithKeyEncryptor<EncryptionKey, Json> {
123108 opts : KeyDerivationOptions ,
124109 lib = ENCRYPTION_LIBRARY . original ,
125110 ) : Promise < EncryptionKey > => {
126- const key =
127- lib === ENCRYPTION_LIBRARY . original
128- ? await Aes . pbkdf2 (
129- password ,
130- salt ,
131- opts . params . iterations ,
132- SHA256_DIGEST_LENGTH ,
133- )
134- : await AesForked . pbkdf2 ( password , salt ) ;
111+ const key = await getEncryptionLibrary ( lib ) . deriveKey ( password , salt , opts ) ;
135112
136113 return {
137114 key,
@@ -151,14 +128,18 @@ class Encryptor implements WithKeyEncryptor<EncryptionKey, Json> {
151128 key : EncryptionKey ,
152129 data : Json ,
153130 ) : Promise < EncryptionResult > => {
154- const iv = await this . generateIV ( 16 ) ;
131+ const text = JSON . stringify ( data ) ;
155132
156- return Aes . encrypt ( data , key , iv ) . then ( ( cipher : string ) => ( {
133+ const lib = getEncryptionLibrary ( key . lib ) ;
134+ const iv = await lib . generateIV ( 16 ) ;
135+ const cipher = await lib . encrypt ( text , key . key , iv ) ;
136+
137+ return {
157138 cipher,
158139 iv,
159140 keyMetadata : key . keyMetadata ,
160141 lib : key . lib ,
161- } ) ) ;
142+ } ;
162143 } ;
163144
164145 /**
@@ -173,10 +154,10 @@ class Encryptor implements WithKeyEncryptor<EncryptionKey, Json> {
173154 payload : EncryptionResult ,
174155 ) : Promise < unknown > => {
175156 // TODO: Check for key and payload compatiblity?
176- const text =
177- payload . lib === ENCRYPTION_LIBRARY . original
178- ? await Aes . decrypt ( payload . cipher , key , payload . iv )
179- : await AesForked . decrypt ( payload . cipher , key , payload . iv ) ;
157+
158+ // We assume that both ` payload.lib` and `key.lib` are the same here!
159+ const lib = getEncryptionLibrary ( payload . lib ) ;
160+ const text = await lib . decrypt ( payload . cipher , key . key , payload . iv ) ;
180161
181162 return JSON . parse ( text ) ;
182163 } ;
@@ -203,7 +184,7 @@ class Encryptor implements WithKeyEncryptor<EncryptionKey, Json> {
203184 // NOTE: When re-encrypting, we always use the original library and the KDF parameters from
204185 // the encryptor itself. This makes sure we always re-encrypt with the "latest" and "best"
205186 // setup possible.
206- const result = await this . encryptWithKey ( key , JSON . stringify ( data ) ) ;
187+ const result = await this . encryptWithKey ( key , data ) ;
207188 result . lib = key . lib ; // Use the same library than the one used for key generation!
208189 result . salt = salt ;
209190 result . keyMetadata = key . keyMetadata ;
0 commit comments