Created
December 11, 2018 13:42
-
-
Save lalilaloe/02ff061ce417a0866c70e0bcb708c3ac to your computer and use it in GitHub Desktop.
EncryptRequestHandler using crypto libary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as forge from "node-forge"; | |
import BunqJSClient from "../BunqJSClient"; | |
import Session from "../Session"; | |
import LoggerInterface from "../Interfaces/LoggerInterface"; | |
import Request from "./Request"; | |
var crypto = require('crypto'); | |
import ApiAdapterOptions from "../Types/ApiAdapterOptions"; | |
const HEADER_CLIENT_ENCRYPTION_HMAC = "X-Bunq-Client-Encryption-Hmac"; | |
const HEADER_CLIENT_ENCRYPTION_IV = "X-Bunq-Client-Encryption-Iv"; | |
const HEADER_CLIENT_ENCRYPTION_KEY = "X-Bunq-Client-Encryption-Key"; | |
const AES_ENCRYPTION_METHOD = 'aes-256-cbc'; | |
const AES_KEY_LENGTH = 32; | |
const HMAC_ALGORITHM = 'sha1'; | |
const INITIATION_VECTOR_LENGTH = 16; | |
export default class EncryptRequestHandler { | |
public Session: Session; | |
public logger: LoggerInterface; | |
public BunqJSClient: BunqJSClient; | |
constructor(Session: Session, loggerInterface: LoggerInterface, BunqJSClient: BunqJSClient) { | |
this.BunqJSClient = BunqJSClient; | |
this.Session = Session; | |
this.logger = loggerInterface; | |
} | |
/** | |
* Signs a request using our privatekey | |
* @param {Request} request | |
* @param {ApiAdapterOptions} options | |
* @returns {Promise<string>} | |
*/ | |
public async encryptRequest(request: Request, options: ApiAdapterOptions): Promise<void> { | |
const body = JSON.stringify(request.requestConfig.data); | |
const key = crypto.randomBytes(AES_KEY_LENGTH); | |
const iv = crypto.randomBytes(INITIATION_VECTOR_LENGTH); | |
const encryptedAesKey = new Buffer(this.encryptPublic(key, this.Session.serverPublicKey), 'binary'); | |
const encryptedBody = new Buffer(this.encrypt(body, key, iv), 'binary'); | |
const hmacBuffer = new Buffer(this.hmac(key, iv + encryptedBody), 'binary'); | |
// set new body | |
request.setData(encryptedBody.toString('base64')); | |
// disable request transform | |
request.setOptions("transformRequest", data => { | |
// don't transform the data, return it directly | |
return data; | |
}); | |
// set headers | |
request.setHeader("Content-Type", "multipart/form-data"); | |
request.setHeader(HEADER_CLIENT_ENCRYPTION_HMAC, hmacBuffer.toString('base64')); | |
request.setHeader(HEADER_CLIENT_ENCRYPTION_IV, iv.toString('base64')); | |
request.setHeader(HEADER_CLIENT_ENCRYPTION_KEY, encryptedAesKey.toString('base64')); | |
} | |
private hmac(key, content) { | |
var hmac = crypto.createHmac(HMAC_ALGORITHM, key); | |
hmac.update(content); | |
return hmac.digest('binary'); | |
} | |
private encrypt(text, key, iv) { | |
var cipher = crypto.createCipheriv(AES_ENCRYPTION_METHOD, key, iv) | |
var crypted = cipher.update(text, 'utf8', 'binary') | |
crypted += cipher.final('binary'); | |
return crypted; | |
} | |
private encryptPublic(key, publicKey) { | |
const messageDigest = forge.md.sha256.create(); | |
messageDigest.update(key, 'utf8') | |
return publicKey.encrypt(messageDigest.digest().getBytes()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment