cas-typescript-sdk 1.0.8 → 1.0.10
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.
- package/Cargo.toml +5 -0
- package/README.md +8 -1
- package/index.d.ts +19 -0
- package/index.node +0 -0
- package/lib/hashers/IHasherBase.d.ts +6 -0
- package/lib/hashers/IHasherBase.js +2 -0
- package/lib/hashers/SHAWrapper.d.ts +7 -0
- package/lib/hashers/SHAWrapper.js +37 -0
- package/lib/hashers/hasher-base.d.ts +6 -0
- package/lib/hashers/hasher-base.js +2 -0
- package/lib/hashers/hasher-factory.d.ts +4 -0
- package/lib/hashers/hasher-factory.js +13 -0
- package/lib/hashers/hasher-type.d.ts +3 -0
- package/lib/hashers/hasher-type.js +7 -0
- package/lib/hashers/index.d.ts +4 -0
- package/lib/hashers/index.js +9 -0
- package/lib/hashers/sha-wrapper.d.ts +7 -0
- package/lib/hashers/sha-wrapper.js +37 -0
- package/lib/index.d.ts +5 -2
- package/lib/index.js +15 -26
- package/lib/key_exchange/index.d.ts +2 -0
- package/lib/key_exchange/index.js +5 -0
- package/lib/key_exchange/x25519.d.ts +5 -0
- package/lib/key_exchange/x25519.js +13 -0
- package/lib/password-hashers/index.d.ts +1 -1
- package/lib/password-hashers/index.js +1 -1
- package/lib/symmetric/aes-wrapper.d.ts +9 -0
- package/lib/symmetric/aes-wrapper.js +28 -0
- package/lib/symmetric/index.d.ts +2 -0
- package/lib/symmetric/index.js +5 -0
- package/package.json +2 -2
- package/src/hashers/blake2.rs +39 -0
- package/src/hashers/cas_hasher.rs +8 -0
- package/src/hashers/sha.rs +103 -0
- package/src/key_exchange/cas_key_exchange.rs +6 -0
- package/src/key_exchange/x25519.rs +57 -0
- package/src/lib.rs +16 -0
- package/src/password_hashers/argon2.rs +27 -0
- package/src/password_hashers/bcrypt.rs +24 -0
- package/src/password_hashers/scrypt.rs +24 -0
- package/src/symmetric/aes.rs +116 -0
- package/src/symmetric/cas_symmetric_encryption.rs +5 -0
- package/src-ts/hashers/hasher-base.ts +6 -0
- package/src-ts/hashers/hasher-factory.ts +12 -0
- package/src-ts/hashers/hasher-type.ts +3 -0
- package/src-ts/hashers/index.ts +5 -0
- package/src-ts/hashers/sha-wrapper.ts +38 -0
- package/src-ts/index.ts +21 -3
- package/src-ts/key_exchange/index.ts +3 -0
- package/src-ts/key_exchange/x25519.ts +11 -0
- package/src-ts/password-hashers/index.ts +12 -6
- package/src-ts/symmetric/aes-wrapper.ts +39 -0
- package/src-ts/symmetric/index.ts +3 -0
- package/test-ts/hasher.test.spec.ts +71 -0
- package/test-ts/helpers/array.ts +10 -0
- package/test-ts/key-exchange-test.spec.ts +23 -0
- package/test-ts/symmetric.test.spec.ts +31 -0
package/Cargo.toml
CHANGED
|
@@ -8,12 +8,17 @@ path = "src/lib.rs"
|
|
|
8
8
|
crate-type = ["cdylib"]
|
|
9
9
|
|
|
10
10
|
[dependencies]
|
|
11
|
+
aes-gcm = "0.10.3"
|
|
11
12
|
argon2 = "0.5.2"
|
|
12
13
|
bcrypt = "0.15.0"
|
|
14
|
+
blake2 = "0.10.6"
|
|
13
15
|
napi = "2"
|
|
14
16
|
napi-derive = "2"
|
|
15
17
|
rand = "0.8.5"
|
|
18
|
+
rand_chacha = "0.3.1"
|
|
16
19
|
scrypt = "0.11.0"
|
|
20
|
+
sha3 = "0.10.8"
|
|
21
|
+
x25519-dalek = {version = "2.0.0", features = ["static_secrets"] }
|
|
17
22
|
|
|
18
23
|
[build-dependencies]
|
|
19
24
|
napi-build = "1"
|
package/README.md
CHANGED
|
@@ -7,5 +7,12 @@ The official NPM page can be found [here](https://www.npmjs.com/package/cas-type
|
|
|
7
7
|
|
|
8
8
|
This Node.js NPM module is dependent on our Rust layer [here](./src) that contains methods to run industry standard cryptographic operations sequentially, on threads, and the thread pool.
|
|
9
9
|
|
|
10
|
+
## Consuming Library Documentation
|
|
11
|
+
We utilize some smart people's existing work and we believe their documentation should be reviewed when possible.
|
|
12
|
+
- [Spin Research](https://github.com/SpinResearch)
|
|
13
|
+
- [Dalek-Cryptography](https://github.com/dalek-cryptography)
|
|
14
|
+
- [Rust Crypto](https://github.com/RustCrypto)
|
|
15
|
+
- [Rayon](https://github.com/rayon-rs/rayon)
|
|
16
|
+
|
|
10
17
|
## Disclaimer
|
|
11
|
-
Many of the cryptographic crates that are utilized in our core FFI [layer](
|
|
18
|
+
Many of the cryptographic crates that are utilized in our core FFI [layer](./src) have never had a security audit performed. Utilize this SDK at your own risk.
|
package/index.d.ts
CHANGED
|
@@ -9,3 +9,22 @@ export function bcryptHash(passwordToHash: string): string
|
|
|
9
9
|
export function bcryptVerify(hashedPassword: string, passwordToVerify: string): boolean
|
|
10
10
|
export function scryptHash(passwordToHash: string): string
|
|
11
11
|
export function scryptVerify(hashedPassword: string, passwordToVerify: string): boolean
|
|
12
|
+
export function sha512(dataToHash: Array<number>): Array<number>
|
|
13
|
+
export function sha512Verify(dataToHash: Array<number>, dataToVerify: Array<number>): boolean
|
|
14
|
+
export function sha256(dataToHash: Array<number>): Array<number>
|
|
15
|
+
export function sha256Verify(dataToHash: Array<number>, dataToVerify: Array<number>): boolean
|
|
16
|
+
export function x25519GenerateSecretAndPublicKey(): X25519SecretPublicKeyResult
|
|
17
|
+
export function x25519DiffieHellman(mySecretKey: Array<number>, usersPublicKey: Array<number>): Array<number>
|
|
18
|
+
export function aesNonce(): Array<number>
|
|
19
|
+
export function aes128Key(): Array<number>
|
|
20
|
+
export function aes256Key(): Array<number>
|
|
21
|
+
export function aes128Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number>
|
|
22
|
+
export function aes128Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number>
|
|
23
|
+
export function aes256Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number>
|
|
24
|
+
export function aes256Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number>
|
|
25
|
+
export type x25519SecretPublicKeyResult = X25519SecretPublicKeyResult
|
|
26
|
+
export class X25519SecretPublicKeyResult {
|
|
27
|
+
publicKey: Array<number>
|
|
28
|
+
secretKey: Array<number>
|
|
29
|
+
constructor(publicKey: Array<number>, secretKey: Array<number>)
|
|
30
|
+
}
|
package/index.node
CHANGED
|
Binary file
|
|
@@ -0,0 +1,7 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
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;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HasherFactory = void 0;
|
|
4
|
+
const sha_wrapper_1 = require("./sha-wrapper");
|
|
5
|
+
class HasherFactory {
|
|
6
|
+
getHasher(type) {
|
|
7
|
+
let result = new sha_wrapper_1.SHAWrapper();
|
|
8
|
+
switch (type) {
|
|
9
|
+
}
|
|
10
|
+
return result;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.HasherFactory = HasherFactory;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HasherType = exports.HasherFactory = exports.SHAWrapper = void 0;
|
|
4
|
+
const hasher_factory_1 = require("./hasher-factory");
|
|
5
|
+
Object.defineProperty(exports, "HasherFactory", { enumerable: true, get: function () { return hasher_factory_1.HasherFactory; } });
|
|
6
|
+
const hasher_type_1 = require("./hasher-type");
|
|
7
|
+
Object.defineProperty(exports, "HasherType", { enumerable: true, get: function () { return hasher_type_1.HasherType; } });
|
|
8
|
+
const sha_wrapper_1 = require("./sha-wrapper");
|
|
9
|
+
Object.defineProperty(exports, "SHAWrapper", { enumerable: true, get: function () { return sha_wrapper_1.SHAWrapper; } });
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { IHasherBase } from "./hasher-base";
|
|
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
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
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;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { Argon2Wrapper, BCryptWrapper, PasswordHasherFactory, PasswordHasherType, ScryptWrapper } from "./password-hashers/index";
|
|
2
|
+
import { HasherFactory, HasherType, SHAWrapper } from "./hashers/index";
|
|
3
|
+
import { X25519Wrapper } from "./key_exchange/index";
|
|
4
|
+
import { AESWrapper } from "./symmetric/index";
|
|
5
|
+
export { Argon2Wrapper, BCryptWrapper, HasherFactory, HasherType, PasswordHasherFactory, PasswordHasherType, ScryptWrapper, SHAWrapper, X25519Wrapper, AESWrapper };
|
package/lib/index.js
CHANGED
|
@@ -1,28 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.
|
|
27
|
-
const
|
|
28
|
-
exports.
|
|
3
|
+
exports.AESWrapper = exports.X25519Wrapper = exports.SHAWrapper = exports.ScryptWrapper = exports.PasswordHasherType = exports.PasswordHasherFactory = exports.HasherType = exports.HasherFactory = exports.BCryptWrapper = exports.Argon2Wrapper = void 0;
|
|
4
|
+
const index_1 = require("./password-hashers/index");
|
|
5
|
+
Object.defineProperty(exports, "Argon2Wrapper", { enumerable: true, get: function () { return index_1.Argon2Wrapper; } });
|
|
6
|
+
Object.defineProperty(exports, "BCryptWrapper", { enumerable: true, get: function () { return index_1.BCryptWrapper; } });
|
|
7
|
+
Object.defineProperty(exports, "PasswordHasherFactory", { enumerable: true, get: function () { return index_1.PasswordHasherFactory; } });
|
|
8
|
+
Object.defineProperty(exports, "PasswordHasherType", { enumerable: true, get: function () { return index_1.PasswordHasherType; } });
|
|
9
|
+
Object.defineProperty(exports, "ScryptWrapper", { enumerable: true, get: function () { return index_1.ScryptWrapper; } });
|
|
10
|
+
const index_2 = require("./hashers/index");
|
|
11
|
+
Object.defineProperty(exports, "HasherFactory", { enumerable: true, get: function () { return index_2.HasherFactory; } });
|
|
12
|
+
Object.defineProperty(exports, "HasherType", { enumerable: true, get: function () { return index_2.HasherType; } });
|
|
13
|
+
Object.defineProperty(exports, "SHAWrapper", { enumerable: true, get: function () { return index_2.SHAWrapper; } });
|
|
14
|
+
const index_3 = require("./key_exchange/index");
|
|
15
|
+
Object.defineProperty(exports, "X25519Wrapper", { enumerable: true, get: function () { return index_3.X25519Wrapper; } });
|
|
16
|
+
const index_4 = require("./symmetric/index");
|
|
17
|
+
Object.defineProperty(exports, "AESWrapper", { enumerable: true, get: function () { return index_4.AESWrapper; } });
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.X25519Wrapper = void 0;
|
|
4
|
+
const x25519_1 = require("./x25519");
|
|
5
|
+
Object.defineProperty(exports, "X25519Wrapper", { enumerable: true, get: function () { return x25519_1.X25519Wrapper; } });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.X25519Wrapper = void 0;
|
|
4
|
+
const index_1 = require("../../index");
|
|
5
|
+
class X25519Wrapper {
|
|
6
|
+
generateSecretAndPublicKey() {
|
|
7
|
+
return (0, index_1.x25519GenerateSecretAndPublicKey)();
|
|
8
|
+
}
|
|
9
|
+
diffieHellman(secretKey, publicKey) {
|
|
10
|
+
return (0, index_1.x25519DiffieHellman)(secretKey, publicKey);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.X25519Wrapper = X25519Wrapper;
|
|
@@ -3,4 +3,4 @@ import { BCryptWrapper } from "./bcrypt-wrapper";
|
|
|
3
3
|
import { ScryptWrapper } from "./scrypt-wrapper";
|
|
4
4
|
import { PasswordHasherType } from "./password-hasher-type";
|
|
5
5
|
import { PasswordHasherFactory } from "./password-hasher-factory";
|
|
6
|
-
export {
|
|
6
|
+
export { Argon2Wrapper, BCryptWrapper, PasswordHasherFactory, PasswordHasherType, ScryptWrapper, };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ScryptWrapper = exports.
|
|
3
|
+
exports.ScryptWrapper = exports.PasswordHasherType = exports.PasswordHasherFactory = exports.BCryptWrapper = exports.Argon2Wrapper = void 0;
|
|
4
4
|
const argon2_wrapper_1 = require("./argon2-wrapper");
|
|
5
5
|
Object.defineProperty(exports, "Argon2Wrapper", { enumerable: true, get: function () { return argon2_wrapper_1.Argon2Wrapper; } });
|
|
6
6
|
const bcrypt_wrapper_1 = require("./bcrypt-wrapper");
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class AESWrapper {
|
|
2
|
+
aes128Key(): Array<number>;
|
|
3
|
+
aes256Key(): Array<number>;
|
|
4
|
+
aesNonce(): Array<number>;
|
|
5
|
+
aes128Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number>;
|
|
6
|
+
aes128Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number>;
|
|
7
|
+
aes256Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number>;
|
|
8
|
+
aes256Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AESWrapper = void 0;
|
|
4
|
+
const index_1 = require("../../index");
|
|
5
|
+
class AESWrapper {
|
|
6
|
+
aes128Key() {
|
|
7
|
+
return (0, index_1.aes128Key)();
|
|
8
|
+
}
|
|
9
|
+
aes256Key() {
|
|
10
|
+
return (0, index_1.aes256Key)();
|
|
11
|
+
}
|
|
12
|
+
aesNonce() {
|
|
13
|
+
return (0, index_1.aesNonce)();
|
|
14
|
+
}
|
|
15
|
+
aes128Encrypt(aesKey, nonce, plaintext) {
|
|
16
|
+
return (0, index_1.aes128Encrypt)(aesKey, nonce, plaintext);
|
|
17
|
+
}
|
|
18
|
+
aes128Decrypt(aesKey, nonce, ciphertext) {
|
|
19
|
+
return (0, index_1.aes128Decrypt)(aesKey, nonce, ciphertext);
|
|
20
|
+
}
|
|
21
|
+
aes256Encrypt(aesKey, nonce, plaintext) {
|
|
22
|
+
return (0, index_1.aes256Encrypt)(aesKey, nonce, plaintext);
|
|
23
|
+
}
|
|
24
|
+
aes256Decrypt(aesKey, nonce, ciphertext) {
|
|
25
|
+
return (0, index_1.aes256Decrypt)(aesKey, nonce, ciphertext);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.AESWrapper = AESWrapper;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AESWrapper = void 0;
|
|
4
|
+
const aes_wrapper_1 = require("./aes-wrapper");
|
|
5
|
+
Object.defineProperty(exports, "AESWrapper", { enumerable: true, get: function () { return aes_wrapper_1.AESWrapper; } });
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cas-typescript-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"test": "mocha -r ts-node/register ./test-ts/**/*.ts --timeout 20000 --recursive",
|
|
8
|
+
"test": "cargo test && npm run build && mocha -r ts-node/register ./test-ts/**/*.ts --timeout 20000 --recursive",
|
|
9
9
|
"build": "napi build --release && tsc",
|
|
10
10
|
"prepare": "npm run build"
|
|
11
11
|
},
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
use blake2::{Blake2b512, Blake2s256, Digest};
|
|
2
|
+
use super::cas_hasher::CASHasher;
|
|
3
|
+
|
|
4
|
+
pub struct CASBlake2;
|
|
5
|
+
|
|
6
|
+
impl CASHasher for CASBlake2 {
|
|
7
|
+
fn hash_512(data_to_hash: Vec<u8>) -> Vec<u8> {
|
|
8
|
+
let mut hasher = Blake2b512::new();
|
|
9
|
+
hasher.update(data_to_hash);
|
|
10
|
+
let result = hasher.finalize();
|
|
11
|
+
return result.to_vec();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
fn verify_512(hash_to_verify: Vec<u8>, data_to_verify: Vec<u8>) -> bool {
|
|
15
|
+
let mut hasher = Blake2b512::new();
|
|
16
|
+
hasher.update(data_to_verify);
|
|
17
|
+
let result = hasher.finalize();
|
|
18
|
+
return hash_to_verify.eq(&result.to_vec());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
fn hash_256(data_to_hash: Vec<u8>) -> Vec<u8> {
|
|
22
|
+
let mut hasher = Blake2s256::new();
|
|
23
|
+
hasher.update(data_to_hash);
|
|
24
|
+
let result = hasher.finalize();
|
|
25
|
+
return result.to_vec();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fn verify_256(hash_to_verify: Vec<u8>, data_to_verify: Vec<u8>) -> bool {
|
|
29
|
+
let mut hasher = Blake2s256::new();
|
|
30
|
+
hasher.update(data_to_verify);
|
|
31
|
+
let result = hasher.finalize();
|
|
32
|
+
return hash_to_verify.eq(&result.to_vec());
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
#[test]
|
|
37
|
+
fn hash_512_test() {
|
|
38
|
+
|
|
39
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
use napi::bindgen_prelude::Array;
|
|
2
|
+
|
|
3
|
+
pub trait CASHasher {
|
|
4
|
+
fn hash_512(data_to_hash: Vec<u8>) -> Vec<u8>;
|
|
5
|
+
fn verify_512(hash_to_verify: Vec<u8>, data_to_verify: Vec<u8>) -> bool;
|
|
6
|
+
fn hash_256(data_to_hash: Vec<u8>) -> Vec<u8>;
|
|
7
|
+
fn verify_256(hash_to_verify: Vec<u8>, data_to_verify: Vec<u8>) -> bool;
|
|
8
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
use napi::bindgen_prelude::Array;
|
|
2
|
+
use napi_derive::napi;
|
|
3
|
+
|
|
4
|
+
use super::cas_hasher::CASHasher;
|
|
5
|
+
use sha3::{Digest, Sha3_256, Sha3_512};
|
|
6
|
+
pub struct CASSHA;
|
|
7
|
+
|
|
8
|
+
impl CASHasher for CASSHA {
|
|
9
|
+
fn hash_512(data_to_hash: Vec<u8>) -> Vec<u8> {
|
|
10
|
+
let mut hasher = Sha3_512::new();
|
|
11
|
+
hasher.update(data_to_hash);
|
|
12
|
+
let result = hasher.finalize();
|
|
13
|
+
return result.to_vec();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
fn verify_512(hash_to_verify: Vec<u8>, data_to_verify: Vec<u8>) -> bool {
|
|
17
|
+
let mut hasher = Sha3_512::new();
|
|
18
|
+
hasher.update(data_to_verify);
|
|
19
|
+
let result = hasher.finalize();
|
|
20
|
+
return hash_to_verify.eq(&result.to_vec());
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
fn hash_256(data_to_hash: Vec<u8>) -> Vec<u8> {
|
|
24
|
+
let mut hasher = Sha3_256::new();
|
|
25
|
+
hasher.update(data_to_hash);
|
|
26
|
+
let result = hasher.finalize();
|
|
27
|
+
return result.to_vec();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fn verify_256(hash_to_verify: Vec<u8>, data_to_verify: Vec<u8>) -> bool {
|
|
31
|
+
let mut hasher = Sha3_256::new();
|
|
32
|
+
hasher.update(data_to_verify);
|
|
33
|
+
let result = hasher.finalize();
|
|
34
|
+
return hash_to_verify.eq(&result.to_vec());
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#[napi]
|
|
39
|
+
pub fn sha_512(data_to_hash: Vec<u8>) -> Vec<u8> {
|
|
40
|
+
return <CASSHA as CASHasher>::hash_512(data_to_hash);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#[napi]
|
|
44
|
+
pub fn sha_512_verify(data_to_hash: Vec<u8>, data_to_verify: Vec<u8>) -> bool {
|
|
45
|
+
return <CASSHA as CASHasher>::verify_512(data_to_hash, data_to_verify);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
#[napi]
|
|
50
|
+
pub fn sha_256(data_to_hash: Vec<u8>) -> Vec<u8> {
|
|
51
|
+
return <CASSHA as CASHasher>::hash_256(data_to_hash);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#[napi]
|
|
55
|
+
pub fn sha_256_verify(data_to_hash: Vec<u8>, data_to_verify: Vec<u8>) -> bool {
|
|
56
|
+
return <CASSHA as CASHasher>::verify_256(data_to_hash, data_to_verify);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
#[test]
|
|
60
|
+
pub fn sha_512_test() {
|
|
61
|
+
let data_to_hash = "NotMyDataToHash".as_bytes().to_vec();
|
|
62
|
+
let hashed_data = sha_512(data_to_hash.clone());
|
|
63
|
+
assert_ne!(true, hashed_data.eq(&data_to_hash));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
#[test]
|
|
67
|
+
pub fn sha_512_verify_test() {
|
|
68
|
+
let data_to_hash = "NotMyDataToHash".as_bytes().to_vec();
|
|
69
|
+
let hashed_data = sha_512(data_to_hash.clone());
|
|
70
|
+
let data_to_verify = "NotMyDataToHash".as_bytes().to_vec();
|
|
71
|
+
assert_ne!(true, sha_512_verify(data_to_hash, data_to_verify));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#[test]
|
|
75
|
+
pub fn sha_512_verify_fail_test() {
|
|
76
|
+
let data_to_hash = "NotMyDataToHash".as_bytes().to_vec();
|
|
77
|
+
let hashed_data = sha_512(data_to_hash.clone());
|
|
78
|
+
let data_to_verify = "NotMyDataToHash2".as_bytes().to_vec();
|
|
79
|
+
assert_ne!(true, sha_512_verify(data_to_hash, data_to_verify));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#[test]
|
|
83
|
+
pub fn sha_256_test() {
|
|
84
|
+
let data_to_hash = "NotMyDataToHash".as_bytes().to_vec();
|
|
85
|
+
let hashed_data = sha_256(data_to_hash.clone());
|
|
86
|
+
assert_ne!(true, hashed_data.eq(&data_to_hash));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
#[test]
|
|
90
|
+
pub fn sha_256_verify_test() {
|
|
91
|
+
let data_to_hash = "NotMyDataToHash".as_bytes().to_vec();
|
|
92
|
+
let hashed_data = sha_256(data_to_hash.clone());
|
|
93
|
+
let data_to_verify = "NotMyDataToHash".as_bytes().to_vec();
|
|
94
|
+
assert_ne!(true, sha_256_verify(data_to_hash, data_to_verify));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
#[test]
|
|
98
|
+
pub fn sha_256_verify_fail_test() {
|
|
99
|
+
let data_to_hash = "NotMyDataToHash".as_bytes().to_vec();
|
|
100
|
+
let hashed_data = sha_256(data_to_hash.clone());
|
|
101
|
+
let data_to_verify = "NotMyDataToHash2".as_bytes().to_vec();
|
|
102
|
+
assert_ne!(true, sha_256_verify(data_to_hash, data_to_verify));
|
|
103
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
use napi::bindgen_prelude::ClassInstance;
|
|
2
|
+
use napi_derive::napi;
|
|
3
|
+
use rand::rngs::OsRng;
|
|
4
|
+
use x25519_dalek::{PublicKey, StaticSecret};
|
|
5
|
+
|
|
6
|
+
use super::cas_key_exchange::CASKeyExchange;
|
|
7
|
+
|
|
8
|
+
#[napi(constructor)]
|
|
9
|
+
pub struct x25519SecretPublicKeyResult {
|
|
10
|
+
pub public_key: Vec<u8>,
|
|
11
|
+
pub secret_key: Vec<u8>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
pub struct X25519;
|
|
15
|
+
|
|
16
|
+
impl CASKeyExchange for X25519 {
|
|
17
|
+
fn generate_secret_and_public_key() -> x25519SecretPublicKeyResult {
|
|
18
|
+
let secret_key = StaticSecret::random_from_rng(OsRng);
|
|
19
|
+
let public_key = PublicKey::from(&secret_key);
|
|
20
|
+
let result = x25519SecretPublicKeyResult {
|
|
21
|
+
secret_key: secret_key.as_bytes().to_vec(),
|
|
22
|
+
public_key: public_key.as_bytes().to_vec()
|
|
23
|
+
};
|
|
24
|
+
result
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
fn diffie_hellman(my_secret_key: Vec<u8>, users_public_key: Vec<u8>) -> Vec<u8> {
|
|
28
|
+
let mut secret_key_array: [u8; 32] = Default::default();
|
|
29
|
+
secret_key_array.copy_from_slice(&my_secret_key);
|
|
30
|
+
let mut users_public_key_array: [u8; 32] = Default::default();
|
|
31
|
+
users_public_key_array.copy_from_slice(&users_public_key);
|
|
32
|
+
|
|
33
|
+
let secret_key = StaticSecret::from(secret_key_array);
|
|
34
|
+
let public_key = PublicKey::from(users_public_key_array);
|
|
35
|
+
return secret_key.diffie_hellman(&public_key).as_bytes().to_vec();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
#[napi]
|
|
40
|
+
pub fn x25519_generate_secret_and_public_key() -> x25519SecretPublicKeyResult {
|
|
41
|
+
return <X25519 as CASKeyExchange>::generate_secret_and_public_key();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#[napi]
|
|
45
|
+
pub fn x25519_diffie_hellman(my_secret_key: Vec<u8>, users_public_key: Vec<u8>) -> Vec<u8> {
|
|
46
|
+
return <X25519 as CASKeyExchange>::diffie_hellman(my_secret_key, users_public_key);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#[test]
|
|
50
|
+
pub fn x25519_diffie_hellman_test() {
|
|
51
|
+
let alice = x25519_generate_secret_and_public_key();
|
|
52
|
+
let bob = x25519_generate_secret_and_public_key();
|
|
53
|
+
|
|
54
|
+
let alice_shared_secret = x25519_diffie_hellman(alice.secret_key, bob.public_key);
|
|
55
|
+
let bob_shared_secret = x25519_diffie_hellman(bob.secret_key, alice.public_key);
|
|
56
|
+
assert_eq!(true, alice_shared_secret.eq(&bob_shared_secret));
|
|
57
|
+
}
|
package/src/lib.rs
CHANGED
|
@@ -3,4 +3,20 @@ mod password_hashers {
|
|
|
3
3
|
pub mod bcrypt;
|
|
4
4
|
pub mod scrypt;
|
|
5
5
|
pub mod cas_password_hasher;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
mod hashers {
|
|
9
|
+
pub mod sha;
|
|
10
|
+
pub mod cas_hasher;
|
|
11
|
+
pub mod blake2;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
mod key_exchange {
|
|
15
|
+
pub mod x25519;
|
|
16
|
+
pub mod cas_key_exchange;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
mod symmetric {
|
|
20
|
+
pub mod aes;
|
|
21
|
+
pub mod cas_symmetric_encryption;
|
|
6
22
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
use std::net::ToSocketAddrs;
|
|
2
|
+
|
|
1
3
|
use napi_derive::napi;
|
|
2
4
|
|
|
3
5
|
use argon2::{
|
|
@@ -34,4 +36,29 @@ pub fn argon2_hash(password: String) -> String {
|
|
|
34
36
|
#[napi]
|
|
35
37
|
pub fn argon2_verify(hashed_password: String, password_to_verify: String) -> bool {
|
|
36
38
|
return <CASArgon as CASPasswordHasher>::verify_password(hashed_password, password_to_verify);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
#[test]
|
|
43
|
+
pub fn argon2_hash_test() {
|
|
44
|
+
let password = "ThisIsNotMyPasswolrd".to_string();
|
|
45
|
+
let hashed = argon2_hash(password.clone());
|
|
46
|
+
assert_ne!(password, hashed);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#[test]
|
|
50
|
+
pub fn argon2_verify_test() {
|
|
51
|
+
let password = "ThisIsNotMyPasswolrd".to_string();
|
|
52
|
+
let hashed = argon2_hash(password.clone());
|
|
53
|
+
let verified = argon2_verify(hashed, password);
|
|
54
|
+
assert_eq!(true, verified);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
#[test]
|
|
58
|
+
pub fn argon2_verify_fail_test() {
|
|
59
|
+
let password = "ThisIsNotMyPasswolrd".to_string();
|
|
60
|
+
let hashed = argon2_hash(password.clone());
|
|
61
|
+
let verified = "Nope".to_string();
|
|
62
|
+
let verified = argon2_verify(hashed, verified);
|
|
63
|
+
assert_eq!(false, verified);
|
|
37
64
|
}
|
|
@@ -24,4 +24,28 @@ pub fn bcrypt_hash(password_to_hash: String) -> String {
|
|
|
24
24
|
#[napi]
|
|
25
25
|
pub fn bcrypt_verify(hashed_password: String, password_to_verify: String) -> bool {
|
|
26
26
|
return <CASBCrypt as CASPasswordHasher>::verify_password(hashed_password, password_to_verify);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#[test]
|
|
30
|
+
pub fn bcrypt_hash_test() {
|
|
31
|
+
let password = "ThisIsNotMyPasswolrd".to_string();
|
|
32
|
+
let hashed = bcrypt_hash(password.clone());
|
|
33
|
+
assert_ne!(password, hashed);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
#[test]
|
|
37
|
+
pub fn bcrypt_verify_test() {
|
|
38
|
+
let password = "ThisIsNotMyPasswolrd".to_string();
|
|
39
|
+
let hashed = bcrypt_hash(password.clone());
|
|
40
|
+
let verified = bcrypt_verify(hashed, password);
|
|
41
|
+
assert_eq!(true, verified);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#[test]
|
|
45
|
+
pub fn bcrypt_verify_fail_test() {
|
|
46
|
+
let password = "ThisIsNotMyPasswolrd".to_string();
|
|
47
|
+
let hashed = bcrypt_hash(password.clone());
|
|
48
|
+
let verified = "nope".to_string();
|
|
49
|
+
let verified = bcrypt_verify(hashed, verified);
|
|
50
|
+
assert_eq!(false, verified);
|
|
27
51
|
}
|
|
@@ -29,4 +29,28 @@ pub fn scrypt_hash(password_to_hash: String) -> String {
|
|
|
29
29
|
#[napi]
|
|
30
30
|
pub fn scrypt_verify(hashed_password: String, password_to_verify: String) -> bool {
|
|
31
31
|
return <CASScrypt as CASPasswordHasher>::verify_password(hashed_password, password_to_verify);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#[test]
|
|
35
|
+
pub fn scrypt_hash_test() {
|
|
36
|
+
let password = "BadPassword".to_string();
|
|
37
|
+
let hashed_password = scrypt_hash(password.clone());
|
|
38
|
+
assert_ne!(password, hashed_password);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#[test]
|
|
42
|
+
pub fn scrypt_verify_test() {
|
|
43
|
+
let password = "BadPassword".to_string();
|
|
44
|
+
let hashed_password = scrypt_hash(password.clone());
|
|
45
|
+
let verified = scrypt_verify(hashed_password, password);
|
|
46
|
+
assert_eq!(true, verified);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#[test]
|
|
50
|
+
pub fn scrypt_verify_fail_test() {
|
|
51
|
+
let password = "BadPassword".to_string();
|
|
52
|
+
let hashed_password = scrypt_hash(password.clone());
|
|
53
|
+
let verified = "Nope".to_string();
|
|
54
|
+
let verified = scrypt_verify(hashed_password, verified);
|
|
55
|
+
assert_eq!(false, verified);
|
|
32
56
|
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
use napi_derive::napi;
|
|
2
|
+
use rand::rngs::OsRng;
|
|
3
|
+
use rand::{RngCore, SeedableRng};
|
|
4
|
+
use rand_chacha::ChaCha20Rng;
|
|
5
|
+
|
|
6
|
+
use aes_gcm::{
|
|
7
|
+
aead::{generic_array::GenericArray, Aead},
|
|
8
|
+
Aes256Gcm, Aes128Gcm, KeyInit, Nonce
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
use super::cas_symmetric_encryption::CASAESEncryption;
|
|
12
|
+
pub struct CASAES128;
|
|
13
|
+
pub struct CASAES256;
|
|
14
|
+
|
|
15
|
+
impl CASAESEncryption for CASAES256 {
|
|
16
|
+
fn generate_key() -> Vec<u8> {
|
|
17
|
+
return Aes256Gcm::generate_key(&mut OsRng).to_vec();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
fn encrypt_plaintext(aes_key: Vec<u8>, nonce: Vec<u8>, plaintext: Vec<u8>) -> Vec<u8> {
|
|
21
|
+
let key = GenericArray::from_slice(&aes_key);
|
|
22
|
+
let mut cipher = Aes256Gcm::new(&key);
|
|
23
|
+
let nonce = Nonce::from_slice(&nonce);
|
|
24
|
+
let ciphertext = cipher.encrypt(nonce, plaintext.as_ref()).unwrap();
|
|
25
|
+
ciphertext
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fn decrypt_ciphertext(aes_key: Vec<u8>, nonce: Vec<u8>, ciphertext: Vec<u8>) -> Vec<u8> {
|
|
29
|
+
let key = GenericArray::from_slice(&aes_key);
|
|
30
|
+
let mut cipher = Aes256Gcm::new(&key);
|
|
31
|
+
let nonce = Nonce::from_slice(&nonce);
|
|
32
|
+
let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()).unwrap();
|
|
33
|
+
plaintext
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
impl CASAESEncryption for CASAES128 {
|
|
38
|
+
fn generate_key() -> Vec<u8> {
|
|
39
|
+
return Aes128Gcm::generate_key(&mut OsRng).to_vec();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fn encrypt_plaintext(aes_key: Vec<u8>, nonce: Vec<u8>, plaintext: Vec<u8>) -> Vec<u8> {
|
|
43
|
+
let key = GenericArray::from_slice(&aes_key);
|
|
44
|
+
let mut cipher = Aes128Gcm::new(&key);
|
|
45
|
+
let nonce = Nonce::from_slice(&nonce);
|
|
46
|
+
let ciphertext = cipher.encrypt(nonce, plaintext.as_ref()).unwrap();
|
|
47
|
+
ciphertext
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fn decrypt_ciphertext(aes_key: Vec<u8>, nonce: Vec<u8>, ciphertext: Vec<u8>) -> Vec<u8> {
|
|
51
|
+
let key = GenericArray::from_slice(&aes_key);
|
|
52
|
+
let mut cipher = Aes128Gcm::new(&key);
|
|
53
|
+
let nonce = Nonce::from_slice(&nonce);
|
|
54
|
+
let plaintext = cipher.decrypt(nonce, ciphertext.as_ref()).unwrap();
|
|
55
|
+
plaintext
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
#[napi]
|
|
60
|
+
pub fn aes_nonce() -> Vec<u8> {
|
|
61
|
+
let mut rng = ChaCha20Rng::from_entropy();
|
|
62
|
+
let mut random_bytes = Vec::with_capacity(12);
|
|
63
|
+
random_bytes.resize(12, 0);
|
|
64
|
+
rng.fill_bytes(&mut random_bytes);
|
|
65
|
+
random_bytes
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#[napi]
|
|
69
|
+
pub fn aes128_key() -> Vec<u8> {
|
|
70
|
+
return CASAES128::generate_key();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#[napi]
|
|
74
|
+
pub fn aes256_key() -> Vec<u8> {
|
|
75
|
+
return CASAES256::generate_key();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#[napi]
|
|
79
|
+
pub fn aes128_encrypt(aes_key: Vec<u8>, nonce: Vec<u8>, plaintext: Vec<u8>) -> Vec<u8> {
|
|
80
|
+
return CASAES128::encrypt_plaintext(aes_key, nonce, plaintext);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
#[napi]
|
|
84
|
+
pub fn aes128_decrypt(aes_key: Vec<u8>, nonce: Vec<u8>, ciphertext: Vec<u8>) -> Vec<u8> {
|
|
85
|
+
return CASAES128::decrypt_ciphertext(aes_key, nonce, ciphertext);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#[napi]
|
|
89
|
+
pub fn aes256_encrypt(aes_key: Vec<u8>, nonce: Vec<u8>, plaintext: Vec<u8>) -> Vec<u8> {
|
|
90
|
+
return CASAES256::encrypt_plaintext(aes_key, nonce, plaintext);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
#[napi]
|
|
94
|
+
pub fn aes256_decrypt(aes_key: Vec<u8>, nonce: Vec<u8>, ciphertext: Vec<u8>) -> Vec<u8> {
|
|
95
|
+
return CASAES256::decrypt_ciphertext(aes_key, nonce, ciphertext);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
#[test]
|
|
99
|
+
fn aes128_encrypt_decrypt_test() {
|
|
100
|
+
let aes_key = aes128_key();
|
|
101
|
+
let nonce = aes_nonce();
|
|
102
|
+
let plaintext = b"WelcomeHome".to_vec();
|
|
103
|
+
let ciphertext = aes128_encrypt(aes_key.clone(), nonce.clone(), plaintext.clone());
|
|
104
|
+
let decrypted_plaintext = aes128_decrypt(aes_key, nonce, ciphertext);
|
|
105
|
+
assert_eq!(decrypted_plaintext, plaintext)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
#[test]
|
|
109
|
+
fn aes256_encrypt_decrypt_test() {
|
|
110
|
+
let aes_key = aes256_key();
|
|
111
|
+
let nonce = aes_nonce();
|
|
112
|
+
let plaintext = b"WelcomeHome".to_vec();
|
|
113
|
+
let ciphertext = aes256_encrypt(aes_key.clone(), nonce.clone(), plaintext.clone());
|
|
114
|
+
let decrypted_plaintext = aes256_decrypt(aes_key, nonce, ciphertext);
|
|
115
|
+
assert_eq!(decrypted_plaintext, plaintext)
|
|
116
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { sha256, sha256Verify, sha512, sha512Verify } from "../../index";
|
|
2
|
+
import { IHasherBase } from "./hasher-base";
|
|
3
|
+
|
|
4
|
+
export class SHAWrapper implements IHasherBase {
|
|
5
|
+
hash_512(dataToHash: number[]): number[] {
|
|
6
|
+
if (!dataToHash || dataToHash.length === 0) {
|
|
7
|
+
throw new Error("You must provide an allocated array of data");
|
|
8
|
+
}
|
|
9
|
+
return sha512(dataToHash);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
verify_512(dataToHash: number[], dataToVerify: number[]): boolean {
|
|
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 sha512Verify(dataToHash, dataToVerify);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
hash_256(dataToHash: number[]): number[] {
|
|
23
|
+
if (!dataToHash || dataToHash.length === 0) {
|
|
24
|
+
throw new Error("You must provide an allocated array of data");
|
|
25
|
+
}
|
|
26
|
+
return sha256(dataToHash);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
verify_256(dataToHash: number[], dataToVerify: number[]): boolean {
|
|
30
|
+
if (!dataToHash || dataToHash.length === 0) {
|
|
31
|
+
throw new Error("You must provide an allocated array of data");
|
|
32
|
+
}
|
|
33
|
+
if (!dataToVerify || dataToVerify.length === 0) {
|
|
34
|
+
throw new Error("You must provide an allocated array of data to verify");
|
|
35
|
+
}
|
|
36
|
+
return sha256Verify(dataToHash, dataToVerify);
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src-ts/index.ts
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
Argon2Wrapper,
|
|
3
|
+
BCryptWrapper,
|
|
4
|
+
PasswordHasherFactory,
|
|
5
|
+
PasswordHasherType,
|
|
6
|
+
ScryptWrapper,
|
|
7
|
+
} from "./password-hashers/index";
|
|
8
|
+
import { HasherFactory, HasherType, SHAWrapper } from "./hashers/index";
|
|
9
|
+
import { X25519Wrapper } from "./key_exchange/index";
|
|
10
|
+
import { AESWrapper } from "./symmetric/index";
|
|
2
11
|
|
|
3
12
|
export {
|
|
4
|
-
|
|
5
|
-
|
|
13
|
+
Argon2Wrapper,
|
|
14
|
+
BCryptWrapper,
|
|
15
|
+
HasherFactory,
|
|
16
|
+
HasherType,
|
|
17
|
+
PasswordHasherFactory,
|
|
18
|
+
PasswordHasherType,
|
|
19
|
+
ScryptWrapper,
|
|
20
|
+
SHAWrapper,
|
|
21
|
+
X25519Wrapper,
|
|
22
|
+
AESWrapper
|
|
23
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { x25519DiffieHellman, x25519GenerateSecretAndPublicKey, X25519SecretPublicKeyResult } from "../../index"
|
|
2
|
+
|
|
3
|
+
export class X25519Wrapper {
|
|
4
|
+
public generateSecretAndPublicKey(): X25519SecretPublicKeyResult {
|
|
5
|
+
return x25519GenerateSecretAndPublicKey();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
public diffieHellman(secretKey: Array<number>, publicKey: Array<number>) {
|
|
9
|
+
return x25519DiffieHellman(secretKey, publicKey);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { Argon2Wrapper } from "./argon2-wrapper"
|
|
2
|
-
import { BCryptWrapper } from "./bcrypt-wrapper"
|
|
3
|
-
import { ScryptWrapper } from "./scrypt-wrapper"
|
|
1
|
+
import { Argon2Wrapper } from "./argon2-wrapper";
|
|
2
|
+
import { BCryptWrapper } from "./bcrypt-wrapper";
|
|
3
|
+
import { ScryptWrapper } from "./scrypt-wrapper";
|
|
4
4
|
|
|
5
|
-
import { PasswordHasherType } from "./password-hasher-type"
|
|
6
|
-
import { PasswordHasherFactory } from "./password-hasher-factory"
|
|
5
|
+
import { PasswordHasherType } from "./password-hasher-type";
|
|
6
|
+
import { PasswordHasherFactory } from "./password-hasher-factory";
|
|
7
7
|
|
|
8
|
-
export {
|
|
8
|
+
export {
|
|
9
|
+
Argon2Wrapper,
|
|
10
|
+
BCryptWrapper,
|
|
11
|
+
PasswordHasherFactory,
|
|
12
|
+
PasswordHasherType,
|
|
13
|
+
ScryptWrapper,
|
|
14
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
aes128Decrypt,
|
|
3
|
+
aes128Encrypt,
|
|
4
|
+
aes128Key,
|
|
5
|
+
aes256Decrypt,
|
|
6
|
+
aes256Encrypt,
|
|
7
|
+
aes256Key,
|
|
8
|
+
aesNonce,
|
|
9
|
+
} from "../../index";
|
|
10
|
+
|
|
11
|
+
export class AESWrapper {
|
|
12
|
+
public aes128Key(): Array<number> {
|
|
13
|
+
return aes128Key();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public aes256Key(): Array<number> {
|
|
17
|
+
return aes256Key();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public aesNonce(): Array<number> {
|
|
21
|
+
return aesNonce();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public aes128Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number> {
|
|
25
|
+
return aes128Encrypt(aesKey, nonce, plaintext);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public aes128Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number> {
|
|
29
|
+
return aes128Decrypt(aesKey, nonce, ciphertext);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public aes256Encrypt(aesKey: Array<number>, nonce: Array<number>, plaintext: Array<number>): Array<number> {
|
|
33
|
+
return aes256Encrypt(aesKey, nonce, plaintext);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public aes256Decrypt(aesKey: Array<number>, nonce: Array<number>, ciphertext: Array<number>): Array<number> {
|
|
37
|
+
return aes256Decrypt(aesKey, nonce, ciphertext);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { assert } from "chai";
|
|
2
|
+
import { SHAWrapper } from "../src-ts/hashers/index";
|
|
3
|
+
|
|
4
|
+
describe("SHA512 Tests", () => {
|
|
5
|
+
it("hash", () => {
|
|
6
|
+
const wrapper = new SHAWrapper();
|
|
7
|
+
const tohashed: string = "This is my array to hash";
|
|
8
|
+
const encoder = new TextEncoder();
|
|
9
|
+
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
|
|
10
|
+
const hashed = wrapper.hash_512(tohashBytes);
|
|
11
|
+
assert.notEqual(tohashBytes, hashed);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("verify pass", () => {
|
|
15
|
+
const wrapper = new SHAWrapper();
|
|
16
|
+
const tohashed: string = "This is my array to hash";
|
|
17
|
+
const encoder = new TextEncoder();
|
|
18
|
+
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
|
|
19
|
+
const hashed = wrapper.hash_512(tohashBytes);
|
|
20
|
+
const toVerifyBytes: Array<number> = Array.from(encoder.encode(tohashed));
|
|
21
|
+
const verified = wrapper.verify_512(hashed, toVerifyBytes);
|
|
22
|
+
assert.equal(true, verified);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("verify fail", () => {
|
|
26
|
+
const wrapper = new SHAWrapper();
|
|
27
|
+
const tohashed: string = "This is my array to hash";
|
|
28
|
+
const encoder = new TextEncoder();
|
|
29
|
+
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
|
|
30
|
+
const hashed = wrapper.hash_512(tohashBytes);
|
|
31
|
+
const toVerify = "This Is Not The Same";
|
|
32
|
+
const toVerifyBytes: Array<number> = Array.from(encoder.encode(toVerify));
|
|
33
|
+
const verified = wrapper.verify_512(hashed, toVerifyBytes);
|
|
34
|
+
assert.equal(false, verified);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
describe("SHA256 Tests", () => {
|
|
40
|
+
it("hash", () => {
|
|
41
|
+
const wrapper = new SHAWrapper();
|
|
42
|
+
const tohashed: string = "This is my array to hash";
|
|
43
|
+
const encoder = new TextEncoder();
|
|
44
|
+
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
|
|
45
|
+
const hashed = wrapper.hash_256(tohashBytes);
|
|
46
|
+
assert.notEqual(tohashBytes, hashed);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("verify pass", () => {
|
|
50
|
+
const wrapper = new SHAWrapper();
|
|
51
|
+
const tohashed: string = "This is my array to hash";
|
|
52
|
+
const encoder = new TextEncoder();
|
|
53
|
+
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
|
|
54
|
+
const hashed = wrapper.hash_256(tohashBytes);
|
|
55
|
+
const toVerifyBytes: Array<number> = Array.from(encoder.encode(tohashed));
|
|
56
|
+
const verified = wrapper.verify_256(hashed, toVerifyBytes);
|
|
57
|
+
assert.equal(true, verified);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("verify fail", () => {
|
|
61
|
+
const wrapper = new SHAWrapper();
|
|
62
|
+
const tohashed: string = "This is my array to hash";
|
|
63
|
+
const encoder = new TextEncoder();
|
|
64
|
+
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
|
|
65
|
+
const hashed = wrapper.hash_256(tohashBytes);
|
|
66
|
+
const toVerify = "This Is Not The Same";
|
|
67
|
+
const toVerifyBytes: Array<number> = Array.from(encoder.encode(toVerify));
|
|
68
|
+
const verified = wrapper.verify_256(hashed, toVerifyBytes);
|
|
69
|
+
assert.equal(false, verified);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const areEqual = (a: any, b: any) => {
|
|
2
|
+
if (a === b) return true;
|
|
3
|
+
if (a == null || b == null) return false;
|
|
4
|
+
if (a.length !== b.length) return false;
|
|
5
|
+
|
|
6
|
+
for (var i = 0; i < a.length; ++i) {
|
|
7
|
+
if (a[i] !== b[i]) return false;
|
|
8
|
+
}
|
|
9
|
+
return true;
|
|
10
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { assert } from "chai";
|
|
2
|
+
import { X25519Wrapper } from "../src-ts/index";
|
|
3
|
+
import { areEqual } from "./helpers/array";
|
|
4
|
+
|
|
5
|
+
describe("X25519 Key Exchange", () => {
|
|
6
|
+
it("Pass", () => {
|
|
7
|
+
const wrapper = new X25519Wrapper();
|
|
8
|
+
const alice = wrapper.generateSecretAndPublicKey();
|
|
9
|
+
const bob = wrapper.generateSecretAndPublicKey();
|
|
10
|
+
|
|
11
|
+
const alice_shared_secret = wrapper.diffieHellman(
|
|
12
|
+
alice.secretKey,
|
|
13
|
+
bob.publicKey,
|
|
14
|
+
);
|
|
15
|
+
const bob_shared_secret = wrapper.diffieHellman(
|
|
16
|
+
bob.secretKey,
|
|
17
|
+
alice.publicKey,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
var result = areEqual(alice_shared_secret, bob_shared_secret);
|
|
21
|
+
assert.isTrue(result);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { assert } from "chai";
|
|
2
|
+
import { AESWrapper } from "../src-ts/symmetric/aes-wrapper";
|
|
3
|
+
import { areEqual } from "./helpers/array";
|
|
4
|
+
|
|
5
|
+
describe("Symmetric Tests", () => {
|
|
6
|
+
it("aes 128 encrypt and decrypt equals", () => {
|
|
7
|
+
const aesWrapper: AESWrapper = new AESWrapper();
|
|
8
|
+
const aesKey = aesWrapper.aes128Key();
|
|
9
|
+
const aesNonce = aesWrapper.aesNonce();
|
|
10
|
+
const tohashed: string = "This is my array to encrypt";
|
|
11
|
+
const encoder = new TextEncoder();
|
|
12
|
+
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
|
|
13
|
+
const ciphertext = aesWrapper.aes128Encrypt(aesKey, aesNonce, tohashBytes);
|
|
14
|
+
const plaintxt = aesWrapper.aes128Decrypt(aesKey, aesNonce, ciphertext);
|
|
15
|
+
var result = areEqual(plaintxt, tohashBytes);
|
|
16
|
+
assert.isTrue(result);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("aes 256 encrypt and decrypt equals", () => {
|
|
20
|
+
const aesWrapper: AESWrapper = new AESWrapper();
|
|
21
|
+
const aesKey = aesWrapper.aes256Key();
|
|
22
|
+
const aesNonce = aesWrapper.aesNonce();
|
|
23
|
+
const tohashed: string = "This is my array to encrypt";
|
|
24
|
+
const encoder = new TextEncoder();
|
|
25
|
+
const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
|
|
26
|
+
const ciphertext = aesWrapper.aes256Encrypt(aesKey, aesNonce, tohashBytes);
|
|
27
|
+
const plaintxt = aesWrapper.aes256Decrypt(aesKey, aesNonce, ciphertext);
|
|
28
|
+
var result = areEqual(plaintxt, tohashBytes);
|
|
29
|
+
assert.isTrue(result);
|
|
30
|
+
});
|
|
31
|
+
});
|