68 lines
1.4 KiB
TypeScript
68 lines
1.4 KiB
TypeScript
import {
|
|
constants,
|
|
generateKeyPairSync,
|
|
privateDecrypt,
|
|
} from 'node:crypto';
|
|
|
|
import { HttpStatus, Injectable } from '@nestjs/common';
|
|
import { throwVbenError } from '@/common';
|
|
|
|
@Injectable()
|
|
export class AdminPasswordCryptoService {
|
|
private readonly privateKey: string;
|
|
|
|
private readonly publicKey: string;
|
|
|
|
constructor() {
|
|
const keyPair = generateKeyPairSync('rsa', {
|
|
modulusLength: 2048,
|
|
privateKeyEncoding: {
|
|
format: 'pem',
|
|
type: 'pkcs8',
|
|
},
|
|
publicKeyEncoding: {
|
|
format: 'pem',
|
|
type: 'spki',
|
|
},
|
|
});
|
|
|
|
this.privateKey = keyPair.privateKey;
|
|
this.publicKey = keyPair.publicKey;
|
|
}
|
|
|
|
getPublicKey() {
|
|
return {
|
|
algorithm: 'RSA-OAEP' as const,
|
|
hash: 'SHA-256' as const,
|
|
publicKey: this.publicKey,
|
|
};
|
|
}
|
|
|
|
decryptPassword(encryptedPassword?: string) {
|
|
if (!encryptedPassword) {
|
|
throwVbenError(
|
|
'Encrypted password is required',
|
|
HttpStatus.BAD_REQUEST,
|
|
'BadRequestException',
|
|
);
|
|
}
|
|
|
|
try {
|
|
return privateDecrypt(
|
|
{
|
|
key: this.privateKey,
|
|
oaepHash: 'sha256',
|
|
padding: constants.RSA_PKCS1_OAEP_PADDING,
|
|
},
|
|
Buffer.from(encryptedPassword, 'base64'),
|
|
).toString('utf8');
|
|
} catch {
|
|
throwVbenError(
|
|
'Password decrypt failed',
|
|
HttpStatus.BAD_REQUEST,
|
|
'BadRequestException',
|
|
);
|
|
}
|
|
}
|
|
}
|