Skip to content

Commit

Permalink
Merge pull request #23 from Cryptographic-API-Services/#22-password-h…
Browse files Browse the repository at this point in the history
…ashing-threading

#22 password hashing threading
  • Loading branch information
WingZer0o authored May 12, 2024
2 parents 9d1eb3d + 90159d1 commit a45b4e3
Show file tree
Hide file tree
Showing 14 changed files with 375 additions and 25 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ sha3 = "0.10.8"
x25519-dalek = {version = "2.0.0", features = ["static_secrets"]}
rand_07 = { package = "rand", version = "0.7.0" }
ascon-aead = "0.4.2"
rayon = "1.10.0"

[profile.dev.package.num-bigint-dig]
opt-level = 3
Expand Down
99 changes: 99 additions & 0 deletions docs/EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,105 @@ const ciphertext = aesWrapper.aes128Encrypt(aesKey, aesNonce, tohashBytes);
const plaintxt = aesWrapper.aes128Decrypt(aesKey, aesNonce, ciphertext);
```

### Asymmetric
-RSA
```typescript
const rsaWrapper: RSAWrapper = new RSAWrapper();
const keys: RsaKeyPairResult = rsaWrapper.generateKeys(4096);
const tohashed: string = "This is my array to encrypt";
const encoder = new TextEncoder();
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
const ciphertext = rsaWrapper.encrypt(keys.publicKey, tohashBytes);
const plaintext = rsaWrapper.decrypt(keys.privateKey, ciphertext);
```


### Digital Signature
-ED25519 SHA
```typescript
const shaDsWrapper = DigitalSignatureFactory.get(DigitalSignatureType.SHA256)
const toHash: string = "This is my array to encrypt";
const encoder = new TextEncoder();
const toHashBytes: Array<number> = Array.from(encoder.encode(toHash));
const dsResult = shaDsWrapper.createED25519(toHashBytes);
const verify = shaDsWrapper.verifyED25519(dsResult.publicKey, toHashBytes, dsResult.signature);
```

-RSA SHA
```typescript
const shaDsWrapper = DigitalSignatureFactory.get(DigitalSignatureType.SHA512)
const tohashed: string = "This is my array to encrypt";
const notOriginal: string = "This is not a fun time";
const encoder = new TextEncoder();
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
const badBytes: Array<number> = Array.from(encoder.encode(notOriginal));
const dsResult: RSADigitalSignatureResult = shaDsWrapper.createRsa(4096, tohashBytes);
const verify = shaDsWrapper.verifyRSa(dsResult.publicKey, badBytes, dsResult.signature);
```


### Hashers
-SHA3 512
```typescript
const wrapper = new SHAWrapper();
const tohashed: string = "This is my array to hash";
const encoder = new TextEncoder();
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
const hashed = wrapper.hash512(tohashBytes);
```

-SHA3 256
```typescript
const wrapper = new SHAWrapper();
const tohashed: string = "This is my array to hash";
const encoder = new TextEncoder();
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
const hashed = wrapper.hash256(tohashBytes);
```

### Hybrid Encryption
-AES/RSA Encryption
```typescript
const hybridWrapper = new HybridEncryptionWrapper();
let initalizer = new AESRSAHybridInitializer(128, 4096);
const tohashed: string = "This is my encrypt text for rsa hybrid";
const encoder = new TextEncoder();
const toEncrypt: Array<number> = Array.from(encoder.encode(tohashed));
let result: AesRsaHybridEncryptResult = hybridWrapper.encrypt(toEncrypt, initalizer);
let plaintext: Array<number> = hybridWrapper.decrypt(initalizer.rsaKeyPair.privateKey, result);
```

### Key Exchange
-X25519
```typescript
const wrapper = new X25519Wrapper();
const alice = wrapper.generateSecretAndPublicKey();
const bob = wrapper.generateSecretAndPublicKey();

const alice_shared_secret = wrapper.generateSharedSecret(
alice.secretKey,
bob.publicKey,
);
const bob_shared_secret = wrapper.generateSharedSecret(
bob.secretKey,
alice.publicKey,
);

