Skip to content

Commit 5b43a7b

Browse files
gantunesrowencraston
authored andcommitted
refactor: encryptor to typescript
1 parent 0f7f117 commit 5b43a7b

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

app/core/Encryptor/Encryptor.ts

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import { NativeModules } from 'react-native';
2+
const Aes = NativeModules.Aes;
3+
const AesForked = NativeModules.AesForked;
4+
5+
/**
6+
* Class that exposes two public methods: Encrypt and Decrypt
7+
* This is used by the KeyringController to encrypt / decrypt the state
8+
* which contains sensitive seed words and addresses
9+
*/
10+
class Encryptor {
11+
key = null;
12+
13+
_generateSalt(byteCount = 32) {
14+
const view = new Uint8Array(byteCount);
15+
global.crypto.getRandomValues(view);
16+
const b64encoded = btoa(String.fromCharCode.apply(null, Array.from(view)));
17+
return b64encoded;
18+
}
19+
20+
_generateKey = ({
21+
password,
22+
salt,
23+
lib,
24+
}: {
25+
password: string;
26+
salt: string;
27+
lib: string;
28+
}) =>
29+
lib === 'original'
30+
? Aes.pbkdf2(password, salt, 5000, 256)
31+
: AesForked.pbkdf2(password, salt);
32+
33+
_keyFromPassword = ({
34+
password,
35+
salt,
36+
lib,
37+
}: {
38+
password: string;
39+
salt: string;
40+
lib: string;
41+
}) => this._generateKey({ password, salt, lib });
42+
43+
_encryptWithKey = async ({
44+
text,
45+
keyBase64,
46+
}: {
47+
text: string;
48+
keyBase64: string;
49+
}) => {
50+
const iv = await Aes.randomKey(16);
51+
return Aes.encrypt(text, keyBase64, iv).then((cipher: string) => ({
52+
cipher,
53+
iv,
54+
}));
55+
};
56+
57+
_decryptWithKey = ({
58+
encryptedData,
59+
key,
60+
lib,
61+
}: {
62+
encryptedData: { cipher: string; iv: string };
63+
key: string;
64+
lib: string;
65+
}) =>
66+
lib === 'original'
67+
? Aes.decrypt(encryptedData.cipher, key, encryptedData.iv)
68+
: AesForked.decrypt(encryptedData.cipher, key, encryptedData.iv);
69+
70+
/**
71+
* Asynchronously encrypts a given object using AES encryption.
72+
* The encryption process involves generating a salt, deriving a key from the provided password and salt,
73+
* and then using the key to encrypt the object. The result includes the encrypted data, the salt used,
74+
* and the library version ('original' in this case).
75+
*
76+
* @param params.password - The password used for generating the encryption key.
77+
* @param params.object - The data object to encrypt. It can be of any type, as it will be stringified during the encryption process.
78+
* @returns A promise that resolves to a string. The string is a JSON representation of an object containing the encrypted data, the salt used for encryption, and the library version.
79+
*/
80+
encrypt = async ({
81+
password,
82+
object,
83+
}: {
84+
password: string;
85+
object: unknown;
86+
}): Promise<string> => {
87+
const salt = this._generateSalt(16);
88+
const key = await this._keyFromPassword({
89+
password,
90+
salt,
91+
lib: 'original',
92+
});
93+
const result = await this._encryptWithKey({
94+
text: JSON.stringify(object),
95+
keyBase64: key,
96+
});
97+
result.salt = salt;
98+
result.lib = 'original';
99+
return JSON.stringify(result);
100+
};
101+
102+
/**
103+
* Decrypts an encrypted JS object (encryptedString)
104+
* using a password (and AES decryption with native libraries)
105+
*
106+
* @param {string} password - Password used for decryption
107+
* @param {string} encryptedString - String to decrypt
108+
* @returns - Promise resolving to decrypted data object
109+
*/
110+
decrypt = async ({
111+
password,
112+
encryptedString,
113+
}: {
114+
password: string;
115+
encryptedString: string;
116+
}) => {
117+
const encryptedData = JSON.parse(encryptedString);
118+
const key = await this._keyFromPassword({
119+
password,
120+
salt: encryptedData.salt,
121+
lib: encryptedData.lib,
122+
});
123+
const data = await this._decryptWithKey({
124+
encryptedData,
125+
key,
126+
lib: encryptedData.lib,
127+
});
128+
return JSON.parse(data);
129+
};
130+
}
131+
132+
// eslint-disable-next-line import/prefer-default-export
133+
export { Encryptor };

app/core/Encryptor/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Encryptor } from './Encryptor';
2+
3+
export default Encryptor;

0 commit comments

Comments
 (0)