cas-typescript-sdk 1.0.13 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +1 -1
  2. package/build-node.sh +2 -0
  3. package/index.d.ts +7 -0
  4. package/index.node +0 -0
  5. package/lib/hybrid/hybrid-encryption-wrapper.d.ts +9 -0
  6. package/lib/hybrid/hybrid-encryption-wrapper.js +30 -0
  7. package/lib/hybrid/index.d.ts +4 -0
  8. package/lib/hybrid/index.js +9 -0
  9. package/lib/hybrid/types/aes-rsa-hybird-encrypt-result.d.ts +7 -0
  10. package/lib/hybrid/types/aes-rsa-hybird-encrypt-result.js +16 -0
  11. package/lib/hybrid/types/aes-rsa-hybrid-initializer.d.ts +8 -0
  12. package/lib/hybrid/types/aes-rsa-hybrid-initializer.js +25 -0
  13. package/lib/index.d.ts +3 -2
  14. package/lib/index.js +8 -4
  15. package/lib/symmetric/aes-wrapper.d.ts +3 -0
  16. package/lib/symmetric/aes-wrapper.js +6 -0
  17. package/package.json +6 -2
  18. package/src/symmetric/aes.rs +36 -1
  19. package/src/symmetric/cas_symmetric_encryption.rs +9 -0
  20. package/src-ts/hybrid/hybrid-encryption-wrapper.ts +64 -0
  21. package/src-ts/hybrid/index.ts +9 -0
  22. package/src-ts/hybrid/types/aes-rsa-hybird-encrypt-result.ts +13 -0
  23. package/src-ts/hybrid/types/aes-rsa-hybrid-initializer.ts +24 -0
  24. package/src-ts/index.ts +12 -4
  25. package/src-ts/symmetric/aes-wrapper.ts +11 -0
  26. package/test-ts/hybrid.test.spec.ts +33 -0
  27. package/test-ts/insecure-channel.test.spec.ts +51 -0
  28. package/lib/cas_core_lib.dll +0 -0
  29. package/lib/hashers/IHasherBase.d.ts +0 -6
  30. package/lib/hashers/IHasherBase.js +0 -2
  31. package/lib/hashers/SHAWrapper.d.ts +0 -7
  32. package/lib/hashers/SHAWrapper.js +0 -37
  33. package/lib/libcas_core_lib.so +0 -0
  34. package/lib/password-hashers/types/argon2-hash-thread-result.d.ts +0 -3
  35. package/lib/password-hashers/types/argon2-hash-thread-result.js +0 -11
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # eas-typescript-sdk
1
+ # cas-typescript-sdk
2
2
 
3
3
  Ever wanted all of your most useful cryptograpihc operations in one module and not have to surf documentation for various packages?
4
4
  CAS is here to provide a unified development experience as an abstract layer to the RustCrypto and Dalek-Cryptography suite of algorithms.