var result = areEqual(alice_shared_secret, bob_shared_secret);
```

### Sponges
-Ascon 128
```typescript
const wrapper: AsconWrapper = new AsconWrapper();
const key: Array<number> = wrapper.ascon128Key();
const nonce: Array<number> = wrapper.ascon128Nonce();
const tohashed: string = "This is my array to encrypt";
const encoder = new TextEncoder();
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
const ciphertext = wrapper.ascon128Encrypt(key, nonce, tohashBytes);
const plaintext = wrapper.ascon128Decrypt(key, nonce, ciphertext);
```

### Passwords
- BCrypt
Expand Down
6 changes: 6 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
/* auto-generated by NAPI-RS */

export function argon2Hash(password: string): string
export function argon2HashThreadPool(password: string): string
export function argon2Verify(hashedPassword: string, passwordToVerify: string): boolean
export function argon2VerifyThreadpool(hashedPassword: string, passwordToVerify: string): boolean
export function bcryptHash(passwordToHash: string): string
export function bcryptHashThreadpool(passwordToHash: string): string
export function bcryptVerify(hashedPassword: string, passwordToVerify: string): boolean
export function bcryptVerifyThreadpool(passwordToHash: string, passwordToVerify: string): boolean
export function scryptHash(passwordToHash: string): string
export function scryptVerify(hashedPassword: string, passwordToVerify: string): boolean
export function scryptHashThreadpool(passwordToHash: string): string
export function scryptVerifyThreadpool(hashedPassword: string, passwordToVerify: string): boolean
export function sha512(dataToHash: Array<number>): Array<number>
export function sha512Verify(dataToHash: Array<number>, dataToVerify: Array<number>): boolean
export function sha256(dataToHash: Array<number>): Array<number>
Expand Down
Binary file modified index.node
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

{
"name": "cas-typescript-sdk",
"version": "1.0.19",
"version": "1.0.22",
"description": "",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
28 changes: 24 additions & 4 deletions src-ts/password-hashers/argon2-wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
import {argon2Hash, argon2Verify} from "./../../index";
import { IPasswordHasherBase} from "./password-hasher-base";
import { argon2Hash, argon2HashThreadPool, argon2Verify, argon2VerifyThreadpool } from "./../../index";
import { IPasswordHasherBase } from "./password-hasher-base";

export class Argon2Wrapper implements IPasswordHasherBase {

verifyThreadPool(hashedPassword: string, passwordToCheck: string): boolean {
if (!hashedPassword) {
throw new Error("You must provide a password to verify with Argon2");
}
if (!passwordToCheck) {
throw new Error("You must provide a password to check to verify with Argon2");
}
return argon2VerifyThreadpool(hashedPassword, passwordToCheck);
}

public hashPasswordThreadPool(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Argon2");
}
return argon2HashThreadPool(password);
}

public hashPassword(password: string): string {
if (!password){
if (!password) {
throw new Error("You must provide a password to hash with Argon2");
}
return argon2Hash(password);
}

public verify(hashedPassword: string, passwordToVerify: string): boolean {
if (!hashedPassword || !passwordToVerify) {
throw new Error("You must provide a hashed password and a plaintext password to verify with Argon2");
throw new Error(
"You must provide a hashed password and a plaintext password to verify with Argon2",
);
}
return argon2Verify(hashedPassword, passwordToVerify);
}
Expand Down
19 changes: 18 additions & 1 deletion src-ts/password-hashers/bcrypt-wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
import { IPasswordHasherBase } from "./password-hasher-base";
import { bcryptHash, bcryptVerify } from "./../../index";
import { bcryptHash, bcryptHashThreadpool, bcryptVerify, bcryptVerifyThreadpool } from "./../../index";

export class BCryptWrapper implements IPasswordHasherBase {

verifyThreadPool(hashedPassword: string, passwordToCheck: string): boolean {
if (!hashedPassword || !passwordToCheck) {
throw new Error(
"You must provide a hashed password and a plaintext password to verify with Argon2",
);
}
return bcryptVerifyThreadpool(hashedPassword, passwordToCheck);
}

public hashPasswordThreadPool(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Argon2");
}
return bcryptHashThreadpool(password);
}

public hashPassword(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Argon2");
Expand Down
2 changes: 2 additions & 0 deletions src-ts/password-hashers/password-hasher-base.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export interface IPasswordHasherBase {
hashPassword(password: string): string;
verify(hashedPassword: string, passwordToVerify: string): boolean;
hashPasswordThreadPool(password: string): string;
verifyThreadPool(hashedPassword: string, passwordToCheck: string): boolean;
}
47 changes: 32 additions & 15 deletions src-ts/password-hashers/scrypt-wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
import { scryptHash, scryptVerify } from "../../index";
import { scryptHash, scryptHashThreadpool, scryptVerify, scryptVerifyThreadpool } from "../../index";
import { IPasswordHasherBase } from "./password-hasher-base";

export class ScryptWrapper implements IPasswordHasherBase {

public hashPassword(password: string): string {
if (!password){
throw new Error("You must provide a password to hash with Scrypt");
}
return scryptHash(password);
}

public verify(hashedPassword: string, passwordToVerify: string): boolean {
if (!hashedPassword || !passwordToVerify) {
throw new Error("You must provide a hashed password and a plaintext password to verify with Scrypt");
}
return scryptVerify(hashedPassword, passwordToVerify);
}
verifyThreadPool(hashedPassword: string, passwordToCheck: string): boolean {
if (!hashedPassword || !passwordToCheck) {
throw new Error(
"You must provide a hashed password and a plaintext password to verify with Scrypt",
);
}
return scryptVerifyThreadpool(hashedPassword, passwordToCheck);
}

}
hashPasswordThreadPool(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Scrypt");
}
return scryptHashThreadpool(password);
}

public hashPassword(password: string): string {
if (!password) {
throw new Error("You must provide a password to hash with Scrypt");
}
return scryptHash(password);
}

public verify(hashedPassword: string, passwordToVerify: string): boolean {
if (!hashedPassword || !passwordToVerify) {
throw new Error(
"You must provide a hashed password and a plaintext password to verify with Scrypt",
);
}
return scryptVerify(hashedPassword, passwordToVerify);
}
}
21 changes: 21 additions & 0 deletions src-ts/symmetric/aes-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,32 @@ import {
aesNonce,
} from "../../index";

/**
* @description A wrapper class that contains methods to construct keys, nonces, and methods to encrypt and decrypt with AES-128-GCM and AES-256-GCM
*
* @example
* ```ts
* const nonce = aesWrapper.generateAESNonce();
const key = aesWrapper.aes128Key();
const textEncoder = new TextEncoder();
const array = Array.from(textEncoder.encode("Hello World"));
const encrypted = aesWrapper.aes128Encrypt(key, nonce, array);
* ```
*/
export class AESWrapper {

/**
* @description Generates a 128 bit AES key
* @returns returns a 128 bit AES key
*/
public aes128Key(): Array<number> {
return aes128Key();
}

/**
* @description Generates a 256 bit AES key
* @returns returns a 256 bit AES key
*/
public aes256Key(): Array<number> {
return aes256Key();
}
Expand Down
41 changes: 40 additions & 1 deletion src/password_hashers/argon2.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::net::ToSocketAddrs;

use napi_derive::napi;

Expand All @@ -7,6 +6,8 @@ use argon2::{
Argon2, PasswordHash, PasswordHasher, PasswordVerifier,
};

use crate::symmetric::aes::CASAES128;

use super::cas_password_hasher::CASPasswordHasher;

pub struct CASArgon;
Expand Down Expand Up @@ -35,11 +36,49 @@ pub fn argon2_hash(password: String) -> String {
return <CASArgon as CASPasswordHasher>::hash_password(password);
}

#[napi]
pub fn argon2_hash_thread_pool(password: String) -> String {
let (sender, receiver) = std::sync::mpsc::channel();
rayon::spawn(move || {
let hash_result = <CASArgon as CASPasswordHasher>::hash_password(password);
sender.send(hash_result);
});
let result = receiver.recv().unwrap();
result
}

#[napi]
pub fn argon2_verify(hashed_password: String, password_to_verify: String) -> bool {
return <CASArgon as CASPasswordHasher>::verify_password(hashed_password, password_to_verify);
}

#[napi]
pub fn argon2_verify_threadpool(hashed_password: String, password_to_verify: String) -> bool {
let (sender, receiver) = std::sync::mpsc::channel();
rayon::spawn(move || {
let verify_result = <CASArgon as CASPasswordHasher>::verify_password(hashed_password, password_to_verify);
sender.send(verify_result);
});
let result = receiver.recv().unwrap();
result
}

#[test]
pub fn argon2_hash_threadpool_test() {
let password = "ThisIsNotMyPasswolrd".to_string();
let hashed = argon2_hash_thread_pool(password.clone());
assert_ne!(password, hashed);
}

#[test]
pub fn argon2_verify_threadpool_test() {
let password = "ThisIsNotMyPasswolrd".to_string();
let passwordToCheck = "ThisIsNotMyPasswolrd".to_string();
let hashed = argon2_hash_thread_pool(password);
let result = argon2_verify_threadpool(hashed, passwordToCheck);
assert_eq!(result, true);
}

#[test]
pub fn argon2_hash_test() {
let password = "ThisIsNotMyPasswolrd".to_string();
Expand Down
Loading

0 comments on commit a45b4e3

Please sign in to comment.