mirror of
https://github.com/cupcakearmy/occulto.git
synced 2025-09-05 22:20:41 +00:00
initial commit
This commit is contained in:
164
src/AES.ts
Normal file
164
src/AES.ts
Normal 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
39
src/RSA.ts
Normal 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
4
src/Util.ts
Normal 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
27
src/index.ts
Normal 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,
|
||||
}
|
Reference in New Issue
Block a user