initial commit

This commit is contained in:
cupcakearmy
2019-03-30 20:50:04 +01:00
commit c1e4f4b1aa
10 changed files with 536 additions and 0 deletions

164
src/AES.ts Normal file
View File

@@ -0,0 +1,164 @@
import forge from 'node-forge'
export enum Ciphers {
AES_256_GCM,
AES_192_GCM,
AES_128_GCM,
AES_256_CTR,
AES_192_CTR,
AES_128_CTR,
AES_256_CBC,
AES_192_CBC,
AES_128_CBC,
}
type CipherConfig = {
alg: forge.cipher.Algorithm,
saltSize: number
keySize: number
tagSize: number
it: number
}
type EncryptedItem = {
alg: forge.cipher.Algorithm,
data: string,
keySize: number,
iv: string,
it: number
salt: string,
tag: string,
tagSize: number,
}
export default class AES {
static Ciphers = Ciphers
static encrypt(data: string, key: string, type: Ciphers = Ciphers.AES_256_GCM): string {
const { alg, it, keySize, saltSize, tagSize } = AES.getCipherConfig(type)
const salt = forge.random.getBytesSync(saltSize)
const iv = forge.random.getBytesSync(keySize)
const cipher = forge.cipher.createCipher(
alg,
forge.pkcs5.pbkdf2(key, salt, it, keySize),
)
cipher.start({
iv,
tagLength: tagSize,
})
cipher.update(forge.util.createBuffer(data))
cipher.finish()
const encrypted: EncryptedItem = {
alg,
data: forge.util.hexToBytes(cipher.output.toHex()),
keySize,
iv,
it,
salt,
tag: forge.util.hexToBytes(cipher.mode.tag.toHex()),
tagSize,
}
return Buffer.from(JSON.stringify(encrypted)).toString('base64')
}
static decrypt(e: string, key: string): string {
const { alg, data, keySize, iv, it, salt, tag, tagSize }: EncryptedItem = JSON.parse(Buffer.from(e, 'base64').toString())
const cipher = forge.cipher.createCipher(
alg,
forge.pkcs5.pbkdf2(key, salt, it, keySize),
)
cipher.start({
iv,
tag: new forge.util.ByteStringBuffer(tag),
tagLength: tagSize,
})
cipher.update(new forge.util.ByteStringBuffer(data))
cipher.finish()
return cipher.output.toString()
}
private static getCipherConfig = (type: Ciphers): CipherConfig => {
switch (type) {
case Ciphers.AES_128_GCM:
return {
alg: 'AES-GCM',
saltSize: 128,
keySize: 16,
tagSize: 128,
it: 2 ** 12,
}
case Ciphers.AES_192_GCM:
return {
alg: 'AES-GCM',
saltSize: 128,
keySize: 24,
tagSize: 128,
it: 2 ** 12,
}
case Ciphers.AES_256_GCM:
return {
alg: 'AES-GCM',
saltSize: 128,
keySize: 32,
tagSize: 128,
it: 2 ** 12,
}
case Ciphers.AES_128_CBC:
return {
alg: 'AES-CBC',
saltSize: 128,
keySize: 16,
tagSize: 128,
it: 2 ** 12,
}
case Ciphers.AES_192_CBC:
return {
alg: 'AES-CBC',
saltSize: 128,
keySize: 24,
tagSize: 128,
it: 2 ** 12,
}
case Ciphers.AES_256_CBC:
return {
alg: 'AES-CBC',
saltSize: 128,
keySize: 32,
tagSize: 128,
it: 2 ** 12,
}
case Ciphers.AES_128_CTR:
return {
alg: 'AES-CTR',
saltSize: 128,
keySize: 16,
tagSize: 128,
it: 2 ** 12,
}
case Ciphers.AES_192_CTR:
return {
alg: 'AES-CTR',
saltSize: 128,
keySize: 24,
tagSize: 128,
it: 2 ** 12,
}
case Ciphers.AES_256_CTR:
return {
alg: 'AES-CTR',
saltSize: 128,
keySize: 32,
tagSize: 128,
it: 2 ** 12,
}
}
}
}

39
src/RSA.ts Normal file
View File

@@ -0,0 +1,39 @@
import forge from 'node-forge'
import { Base64 } from './Util'
type PrivateKey = string
type PublicKey = string
export type KeyPair = {
pub: PublicKey
prv: PrivateKey
}
export default class RSA {
static gen = (size: number = 2 ** 12): Promise<KeyPair> => new Promise<KeyPair>((resolve, reject) => {
forge.pki.rsa.generateKeyPair({ bits: size }, function (err, keypair) {
if (err) reject()
else resolve({
pub: forge.pki.publicKeyToPem(keypair.publicKey),
prv: forge.pki.privateKeyToPem(keypair.privateKey),
})
})
})
static encrypt(data: string, key: PublicKey): string {
const obj = forge.pki.publicKeyFromPem(key)
if (obj instanceof ArrayBuffer) throw new Error()
return Base64.encode(obj.encrypt(data))
}
static decrypt(data: string, key: PrivateKey): string {
const obj = forge.pki.privateKeyFromPem(key)
if (obj instanceof ArrayBuffer) throw new Error()
return obj.decrypt(Base64.decode(data))
}
}

4
src/Util.ts Normal file
View File

@@ -0,0 +1,4 @@
export class Base64 {
static encode = (s: string): string => Buffer.from(s).toString('base64')
static decode = (s: string): string => Buffer.from(s, 'base64').toString()
}

27
src/index.ts Normal file
View File

@@ -0,0 +1,27 @@
import AES from './AES'
import RSA from './RSA'
//
// (async () => {
//
// const text = `lorem ipsums`
// const key = `test`
//
// // Asymetric
// const pair = await RSA.gen()
// const ae = RSA.encrypt(text, pair.pub)
// console.log(ae)
// const ad = RSA.decrypt(ae, pair.prv)
// console.log(ad)
//
// // Symmetric
// const se = AES.encrypt(text, key, AES.Ciphers.AES_256_GCM)
// console.log(se)
// const sd = AES.decrypt(se, key)
// console.log(sd)
//
// })()
export default {
RSA,
AES,
}