encryption interface

This commit is contained in:
joseji 2022-11-09 10:46:01 +01:00
parent 73ced2291e
commit ac6b8e666f
6 changed files with 110 additions and 2 deletions

View File

@ -0,0 +1,12 @@
import { registerEnumType } from 'type-graphql'
export enum PasswordEncryptionType {
EMAIL = 0,
ONE_TIME = 1,
GRADIDO_ID = 2,
}
registerEnumType(PasswordEncryptionType, {
name: 'PasswordEncryptionType', // this one is mandatory
description: 'Type of the password encryption', // this one is optional
})

View File

@ -0,0 +1,19 @@
import { User } from '@entity/User'
import { PasswordEncryptr } from './PasswordEncryptr'
import { SecretKeyCryptographyCreateKey } from './EncryptorUtils'
export class EmailEncryptr implements PasswordEncryptr {
async encryptPassword(dbUser: User, password: string): Promise<bigint> {
const keyBuffer = SecretKeyCryptographyCreateKey(dbUser.emailContact.email, password) // return short and long hash
const passwordHash = keyBuffer[0].readBigUInt64LE()
return passwordHash
}
async verifyPassword(dbUser: User, password: string): Promise<boolean> {
if (BigInt(password) !== (await this.encryptPassword(dbUser, dbUser.password.toString()))) {
return false
}
return true
}
}

View File

@ -0,0 +1,52 @@
import CONFIG from '@/config'
import { backendLogger as logger } from '@/server/logger'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const sodium = require('sodium-native')
// We will reuse this for changePassword
export const isValidPassword = (password: string): boolean => {
return !!password.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9 \\t\\n\\r]).{8,}$/)
}
export const SecretKeyCryptographyCreateKey = (salt: string, password: string): Buffer[] => {
logger.trace('SecretKeyCryptographyCreateKey...')
const configLoginAppSecret = Buffer.from(CONFIG.LOGIN_APP_SECRET, 'hex')
const configLoginServerKey = Buffer.from(CONFIG.LOGIN_SERVER_KEY, 'hex')
if (configLoginServerKey.length !== sodium.crypto_shorthash_KEYBYTES) {
logger.error(
`ServerKey has an invalid size. The size must be ${sodium.crypto_shorthash_KEYBYTES} bytes.`,
)
throw new Error(
`ServerKey has an invalid size. The size must be ${sodium.crypto_shorthash_KEYBYTES} bytes.`,
)
}
const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES)
sodium.crypto_hash_sha512_init(state)
sodium.crypto_hash_sha512_update(state, Buffer.from(salt))
sodium.crypto_hash_sha512_update(state, configLoginAppSecret)
const hash = Buffer.alloc(sodium.crypto_hash_sha512_BYTES)
sodium.crypto_hash_sha512_final(state, hash)
const encryptionKey = Buffer.alloc(sodium.crypto_box_SEEDBYTES)
const opsLimit = 10
const memLimit = 33554432
const algo = 2
sodium.crypto_pwhash(
encryptionKey,
Buffer.from(password),
hash.slice(0, sodium.crypto_pwhash_SALTBYTES),
opsLimit,
memLimit,
algo,
)
const encryptionKeyHash = Buffer.alloc(sodium.crypto_shorthash_BYTES)
sodium.crypto_shorthash(encryptionKeyHash, encryptionKey, configLoginServerKey)
logger.debug(
`SecretKeyCryptographyCreateKey...successful: encryptionKeyHash= ${encryptionKeyHash}, encryptionKey= ${encryptionKey}`,
)
return [encryptionKeyHash, encryptionKey]
}

View File

@ -0,0 +1,19 @@
import { User } from '@entity/User'
import { SecretKeyCryptographyCreateKey } from './EncryptorUtils'
import { PasswordEncryptr } from './PasswordEncryptr'
export class GradidoIDEncryptr implements PasswordEncryptr {
async encryptPassword(dbUser: User, password: string): Promise<bigint> {
const keyBuffer = SecretKeyCryptographyCreateKey(dbUser.gradidoID, password) // return short and long hash
const passwordHash = keyBuffer[0].readBigUInt64LE()
return passwordHash
}
async verifyPassword(dbUser: User, password: string): Promise<boolean> {
if (BigInt(password) !== (await this.encryptPassword(dbUser, dbUser.password.toString()))) {
return false
}
return true
}
}

View File

@ -0,0 +1,6 @@
import { User } from '@entity/User'
export interface PasswordEncryptr {
encryptPassword(dbUser: User, password: string): Promise<bigint>
verifyPassword(dbUser: User, password: string): Promise<boolean>
}

View File

@ -1,4 +1,4 @@
/* MIGRATION TO ADD GRADIDO_ID /* MIGRATION TO ADD ENCRYPTION TO PASSWORDS
* *
* This migration adds and renames columns to and in the table `users` * This migration adds and renames columns to and in the table `users`
*/ */