'RSA library with angular
Hello I am trying to implement encryption in my application. I am using angular (angular-4) for the frontend and node js for the backend. Communication is done through socket.io through custom commands. But basically what I am stuck at is finding an appropriate library for RSA encryption in client side. client will first request server for an RSA public key. Server responds with key but now I cannot find any library suitable to encrypt data with RSA using this public key. I have tried node-rsa. Following is a code sn
import * as NodeRSA from 'node-rsa';
@Injectable()
export class SecurityService {
RSA: any
initializeRSA(key: string) {
this.RSA = new NodeRSA();
this.RSA.importKey(key)
console.log(this.RSA.encrypt('Hello World'));
}
But I am receiving this error.
Error during encryption. Original error: TypeError: crypt.createHash is not a function
at NodeRSA.webpackJsonp.../../../../node-rsa/src/NodeRSA.js.module.exports.NodeRSA.$$encrypt
Help would be very much appreciated.
Solution 1:[1]
I used CryptoJS for AES encoding. And, node-forge for RSA encoding.
Part 1:
npm install --save node-forge
npm install --save crypto-js
npm install --save @types/crypto-js
npm install --save @types/node-forge
import { Injectable } from '@angular/core';
import * as forge from 'node-forge';
import * as CryptoJS from 'crypto-js';
/*
* forge: For RSA encryption
* CryptoJS: For AES encryption
*/
export interface AESKeys {
iv: string;
key: string;
}
@Injectable()
export class MyEncryptService {
constructor() {}
/**
* @param randomWordArray
* AES Key or IV generated in this service as Hex string
* @param pemKey
* the Public Key from "get_rsa_key" endpoint (separate http service)
* @returns
* a RSA encrypted random key/iv
*/
public getBase64Encrypted(randomWordArray, pemKey): string {
const pk = forge.pki.publicKeyFromPem(pemKey);
return forge.util.encode64(pk.encrypt(forge.util.hexToBytes(randomWordArray)));
}
/**
* @param text
* field input text
* @param randomKey
* random key generated from word array
* @param randomIv
* random iv generated from word array
* @returns
* encrypted text
*/
public encrypted(text, randomKey, randomIv): string {
const cipherText: any = CryptoJS.AES.encrypt(text, randomKey, {
iv: randomIv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.NoPadding
});
return cipherText.toString();
}
/**
* @param wordLength
* normally: IV = 16 or Key = 32
* @returns
* randomly generated 128bit (IV) or 256bit (Key) word array
*/
public getWordArray(wordLength): string {
return CryptoJS.lib.WordArray.random(wordLength);
}
}
Solution 2:[2]
What you can do if you want to stay with the very good node-rsa library it to eject ng-cli from your project and configure webpack to automatically polyfill the nodejs crypto module with the crypto-browserify library.
First, eject ng-cli from your project (you will need to run yarn build
or npm run build
to build your project and you won't be able anymore to use ng build
) :
ng eject
Then you need to add this data to the webpack.config.js
file created by the ejection process :
"node": {
...
"crypto": true,
...
}
This will tell webpack to polyfill the crypto
module.
I will soon dive into how to keep ng-cli
and have a correct polyfilling behavior...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Arnaud Tournier |