cas-typescript-sdk 1.0.10 → 1.0.11

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 CHANGED
@@ -16,6 +16,7 @@ napi = "2"
16
16
  napi-derive = "2"
17
17
  rand = "0.8.5"
18
18
  rand_chacha = "0.3.1"
19
+ rsa = "0.9.6"
19
20
  scrypt = "0.11.0"
20
21
  sha3 = "0.10.8"
21
22
  x25519-dalek = {version = "2.0.0", features = ["static_secrets"] }
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # eas-typescript-sdk
2
2
 
3
+ Ever wanted all of your most useful cryptograpihc operations in one module and not have to surf documentation for various packages?
4
+ CAS is here to provide a unified development experience as an abstract layer to the RustCrypto and Dalek-Cryptography suite of algorithms.
3
5
  The official NPM page can be found [here](https://www.npmjs.com/package/cas-typescript-sdk).
4
6
 
5
7
  ## Consuming Library Documentation
package/index.d.ts CHANGED
@@ -22,9 +22,20 @@ 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 generateRsaKeys(keySize: number): RsaKeyPairResult
26
+ export function encryptPlaintextRsa(publicKey: string, plaintext: Array<number>): Array<number>
27
+ export function decryptCiphertextRsa(privateKey: string, ciphertext: Array<number>): Array<number>
28
+ export function signRsa(privateKey: string, hash: Array<number>): Array<number>
29
+ export function verifyRsa(publicKey: string, hash: Array<number>, signature: Array<number>): boolean
25
30
  export type x25519SecretPublicKeyResult = X25519SecretPublicKeyResult
26
31
  export class X25519SecretPublicKeyResult {
27
32
  publicKey: Array<number>
28
33
  secretKey: Array<number>
29
34
  constructor(publicKey: Array<number>, secretKey: Array<number>)
30
35
  }
36
+ export type RSAKeyPairResult = RsaKeyPairResult
37
+ export class RsaKeyPairResult {
38
+ privateKey: string
39
+ publicKey: string
40
+ constructor(privateKey: string, publicKey: string)
41
+ }
package/index.node CHANGED
Binary file
@@ -0,0 +1,8 @@
1
+ import { RsaKeyPairResult } from "../../index";
2
+ export declare class RSAWrapper {
3
+ generateKeys(keySize: number): RsaKeyPairResult;
4
+ encrypt(publicKey: string, plaintext: Array<number>): Array<number>;
5
+ decrypt(privateKey: string, ciphertext: Array<number>): Array<number>;
6
+ sign(privateKey: string, hash: Array<number>): Array<number>;
7
+ verify(publicKey: string, hash: Array<number>, signature: Array<number>): boolean;
8
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RSAWrapper = void 0;
4
+ const index_1 = require("../../index");
5
+ class RSAWrapper {
6
+ generateKeys(keySize) {
7
+ if (keySize !== 1024 && keySize !== 2048 && keySize !== 4096) {
8
+ throw new Error("You must provide an appropriate key size to generate RSA keys");
9
+ }
10
+ return (0, index_1.generateRsaKeys)(keySize);
11
+ }
12
+ encrypt(publicKey, plaintext) {
13
+ if (!publicKey) {
14
+ throw new Error("You must provide a public key to encrypt with RSA");
15
+ }
16
+ if (!plaintext || plaintext.length === 0) {
17
+ throw new Error("You must provide an array of plaintext bytes to encrypt with RSA");
18
+ }
19
+ return (0, index_1.encryptPlaintextRsa)(publicKey, plaintext);
20
+ }
21
+ decrypt(privateKey, ciphertext) {
22
+ if (!privateKey) {
23
+ throw new Error("You must provide a private key to encrypt with RSA");
24
+ }
25
+ if (!ciphertext || ciphertext.length === 0) {
26
+ throw new Error("You must provide an array of ciphertext bytes to encrypt with RSA");
27
+ }
28
+ return (0, index_1.decryptCiphertextRsa)(privateKey, ciphertext);
29
+ }
30
+ sign(privateKey, hash) {
31
+ if (!privateKey) {
32
+ throw new Error("You must provide a private key to sign with RSA");
33
+ }
34
+ if (!hash || hash.length === 0) {
35
+ throw new Error("You must provide an allocated hash to sign with RSA");
36
+ }
37
+ return (0, index_1.signRsa)(privateKey, hash);
38
+ }
39
+ verify(publicKey, hash, signature) {
40
+ if (!publicKey) {
41
+ throw new Error("You must provide a public key to verify with RSA");
42
+ }
43
+ if (!hash || hash.length === 0) {
44
+ throw new Error("You must provide an allocated hash to verify with RSA");
45
+ }
46
+ if (!signature || signature.length === 0) {
47
+ throw new Error("You must provide and allocated signature to verify with RSA");
48
+ }
49
+ return (0, index_1.verifyRsa)(publicKey, hash, signature);
50
+ }
51
+ }
52
+ exports.RSAWrapper = RSAWrapper;
@@ -0,0 +1,3 @@
1
+ import { RSAWrapper } from "./RSAWrapper";
2
+ import { RsaKeyPairResult } from "../../index";
3
+ export { RSAWrapper, RsaKeyPairResult };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RsaKeyPairResult = exports.RSAWrapper = void 0;
4
+ const RSAWrapper_1 = require("./RSAWrapper");
5
+ Object.defineProperty(exports, "RSAWrapper", { enumerable: true, get: function () { return RSAWrapper_1.RSAWrapper; } });
6
+ const index_1 = require("../../index");
7
+ Object.defineProperty(exports, "RsaKeyPairResult", { enumerable: true, get: function () { return index_1.RsaKeyPairResult; } });
package/lib/index.d.ts CHANGED
@@ -2,4 +2,5 @@ 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
- export { Argon2Wrapper, BCryptWrapper, HasherFactory, HasherType, PasswordHasherFactory, PasswordHasherType, ScryptWrapper, SHAWrapper, X25519Wrapper, AESWrapper };
5
+ import { RSAWrapper, RsaKeyPairResult } from "./asymmetric";
6
+ export { Argon2Wrapper, BCryptWrapper, HasherFactory, HasherType, PasswordHasherFactory, PasswordHasherType, ScryptWrapper, SHAWrapper, X25519Wrapper, AESWrapper, RSAWrapper, RsaKeyPairResult };
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AESWrapper = exports.X25519Wrapper = exports.SHAWrapper = exports.ScryptWrapper = exports.PasswordHasherType = exports.PasswordHasherFactory = exports.HasherType = exports.HasherFactory = exports.BCryptWrapper = exports.Argon2Wrapper = void 0;
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;
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,3 +15,6 @@ 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; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cas-typescript-sdk",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -0,0 +1,15 @@
1
+ use napi_derive::napi;
2
+
3
+ #[napi(constructor)]
4
+ pub struct RSAKeyPairResult {
5
+ pub private_key: String,
6
+ pub public_key: String
7
+ }
8
+
9
+ pub trait CASRSAEncryption {
10
+ fn generate_rsa_keys(key_size: u32) -> RSAKeyPairResult;
11
+ fn encrypt_plaintext(public_key: String, plaintext: Vec<u8>) -> Vec<u8>;
12
+ fn decrypt_ciphertext(private_key: String, ciphertext: Vec<u8>) -> Vec<u8>;
13
+ fn sign(private_key: String, hash: Vec<u8>) -> Vec<u8>;
14
+ fn verify(public_key: String, hash: Vec<u8>, signed_text: Vec<u8>) -> bool;
15
+ }
@@ -0,0 +1,80 @@
1
+ use napi_derive::napi;
2
+ use rand::rngs::OsRng;
3
+ use rsa::{
4
+ pkcs1::{DecodeRsaPublicKey, EncodeRsaPublicKey}, pkcs8::{DecodePrivateKey, EncodePrivateKey}, Pkcs1v15Encrypt, Pkcs1v15Sign, RsaPrivateKey, RsaPublicKey
5
+ };
6
+
7
+ use super::cas_asymmetric_encryption::{CASRSAEncryption, RSAKeyPairResult};
8
+ pub struct CASRSA;
9
+
10
+ impl CASRSAEncryption for CASRSA {
11
+ fn generate_rsa_keys(key_size: u32) -> RSAKeyPairResult {
12
+ let mut rng: OsRng = OsRng;
13
+ let private_key: RsaPrivateKey = RsaPrivateKey::new(&mut rng, key_size as usize).expect("failed to generate a key");
14
+ let public_key: RsaPublicKey = private_key.to_public_key();
15
+ let result = RSAKeyPairResult {
16
+ public_key: public_key.to_pkcs1_pem(rsa::pkcs1::LineEnding::LF).unwrap().to_string(),
17
+ private_key: private_key.to_pkcs8_pem(rsa::pkcs8::LineEnding::LF).unwrap().to_string()
18
+ };
19
+ result
20
+ }
21
+
22
+ fn encrypt_plaintext(public_key: String, plaintext: Vec<u8>) -> Vec<u8> {
23
+ let public_key = RsaPublicKey::from_pkcs1_pem(&public_key).unwrap();
24
+ let mut rng = rand::thread_rng();
25
+ let ciphertext = public_key.encrypt(&mut rng, Pkcs1v15Encrypt, &plaintext).unwrap();
26
+ ciphertext
27
+ }
28
+
29
+ fn decrypt_ciphertext(private_key: String, ciphertext: Vec<u8>) -> Vec<u8> {
30
+ let private_key = RsaPrivateKey::from_pkcs8_pem(&private_key).unwrap();
31
+ let plaintext = private_key.decrypt(Pkcs1v15Encrypt, &ciphertext).unwrap();
32
+ plaintext
33
+ }
34
+
35
+ fn sign(private_key: String, hash: Vec<u8>) -> Vec<u8> {
36
+ let private_key = RsaPrivateKey::from_pkcs8_pem(&private_key).unwrap();
37
+ let mut signed_data = private_key.sign(Pkcs1v15Sign::new_unprefixed(), &hash).unwrap();
38
+ signed_data
39
+ }
40
+
41
+ fn verify(public_key: String, hash: Vec<u8>, signature: Vec<u8>) -> bool {
42
+ let public_key = RsaPublicKey::from_pkcs1_pem(&public_key).unwrap();
43
+ let verified = public_key.verify(
44
+ Pkcs1v15Sign::new_unprefixed(),
45
+ &hash,
46
+ &signature,
47
+ );
48
+ if verified.is_err() == false {
49
+ return true;
50
+ } else {
51
+ return false;
52
+ }
53
+ }
54
+ }
55
+
56
+
57
+ #[napi]
58
+ pub fn generate_rsa_keys(key_size: u32) -> RSAKeyPairResult {
59
+ return CASRSA::generate_rsa_keys(key_size);
60
+ }
61
+
62
+ #[napi]
63
+ pub fn encrypt_plaintext_rsa(public_key: String, plaintext: Vec<u8>) -> Vec<u8> {
64
+ return CASRSA::encrypt_plaintext(public_key, plaintext);
65
+ }
66
+
67
+ #[napi]
68
+ pub fn decrypt_ciphertext_rsa(private_key: String, ciphertext: Vec<u8>) -> Vec<u8> {
69
+ return CASRSA::decrypt_ciphertext(private_key, ciphertext);
70
+ }
71
+
72
+ #[napi]
73
+ pub fn sign_rsa(private_key: String, hash: Vec<u8>) -> Vec<u8> {
74
+ return CASRSA::sign(private_key, hash);
75
+ }
76
+
77
+ #[napi]
78
+ pub fn verify_rsa(public_key: String, hash: Vec<u8>, signature: Vec<u8>) -> bool {
79
+ return CASRSA::verify(public_key, hash, signature);
80
+ }
package/src/lib.rs CHANGED
@@ -19,4 +19,9 @@ mod key_exchange {
19
19
  mod symmetric {
20
20
  pub mod aes;
21
21
  pub mod cas_symmetric_encryption;
22
+ }
23
+
24
+ mod asymmetric {
25
+ pub mod cas_asymmetric_encryption;
26
+ pub mod cas_rsa;
22
27
  }
@@ -0,0 +1,53 @@
1
+ import { decryptCiphertextRsa, encryptPlaintextRsa, generateRsaKeys, RsaKeyPairResult, signRsa, verifyRsa } from "../../index";
2
+
3
+ export class RSAWrapper {
4
+ public generateKeys(keySize: number): RsaKeyPairResult {
5
+ if (keySize !== 1024 && keySize !== 2048 && keySize !== 4096) {
6
+ throw new Error("You must provide an appropriate key size to generate RSA keys");
7
+ }
8
+ return generateRsaKeys(keySize);
9
+ }
10
+
11
+ public encrypt(publicKey: string, plaintext: Array<number>): Array<number> {
12
+ if (!publicKey) {
13
+ throw new Error("You must provide a public key to encrypt with RSA");
14
+ }
15
+ if (!plaintext || plaintext.length === 0) {
16
+ throw new Error("You must provide an array of plaintext bytes to encrypt with RSA");
17
+ }
18
+ return encryptPlaintextRsa(publicKey, plaintext);
19
+ }
20
+
21
+ public decrypt(privateKey: string, ciphertext: Array<number>): Array<number> {
22
+ if (!privateKey) {
23
+ throw new Error("You must provide a private key to encrypt with RSA");
24
+ }
25
+ if (!ciphertext || ciphertext.length === 0) {
26
+ throw new Error("You must provide an array of ciphertext bytes to encrypt with RSA");
27
+ }
28
+ return decryptCiphertextRsa(privateKey, ciphertext);
29
+ }
30
+
31
+ public sign(privateKey: string, hash: Array<number>): Array<number> {
32
+ if (!privateKey) {
33
+ throw new Error("You must provide a private key to sign with RSA");
34
+ }
35
+ if (!hash || hash.length === 0) {
36
+ throw new Error("You must provide an allocated hash to sign with RSA");
37
+ }
38
+ return signRsa(privateKey, hash);
39
+ }
40
+
41
+ public verify(publicKey: string, hash: Array<number>, signature: Array<number>): boolean {
42
+ if (!publicKey) {
43
+ throw new Error("You must provide a public key to verify with RSA");
44
+ }
45
+ if (!hash || hash.length === 0) {
46
+ throw new Error("You must provide an allocated hash to verify with RSA");
47
+ }
48
+ if (!signature || signature.length === 0) {
49
+ throw new Error("You must provide and allocated signature to verify with RSA");
50
+ }
51
+ return verifyRsa(publicKey, hash, signature);
52
+ }
53
+ }
@@ -0,0 +1,4 @@
1
+ import { RSAWrapper } from "./RSAWrapper";
2
+ import { RsaKeyPairResult } from "../../index";
3
+
4
+ export { RSAWrapper, RsaKeyPairResult };
package/src-ts/index.ts CHANGED
@@ -8,6 +8,7 @@ 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
12
 
12
13
  export {
13
14
  Argon2Wrapper,
@@ -19,5 +20,7 @@ export {
19
20
  ScryptWrapper,
20
21
  SHAWrapper,
21
22
  X25519Wrapper,
22
- AESWrapper
23
+ AESWrapper,
24
+ RSAWrapper,
25
+ RsaKeyPairResult
23
26
  };
@@ -0,0 +1,28 @@
1
+ import { assert } from "chai";
2
+ import { RSAWrapper, RsaKeyPairResult } from "..";
3
+ import { areEqual } from "./helpers/array";
4
+
5
+ describe("Asymmetric Tests", () => {
6
+ it("RSA 4096 encrypt and decrypt equals", () => {
7
+ const rsaWrapper: RSAWrapper = new RSAWrapper();
8
+ const keys: RsaKeyPairResult = rsaWrapper.generateKeys(4096);
9
+ const tohashed: string = "This is my array to encrypt";
10
+ const encoder = new TextEncoder();
11
+ const tohashBytes: Array<number> = Array.from(encoder.encode(tohashed));
12
+ const ciphertext = rsaWrapper.encrypt(keys.publicKey, tohashBytes);
13
+ const plaintext = rsaWrapper.decrypt(keys.privateKey, ciphertext);
14
+ let result = areEqual(tohashBytes, plaintext);
15
+ assert.isTrue(result);
16
+ });
17
+
18
+ it("RSA 2048 Sign and Verify", () => {
19
+ const rsaWrapper = new RSAWrapper();
20
+ const keys: RsaKeyPairResult = rsaWrapper.generateKeys(2048);
21
+ const tohashed: string = "This is my encrypt";
22
+ const encoder = new TextEncoder();
23
+ const toSignBytes: Array<number> = Array.from(encoder.encode(tohashed));
24
+ const signature: Array<number> = rsaWrapper.sign(keys.privateKey, toSignBytes);
25
+ const verified = rsaWrapper.verify(keys.publicKey, toSignBytes, signature);
26
+ assert.isTrue(verified);
27
+ });
28
+ });