package/build-node.sh ADDED
@@ -0,0 +1,2 @@
1
+ #!usr/bin/env bash
2
+ rm -rf lib && tsc
package/index.d.ts CHANGED
@@ -22,6 +22,8 @@ export function aes128Encrypt(aesKey: Array<number>, nonce: Array<number>, plain
22
22
  export function aes128Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number>
23
23
  export function aes256Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number>
24
24
  export function aes256Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number>
25
+ export function aes256KeyFromX25519SharedSecret(sharedSecret: Array<number>): AesKeyFromX25519SharedSecret
26
+ export function aes128KeyFromX25519SharedSecret(sharedSecret: Array<number>): AesKeyFromX25519SharedSecret
25
27
  export function generateRsaKeys(keySize: number): RsaKeyPairResult
26
28
  export function encryptPlaintextRsa(publicKey: string, plaintext: Array<number>): Array<number>
27
29
  export function decryptCiphertextRsa(privateKey: string, ciphertext: Array<number>): Array<number>
@@ -33,6 +35,11 @@ export class X25519SecretPublicKeyResult {
33
35
  secretKey: Array<number>
34
36
  constructor(publicKey: Array<number>, secretKey: Array<number>)
35
37
  }
38
+ export class AesKeyFromX25519SharedSecret {
39
+ aesKey: Array<number>
40
+ aesNonce: Array<number>
41
+ constructor(aesKey: Array<number>, aesNonce: Array<number>)
42
+ }
36
43
  export type RSAKeyPairResult = RsaKeyPairResult
37
44
  export class RsaKeyPairResult {
38
45
  privateKey: string
package/index.node CHANGED
Binary file
@@ -0,0 +1,9 @@
1
+ import { AesRsaHybridEncryptResult } from "./types/aes-rsa-hybird-encrypt-result";
2
+ import { AESRSAHybridInitializer } from "./types/aes-rsa-hybrid-initializer";
3
+ export declare class HybridEncryptionWrapper {
4
+ private aesWrapper;
5
+ private rsaWrapper;
6
+ constructor();
7
+ encrypt(dataToEncrypt: Array<number>, initalizer: AESRSAHybridInitializer): AesRsaHybridEncryptResult;
8
+ decrypt(privateKey: string, encryptResult: AesRsaHybridEncryptResult): Array<number>;
9
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HybridEncryptionWrapper = void 0;
4
+ const asymmetric_1 = require("../asymmetric");
5
+ const symmetric_1 = require("../symmetric");
6
+ const aes_rsa_hybird_encrypt_result_1 = require("./types/aes-rsa-hybird-encrypt-result");
7
+ class HybridEncryptionWrapper {
8
+ aesWrapper;
9
+ rsaWrapper;
10
+ constructor() {
11
+ this.aesWrapper = new symmetric_1.AESWrapper();
12
+ this.rsaWrapper = new asymmetric_1.RSAWrapper();
13
+ }
14
+ encrypt(dataToEncrypt, initalizer) {
15
+ let encryptedData = (initalizer.aesType === 128)
16
+ ? this.aesWrapper.aes128Encrypt(initalizer.aesKey, initalizer.aesNonce, dataToEncrypt)
17
+ : this.aesWrapper.aes256Encrypt(initalizer.aesKey, initalizer.aesNonce, dataToEncrypt);
18
+ let encryptedAesKey = this.rsaWrapper.encrypt(initalizer.rsaKeyPair.publicKey, initalizer.aesKey);
19
+ let result = new aes_rsa_hybird_encrypt_result_1.AesRsaHybridEncryptResult(encryptedData, encryptedAesKey, initalizer.aesType, initalizer.aesNonce);
20
+ return result;
21
+ }
22
+ decrypt(privateKey, encryptResult) {
23
+ let plaintextAesKey = this.rsaWrapper.decrypt(privateKey, encryptResult.encryptedAesKey);
24
+ let plaintext = (encryptResult.aesType === 128)
25
+ ? this.aesWrapper.aes128Decrypt(plaintextAesKey, encryptResult.aesNonce, encryptResult.ciphertext)
26
+ : this.aesWrapper.aes256Decrypt(plaintextAesKey, encryptResult.aesNonce, encryptResult.ciphertext);
27
+ return plaintext;
28
+ }
29
+ }
30
+ exports.HybridEncryptionWrapper = HybridEncryptionWrapper;
@@ -0,0 +1,4 @@
1
+ import { HybridEncryptionWrapper } from "./hybrid-encryption-wrapper";
2
+ import { AesRsaHybridEncryptResult } from "./types/aes-rsa-hybird-encrypt-result";
3
+ import { AESRSAHybridInitializer } from "./types/aes-rsa-hybrid-initializer";
4
+ export { AesRsaHybridEncryptResult, AESRSAHybridInitializer, HybridEncryptionWrapper, };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HybridEncryptionWrapper = exports.AESRSAHybridInitializer = exports.AesRsaHybridEncryptResult = void 0;
4
+ const hybrid_encryption_wrapper_1 = require("./hybrid-encryption-wrapper");
5
+ Object.defineProperty(exports, "HybridEncryptionWrapper", { enumerable: true, get: function () { return hybrid_encryption_wrapper_1.HybridEncryptionWrapper; } });
6
+ const aes_rsa_hybird_encrypt_result_1 = require("./types/aes-rsa-hybird-encrypt-result");
7
+ Object.defineProperty(exports, "AesRsaHybridEncryptResult", { enumerable: true, get: function () { return aes_rsa_hybird_encrypt_result_1.AesRsaHybridEncryptResult; } });
8
+ const aes_rsa_hybrid_initializer_1 = require("./types/aes-rsa-hybrid-initializer");
9
+ Object.defineProperty(exports, "AESRSAHybridInitializer", { enumerable: true, get: function () { return aes_rsa_hybrid_initializer_1.AESRSAHybridInitializer; } });
@@ -0,0 +1,7 @@
1
+ export declare class AesRsaHybridEncryptResult {
2
+ ciphertext: Array<number>;
3
+ encryptedAesKey: Array<number>;
4
+ aesType: number;
5
+ aesNonce: Array<number>;
6
+ constructor(cipherText: Array<number>, encryptAesKey: Array<number>, aesType: number, aesNonce: Array<number>);
7
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AesRsaHybridEncryptResult = void 0;
4
+ class AesRsaHybridEncryptResult {
5
+ ciphertext;
6
+ encryptedAesKey;
7
+ aesType;
8
+ aesNonce;
9
+ constructor(cipherText, encryptAesKey, aesType, aesNonce) {
10
+ this.ciphertext = cipherText;
11
+ this.encryptedAesKey = encryptAesKey;
12
+ this.aesType = aesType;
13
+ this.aesNonce = aesNonce;
14
+ }
15
+ }
16
+ exports.AesRsaHybridEncryptResult = AesRsaHybridEncryptResult;
@@ -0,0 +1,8 @@
1
+ import { RsaKeyPairResult } from "../../..";
2
+ export declare class AESRSAHybridInitializer {
3
+ aesType: number;
4
+ aesKey: Array<number>;
5
+ aesNonce: Array<number>;
6
+ rsaKeyPair: RsaKeyPairResult;
7
+ constructor(aesType: number, rsaSize: number);
8
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AESRSAHybridInitializer = void 0;
4
+ const asymmetric_1 = require("../../asymmetric");
5
+ const symmetric_1 = require("../../symmetric");
6
+ class AESRSAHybridInitializer {
7
+ aesType;
8
+ aesKey;
9
+ aesNonce;
10
+ rsaKeyPair;
11
+ constructor(aesType, rsaSize) {
12
+ if (aesType !== 128 && aesType !== 256) {
13
+ throw new Error("Need an appropriate AES size to generate a hybrid initalizer");
14
+ }
15
+ this.aesType = aesType;
16
+ let aesWrapper = new symmetric_1.AESWrapper();
17
+ this.aesKey = (aesType === 128) ? aesWrapper.aes128Key() : aesWrapper.aes256Key();
18
+ this.aesNonce = aesWrapper.aesNonce();
19
+ if (rsaSize !== 1028 && rsaSize !== 2048 && rsaSize !== 4096) {
20
+ throw new Error("You must provide an appropriate RSA Key pair size to generate a hybrid initalizer");
21
+ }
22
+ this.rsaKeyPair = new asymmetric_1.RSAWrapper().generateKeys(rsaSize);
23
+ }
24
+ }
25
+ exports.AESRSAHybridInitializer = AESRSAHybridInitializer;
package/lib/index.d.ts CHANGED
@@ -2,5 +2,6 @@ import { Argon2Wrapper, BCryptWrapper, PasswordHasherFactory, PasswordHasherType
2
2
  import { HasherFactory, HasherType, SHAWrapper } from "./hashers/index";
3
3
  import { X25519Wrapper } from "./key_exchange/index";
4
4
  import { AESWrapper } from "./symmetric/index";
5
- import { RSAWrapper, RsaKeyPairResult } from "./asymmetric";
6
- export { Argon2Wrapper, BCryptWrapper, HasherFactory, HasherType, PasswordHasherFactory, PasswordHasherType, ScryptWrapper, SHAWrapper, X25519Wrapper, AESWrapper, RSAWrapper, RsaKeyPairResult };
5
+ import { RsaKeyPairResult, RSAWrapper } from "./asymmetric/index";
6
+ import { AesRsaHybridEncryptResult, AESRSAHybridInitializer, HybridEncryptionWrapper } from "./hybrid/index";
7
+ export { AesRsaHybridEncryptResult, AESRSAHybridInitializer, AESWrapper, Argon2Wrapper, BCryptWrapper, HasherFactory, HasherType, HybridEncryptionWrapper, PasswordHasherFactory, PasswordHasherType, RsaKeyPairResult, RSAWrapper, ScryptWrapper, SHAWrapper, X25519Wrapper, };
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RsaKeyPairResult = exports.RSAWrapper = exports.AESWrapper = exports.X25519Wrapper = exports.SHAWrapper = exports.ScryptWrapper = exports.PasswordHasherType = exports.PasswordHasherFactory = exports.HasherType = exports.HasherFactory = exports.BCryptWrapper = exports.Argon2Wrapper = void 0;
3
+ exports.X25519Wrapper = exports.SHAWrapper = exports.ScryptWrapper = exports.RSAWrapper = exports.RsaKeyPairResult = exports.PasswordHasherType = exports.PasswordHasherFactory = exports.HybridEncryptionWrapper = exports.HasherType = exports.HasherFactory = exports.BCryptWrapper = exports.Argon2Wrapper = exports.AESWrapper = exports.AESRSAHybridInitializer = exports.AesRsaHybridEncryptResult = void 0;
4
4
  const index_1 = require("./password-hashers/index");
5
5
  Object.defineProperty(exports, "Argon2Wrapper", { enumerable: true, get: function () { return index_1.Argon2Wrapper; } });
6
6
  Object.defineProperty(exports, "BCryptWrapper", { enumerable: true, get: function () { return index_1.BCryptWrapper; } });
@@ -15,6 +15,10 @@ const index_3 = require("./key_exchange/index");
15
15
  Object.defineProperty(exports, "X25519Wrapper", { enumerable: true, get: function () { return index_3.X25519Wrapper; } });
16
16
  const index_4 = require("./symmetric/index");
17
17
  Object.defineProperty(exports, "AESWrapper", { enumerable: true, get: function () { return index_4.AESWrapper; } });
18
- const asymmetric_1 = require("./asymmetric");
19
- Object.defineProperty(exports, "RSAWrapper", { enumerable: true, get: function () { return asymmetric_1.RSAWrapper; } });
20
- Object.defineProperty(exports, "RsaKeyPairResult", { enumerable: true, get: function () { return asymmetric_1.RsaKeyPairResult; } });
18
+ const index_5 = require("./asymmetric/index");
19
+ Object.defineProperty(exports, "RsaKeyPairResult", { enumerable: true, get: function () { return index_5.RsaKeyPairResult; } });
20
+ Object.defineProperty(exports, "RSAWrapper", { enumerable: true, get: function () { return index_5.RSAWrapper; } });
21
+ const index_6 = require("./hybrid/index");
22
+ Object.defineProperty(exports, "AesRsaHybridEncryptResult", { enumerable: true, get: function () { return index_6.AesRsaHybridEncryptResult; } });
23
+ Object.defineProperty(exports, "AESRSAHybridInitializer", { enumerable: true, get: function () { return index_6.AESRSAHybridInitializer; } });
24
+ Object.defineProperty(exports, "HybridEncryptionWrapper", { enumerable: true, get: function () { return index_6.HybridEncryptionWrapper; } });
@@ -1,3 +1,4 @@
1
+ import { AesKeyFromX25519SharedSecret } from "../../index";
1
2
  export declare class AESWrapper {
2
3
  aes128Key(): Array<number>;
3
4
  aes256Key(): Array<number>;
@@ -6,4 +7,6 @@ export declare class AESWrapper {
6
7
  aes128Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number>;
7
8
  aes256Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number>;
8
9
  aes256Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number>;
10
+ aes256KeyFromX25519SharedSecret(shared_secret: Array<number>): AesKeyFromX25519SharedSecret;
11
+ aes128KeyFromX25519SharedSecret(shared_secret: Array<number>): AesKeyFromX25519SharedSecret;
9
12
  }
@@ -24,5 +24,11 @@ class AESWrapper {
24
24
  aes256Decrypt(aesKey, nonce, ciphertext) {
25
25
  return (0, index_1.aes256Decrypt)(aesKey, nonce, ciphertext);
26
26
  }
27
+ aes256KeyFromX25519SharedSecret(shared_secret) {
28
+ return (0, index_1.aes256KeyFromX25519SharedSecret)(shared_secret);
29
+ }
30
+ aes128KeyFromX25519SharedSecret(shared_secret) {
31
+ return (0, index_1.aes128KeyFromX25519SharedSecret)(shared_secret);
32
+ }
27
33
  }
28
34
  exports.AESWrapper = AESWrapper;
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "cas-typescript-sdk",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "scripts": {
8
8
  "test": "cargo test && npm run build && mocha -r ts-node/register ./test-ts/**/*.ts --timeout 20000 --recursive",
9
- "build": "napi build --release && tsc",
9
+ "node:test": "mocha -r ts-node/register ./test-ts/**/*.ts --timeout 20000 --recursive",
10
+ "rust:test": "cargo test",
11
+ "build": "npm run build:rust && npm run build:node",
12
+ "build:rust": "napi build --release",
13
+ "build:node": "bash build-node.sh",
10
14
  "prepare": "npm run build"
11
15
  },
12
16
  "repository": {
@@ -1,3 +1,4 @@
1
+ use aes_gcm::Key;
1
2
  use napi_derive::napi;
2
3
  use rand::rngs::OsRng;
3
4
  use rand::{RngCore, SeedableRng};
@@ -8,7 +9,7 @@ use aes_gcm::{
8
9
  Aes256Gcm, Aes128Gcm, KeyInit, Nonce
9
10
  };
10
11
 
11
- use super::cas_symmetric_encryption::CASAESEncryption;
12
+ use super::cas_symmetric_encryption::{AesKeyFromX25519SharedSecret, CASAESEncryption};
12
13
  pub struct CASAES128;
13
14
  pub struct CASAES256;
14
15
 
@@ -32,6 +33,17 @@ impl CASAESEncryption for CASAES256 {
32
33
  let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()).unwrap();
33
34
  plaintext
34
35
  }
36
+
37
+ fn key_from_x25519_shared_secret(shared_secret: Vec<u8>) -> AesKeyFromX25519SharedSecret {
38
+ let aes_key = Key::<Aes256Gcm>::from_slice(&shared_secret);
39
+ let mut aes_nonce: [u8; 12] = Default::default();
40
+ aes_nonce.copy_from_slice(&shared_secret[..12]);
41
+ let result = AesKeyFromX25519SharedSecret {
42
+ aes_key: aes_key.to_vec(),
43
+ aes_nonce: aes_nonce.to_vec()
44
+ };
45
+ result
46
+ }
35
47
  }
36
48
 
37
49
  impl CASAESEncryption for CASAES128 {
@@ -54,6 +66,19 @@ impl CASAESEncryption for CASAES128 {
54
66
  let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()).unwrap();
55
67
  plaintext
56
68
  }
69
+
70
+ fn key_from_x25519_shared_secret(shared_secret: Vec<u8>) -> AesKeyFromX25519SharedSecret {
71
+ let mut aes_key: [u8; 16] = Default::default();
72
+ aes_key.copy_from_slice(&shared_secret[..16]);
73
+ let aes_key_slice = Key::<Aes128Gcm>::from_slice(&aes_key);
74
+ let mut aes_nonce: [u8; 12] = Default::default();
75
+ aes_nonce.copy_from_slice(&shared_secret[..12]);
76
+ let result = AesKeyFromX25519SharedSecret {
77
+ aes_key: aes_key_slice.to_vec(),
78
+ aes_nonce: aes_nonce.to_vec()
79
+ };
80
+ result
81
+ }
57
82
  }
58
83
 
59
84
  #[napi]
@@ -95,6 +120,16 @@ pub fn aes256_decrypt(aes_key: Vec<u8>, nonce: Vec<u8>, ciphertext: Vec<u8>) ->
95
120
  return CASAES256::decrypt_ciphertext(aes_key, nonce, ciphertext);
96
121
  }
97
122
 
123
+ #[napi]
124
+ pub fn aes_256_key_from_x25519_shared_secret(shared_secret: Vec<u8>) -> AesKeyFromX25519SharedSecret {
125
+ return CASAES256::key_from_x25519_shared_secret(shared_secret);
126
+ }
127
+
128
+ #[napi]
129
+ pub fn aes_128_key_from_x25519_shared_secret(shared_secret: Vec<u8>) -> AesKeyFromX25519SharedSecret {
130
+ return CASAES128::key_from_x25519_shared_secret(shared_secret);
131
+ }
132
+
98
133
  #[test]
99
134
  fn aes128_encrypt_decrypt_test() {
100
135
  let aes_key = aes128_key();
@@ -1,5 +1,14 @@
1
+ use napi_derive::napi;
2
+
3
+ #[napi(constructor)]
4
+ pub struct AesKeyFromX25519SharedSecret {
5
+ pub aes_key: Vec<u8>,
6
+ pub aes_nonce: Vec<u8>
7
+ }
8
+
1
9
  pub trait CASAESEncryption {
2
10
  fn generate_key() -> Vec<u8>;
3
11
  fn encrypt_plaintext(aes_key: Vec<u8>, nonce: Vec<u8>, plaintext: Vec<u8>) -> Vec<u8>;
4
12
  fn decrypt_ciphertext(aes_key: Vec<u8>, nonce: Vec<u8>, ciphertext: Vec<u8>) -> Vec<u8>;
13
+ fn key_from_x25519_shared_secret(shared_secret: Vec<u8>) -> AesKeyFromX25519SharedSecret;
5
14
  }
@@ -0,0 +1,64 @@
1
+ import { RSAWrapper } from "../asymmetric";
2
+ import { AESWrapper } from "../symmetric";
3
+ import { AesRsaHybridEncryptResult } from "./types/aes-rsa-hybird-encrypt-result";
4
+ import { AESRSAHybridInitializer } from "./types/aes-rsa-hybrid-initializer";
5
+
6
+ export class HybridEncryptionWrapper {
7
+ private aesWrapper: AESWrapper;
8
+ private rsaWrapper: RSAWrapper;
9
+
10
+ constructor() {
11
+ this.aesWrapper = new AESWrapper();
12
+ this.rsaWrapper = new RSAWrapper();
13
+ }
14
+
15
+ public encrypt(
16
+ dataToEncrypt: Array<number>,
17
+ initalizer: AESRSAHybridInitializer,
18
+ ): AesRsaHybridEncryptResult {
19
+ let encryptedData: Array<number> = (initalizer.aesType === 128)
20
+ ? this.aesWrapper.aes128Encrypt(
21
+ initalizer.aesKey,
22
+ initalizer.aesNonce,
23
+ dataToEncrypt,
24
+ )
25
+ : this.aesWrapper.aes256Encrypt(
26
+ initalizer.aesKey,
27
+ initalizer.aesNonce,
28
+ dataToEncrypt,
29
+ );
30
+ let encryptedAesKey: Array<number> = this.rsaWrapper.encrypt(
31
+ initalizer.rsaKeyPair.publicKey,
32
+ initalizer.aesKey,
33
+ );
34
+ let result: AesRsaHybridEncryptResult = new AesRsaHybridEncryptResult(
35
+ encryptedData,
36
+ encryptedAesKey,
37
+ initalizer.aesType,
38
+ initalizer.aesNonce,
39
+ );
40
+ return result;
41
+ }
42
+
43
+ public decrypt(
44
+ privateKey: string,
45
+ encryptResult: AesRsaHybridEncryptResult,
46
+ ): Array<number> {
47
+ let plaintextAesKey = this.rsaWrapper.decrypt(
48
+ privateKey,
49
+ encryptResult.encryptedAesKey,
50
+ );
51
+ let plaintext = (encryptResult.aesType === 128)
52
+ ? this.aesWrapper.aes128Decrypt(
53
+ plaintextAesKey,
54
+ encryptResult.aesNonce,
55
+ encryptResult.ciphertext,
56
+ )
57
+ : this.aesWrapper.aes256Decrypt(
58
+ plaintextAesKey,
59
+ encryptResult.aesNonce,
60
+ encryptResult.ciphertext,
61
+ );
62
+ return plaintext;
63
+ }
64
+ }
@@ -0,0 +1,9 @@
1
+ import { HybridEncryptionWrapper } from "./hybrid-encryption-wrapper";
2
+ import { AesRsaHybridEncryptResult } from "./types/aes-rsa-hybird-encrypt-result";
3
+ import { AESRSAHybridInitializer } from "./types/aes-rsa-hybrid-initializer";
4
+
5
+ export {
6
+ AesRsaHybridEncryptResult,
7
+ AESRSAHybridInitializer,
8
+ HybridEncryptionWrapper,
9
+ };
@@ -0,0 +1,13 @@
1
+ export class AesRsaHybridEncryptResult {
2
+ ciphertext: Array<number>;
3
+ encryptedAesKey: Array<number>;
4
+ aesType: number;
5
+ aesNonce: Array<number>;
6
+
7
+ constructor(cipherText: Array<number>, encryptAesKey: Array<number>, aesType: number, aesNonce: Array<number>) {
8
+ this.ciphertext = cipherText;
9
+ this.encryptedAesKey = encryptAesKey;
10
+ this.aesType = aesType;
11
+ this.aesNonce = aesNonce;
12
+ }
13
+ }
@@ -0,0 +1,24 @@
1
+ import { RsaKeyPairResult } from "../../..";
2
+ import { RSAWrapper } from "../../asymmetric";
3
+ import { AESWrapper } from "../../symmetric";
4
+
5
+ export class AESRSAHybridInitializer {
6
+ public aesType: number;
7
+ public aesKey: Array<number>;
8
+ public aesNonce: Array<number>;
9
+ public rsaKeyPair: RsaKeyPairResult;
10
+
11
+ constructor(aesType: number, rsaSize: number) {
12
+ if (aesType !== 128 && aesType !== 256) {
13
+ throw new Error("Need an appropriate AES size to generate a hybrid initalizer");
14
+ }
15
+ this.aesType = aesType;
16
+ let aesWrapper = new AESWrapper();
17
+ this.aesKey = (aesType === 128) ? aesWrapper.aes128Key() : aesWrapper.aes256Key();
18
+ this.aesNonce = aesWrapper.aesNonce();
19
+ if (rsaSize !== 1028 && rsaSize !== 2048 && rsaSize !== 4096) {
20
+ throw new Error("You must provide an appropriate RSA Key pair size to generate a hybrid initalizer");
21
+ }
22
+ this.rsaKeyPair = new RSAWrapper().generateKeys(rsaSize);
23
+ }
24
+ }
package/src-ts/index.ts CHANGED
@@ -8,19 +8,27 @@ import {
8
8
  import { HasherFactory, HasherType, SHAWrapper } from "./hashers/index";
9
9
  import { X25519Wrapper } from "./key_exchange/index";
10
10
  import { AESWrapper } from "./symmetric/index";
11
- import { RSAWrapper, RsaKeyPairResult } from "./asymmetric";
11
+ import { RsaKeyPairResult, RSAWrapper } from "./asymmetric/index";
12
+ import {
13
+ AesRsaHybridEncryptResult,
14
+ AESRSAHybridInitializer,
15
+ HybridEncryptionWrapper,
16
+ } from "./hybrid/index";
12
17
 
13
18
  export {
19
+ AesRsaHybridEncryptResult,
20
+ AESRSAHybridInitializer,
21
+ AESWrapper,
14
22
  Argon2Wrapper,
15
23
  BCryptWrapper,
16
24
  HasherFactory,
17
25
  HasherType,
26
+ HybridEncryptionWrapper,
18
27
  PasswordHasherFactory,
19
28
  PasswordHasherType,
29
+ RsaKeyPairResult,
30
+ RSAWrapper,
20
31
  ScryptWrapper,
21
32
  SHAWrapper,
22
33
  X25519Wrapper,
23
- AESWrapper,
24
- RSAWrapper,
25
- RsaKeyPairResult
26
34
  };
@@ -1,10 +1,13 @@
1
1
  import {
2
+ AesKeyFromX25519SharedSecret,
2
3
  aes128Decrypt,
3
4
  aes128Encrypt,
4
5
  aes128Key,
6
+ aes128KeyFromX25519SharedSecret,
5
7
  aes256Decrypt,
6
8
  aes256Encrypt,
7
9
  aes256Key,
10
+ aes256KeyFromX25519SharedSecret,
8
11
  aesNonce,
9
12
  } from "../../index";
10
13
 
@@ -36,4 +39,12 @@ export class AESWrapper {
36
39
  public aes256Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number> {
37
40
  return aes256Decrypt(aesKey, nonce, ciphertext);
38
41
  }
42
+
43
+ public aes256KeyFromX25519SharedSecret(shared_secret: Array<number>): AesKeyFromX25519SharedSecret {
44
+ return aes256KeyFromX25519SharedSecret(shared_secret);
45
+ }
46
+
47
+ public aes128KeyFromX25519SharedSecret(shared_secret: Array<number>): AesKeyFromX25519SharedSecret {
48
+ return aes128KeyFromX25519SharedSecret(shared_secret);
49
+ }
39
50
  }
@@ -0,0 +1,33 @@
1
+ import { assert } from "chai";
2
+ import {
3
+ AESRSAHybridInitializer,
4
+ AesRsaHybridEncryptResult,
5
+ HybridEncryptionWrapper,
6
+ } from "../src-ts/hybrid/index";
7
+ import { areEqual } from "./helpers/array";
8
+
9
+ describe("Hybrid Encryption Tests", () => {
10
+ it("RSA 4096 AES 128 encrypt and decrypt equals", () => {
11
+ const hybridWrapper = new HybridEncryptionWrapper();
12
+ let initalizer = new AESRSAHybridInitializer(128, 4096);
13
+ const tohashed: string = "This is my encrypt text for rsa hybrid";
14
+ const encoder = new TextEncoder();
15
+ const toEncrypt: Array<number> = Array.from(encoder.encode(tohashed));
16
+ let result: AesRsaHybridEncryptResult = hybridWrapper.encrypt(toEncrypt, initalizer);
17
+ let plaintext: Array<number> = hybridWrapper.decrypt(initalizer.rsaKeyPair.privateKey, result);
18
+ let result2 = areEqual(toEncrypt, plaintext);
19
+ assert.isTrue(result2);
20
+ });
21
+
22
+ it("RSA 2048 AES 256 encrypt and decrypt equals", () => {
23
+ const hybridWrapper = new HybridEncryptionWrapper();
24
+ let initalizer = new AESRSAHybridInitializer(256, 2048);
25
+ const tohashed: string = "This is my encrypt text for rsa hybrid";
26
+ const encoder = new TextEncoder();
27
+ const toEncrypt: Array<number> = Array.from(encoder.encode(tohashed));
28
+ let result: AesRsaHybridEncryptResult = hybridWrapper.encrypt(toEncrypt, initalizer);
29
+ let plaintext: Array<number> = hybridWrapper.decrypt(initalizer.rsaKeyPair.privateKey, result);
30
+ let result2 = areEqual(toEncrypt, plaintext);
31
+ assert.isTrue(result2);
32
+ });
33
+ });
@@ -0,0 +1,51 @@
1
+ import {AESWrapper} from "../src-ts/symmetric/index";
2
+ import {X25519Wrapper} from "../src-ts/key_exchange/index";
3
+ import {X25519SecretPublicKeyResult} from "../index";
4
+ import { areEqual } from "./helpers/array";
5
+ import { assert } from "chai";
6
+
7
+ describe("Insecure Channel Tests", () => {
8
+ it("AES256-GBC Diffie Hellman X25519", () => {
9
+ const aesWrapper = new AESWrapper();
10
+ const x25519Wrapper = new X25519Wrapper();
11
+ const alice_keys: X25519SecretPublicKeyResult = x25519Wrapper.generateSecretAndPublicKey();
12
+ const bob_keys: X25519SecretPublicKeyResult = x25519Wrapper.generateSecretAndPublicKey();
13
+
14
+ const alice_shared_secret = x25519Wrapper.diffieHellman(alice_keys.secretKey, bob_keys.publicKey);
15
+ const bob_shared_secret = x25519Wrapper.diffieHellman(bob_keys.secretKey, alice_keys.publicKey);
16
+
17
+ const alice_aes_key = aesWrapper.aes256KeyFromX25519SharedSecret(alice_shared_secret);
18
+ const bob_aes_key = aesWrapper.aes256KeyFromX25519SharedSecret(bob_shared_secret);
19
+
20
+ const tohashed: string = "This is my encrypt text";
21
+ const encoder = new TextEncoder();
22
+ const toEncrypt: Array<number> = Array.from(encoder.encode(tohashed));
23
+
24
+ const encrypted = aesWrapper.aes256Encrypt(alice_aes_key?.aesKey, alice_aes_key?.aesNonce, toEncrypt);
25
+ const decrypted = aesWrapper.aes256Decrypt(bob_aes_key?.aesKey, bob_aes_key?.aesNonce, encrypted);
26
+ let result = areEqual(decrypted, toEncrypt);
27
+ assert.isTrue(result);
28
+ });
29
+
30
+ it("AES128-GBC Diffie Hellman X25519", () => {
31
+ const aesWrapper = new AESWrapper();
32
+ const x25519Wrapper = new X25519Wrapper();
33
+ const alice_keys: X25519SecretPublicKeyResult = x25519Wrapper.generateSecretAndPublicKey();
34
+ const bob_keys: X25519SecretPublicKeyResult = x25519Wrapper.generateSecretAndPublicKey();
35
+
36
+ const alice_shared_secret = x25519Wrapper.diffieHellman(alice_keys.secretKey, bob_keys.publicKey);
37
+ const bob_shared_secret = x25519Wrapper.diffieHellman(bob_keys.secretKey, alice_keys.publicKey);
38
+
39
+ const alice_aes_key = aesWrapper.aes128KeyFromX25519SharedSecret(alice_shared_secret);
40
+ const bob_aes_key = aesWrapper.aes128KeyFromX25519SharedSecret(bob_shared_secret);
41
+
42
+ const tohashed: string = "This is my encrypt text";
43
+ const encoder = new TextEncoder();
44
+ const toEncrypt: Array<number> = Array.from(encoder.encode(tohashed));
45
+
46
+ const encrypted = aesWrapper.aes128Encrypt(alice_aes_key?.aesKey, alice_aes_key?.aesNonce, toEncrypt);
47
+ const decrypted = aesWrapper.aes128Decrypt(bob_aes_key?.aesKey, bob_aes_key?.aesNonce, encrypted);
48
+ let result = areEqual(decrypted, toEncrypt);
49
+ assert.isTrue(result);
50
+ });
51
+ });
Binary file
@@ -1,6 +0,0 @@
1
- export interface IHasherBase {
2
- hash_512(dataToHash: number[]): number[];
3
- verify_512(dataToHash: number[], dataToVerify: number[]): boolean;
4
- hash_256(dataToHash: number[]): number[];
5
- verify_256(dataToHash: number[], dataToVerify: number[]): boolean;
6
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +0,0 @@
1
- import { IHasherBase } from "./IHasherBase";
2
- export declare class SHAWrapper implements IHasherBase {
3
- hash_512(dataToHash: number[]): number[];
4
- verify_512(dataToHash: number[], dataToVerify: number[]): boolean;
5
- hash_256(dataToHash: number[]): number[];
6
- verify_256(dataToHash: number[], dataToVerify: number[]): boolean;
7
- }
@@ -1,37 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SHAWrapper = void 0;
4
- const index_1 = require("../../index");
5
- class SHAWrapper {
6
- hash_512(dataToHash) {
7
- if (!dataToHash || dataToHash.length === 0) {
8
- throw new Error("You must provide an allocated array of data");
9
- }
10
- return (0, index_1.sha512)(dataToHash);
11
- }
12
- verify_512(dataToHash, dataToVerify) {
13
- if (!dataToHash || dataToHash.length === 0) {
14
- throw new Error("You must provide an allocated array of data");
15
- }
16
- if (!dataToVerify || dataToVerify.length === 0) {
17
- throw new Error("You must provide an allocated array of data to verify");
18
- }
19
- return (0, index_1.sha512Verify)(dataToHash, dataToVerify);
20
- }
21
- hash_256(dataToHash) {
22
- if (!dataToHash || dataToHash.length === 0) {
23
- throw new Error("You must provide an allocated array of data");
24
- }
25
- return (0, index_1.sha256)(dataToHash);
26
- }
27
- verify_256(dataToHash, dataToVerify) {
28
- if (!dataToHash || dataToHash.length === 0) {
29
- throw new Error("You must provide an allocated array of data");
30
- }
31
- if (!dataToVerify || dataToVerify.length === 0) {
32
- throw new Error("You must provide an allocated array of data to verify");
33
- }
34
- return (0, index_1.sha256Verify)(dataToHash, dataToVerify);
35
- }
36
- }
37
- exports.SHAWrapper = SHAWrapper;
Binary file
@@ -1,3 +0,0 @@
1
- import koffi from "koffi";
2
- declare const Argon2HashThreadResult: koffi.IKoffiCType;
3
- export default Argon2HashThreadResult;
@@ -1,11 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const koffi_1 = __importDefault(require("koffi"));
7
- const Argon2HashThreadResult = koffi_1.default.struct("Argon2HashThreadResult", {
8
- passwords: 'char *',
9
- length: 'int'
10
- });
11
- exports.default = Argon2HashThreadResult;