Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 1x 1x 1x 1x 16x 16x 16x 16x 16x 16x 16x 1x 8x 8x 8x 8x 8x 8x 8x 8x 2x 6x 1x 1x | /* * Copyright (c) 2019 NEM Foundation * * Licensed under the Apache License, Version 2.0 (the "License "); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const CryptoJS = require("crypto-js"); // internal dependencies import { EncryptedPayload, } from '../../index'; /** * Class `EncryptionService` describes a high level service * for encryption/decryption of data. * * Implemented algorithms for encryption/decryption include: * - AES with PBKDF2 (Password-Based Key Derivation Function) * * @since 0.3.0 */ class EncryptionService { /** * The `encrypt` method will encrypt given `data` raw string * with given `password` password. * * First we generate a random salt of 32 bytes, then we iterate * 2000 times with PBKDF2 and encrypt with AES. * * @param password {string} * @param data {string} */ public static encrypt( data: string, password: string, ): EncryptedPayload { // create random salt (32 bytes) const salt = CryptoJS.lib.WordArray.random(32); // derive key of 8 bytes with 2000 iterations of PBKDF2 const key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 2000, }); // create encryption input vector of 16 bytes (iv) const iv = CryptoJS.lib.WordArray.random(16); // encrypt with AES const encrypted = CryptoJS.AES.encrypt(data, key, { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC, }); // create our `EncryptedPayload` (16 bytes iv as hex || cipher text) const ciphertext = iv.toString() + encrypted.toString(); const used_salt = CryptoJS.enc.Hex.stringify(salt); return new EncryptedPayload(ciphertext, used_salt); } /** * AES_PBKF2_decryption will decrypt privateKey with provided password * @param payload the object containing the encrypted data. * @param password the password to decrypt the encrypted data */ public static decrypt( payload: EncryptedPayload, password: string, ): string { // read payload const salt = CryptoJS.enc.Hex.parse(payload.salt); const priv = payload.ciphertext; // read encryption configuration const iv: string = CryptoJS.enc.Hex.parse(priv.substr(0, 32)); const cipher: string = priv.substr(32); // re-generate key (PBKDF2) const key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 2000, }); // decrypt and return const decrypted = CryptoJS.AES.decrypt(cipher, key, { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC, }); const decryptedText = decrypted.toString(CryptoJS.enc.Utf8); if (!decryptedText){ // This happens sometimes when the wrong password is used instead of an Error. throw Error('Empty decrypted text!!'); } return decryptedText; } } export {EncryptionService}; |