jstink 1.0.0
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/.github/workflows/node.js.yml +31 -0
- package/LICENSE +21 -0
- package/README.md +68 -0
- package/package.json +26 -0
- package/src/aes_gcm.js +30 -0
- package/src/aes_gcm.proto +67 -0
- package/src/aes_gcm_pb.js +412 -0
- package/src/awskms.js +14 -0
- package/src/ciphertexts.js +31 -0
- package/src/index.js +51 -0
- package/src/keysets.js +24 -0
- package/src/tink.proto +194 -0
- package/src/tink_pb.js +1687 -0
- package/tests/ciphertexts.test.js +41 -0
- package/tests/encrypted.dat +1 -0
- package/tests/index.test.js +44 -0
- package/tests/keyset.json +1 -0
- package/tests/keyset.protobuf +0 -0
- package/tests/keysets.test.js +17 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const ciphertexts = require('../src/ciphertexts');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
describe('ciphertexts', () => {
|
|
5
|
+
|
|
6
|
+
it('should parse encrypted data', () => {
|
|
7
|
+
const encrypted = fs.readFileSync('./tests/encrypted.dat');
|
|
8
|
+
const {keyId, iv, ciphertext, tag} = ciphertexts.parse(encrypted);
|
|
9
|
+
expect(keyId).toEqual('1902300492');
|
|
10
|
+
expect(iv).toEqual(Buffer.from([
|
|
11
|
+
102, 74, 139, 63, 237, 243, 193, 181, 128, 93, 61, 165
|
|
12
|
+
]));
|
|
13
|
+
expect(ciphertext).toEqual(Buffer.from([
|
|
14
|
+
96, 225, 81, 27, 80, 6, 153, 127, 14, 150, 85, 211
|
|
15
|
+
]));
|
|
16
|
+
expect(tag).toEqual(Buffer.from([
|
|
17
|
+
73, 196, 242, 175, 124, 206, 144, 15, 144, 25, 232, 101, 110, 198, 29, 132
|
|
18
|
+
]));
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should create encrypted data in Tink format', () => {
|
|
22
|
+
const keyId = '1902300492';
|
|
23
|
+
const iv = Buffer.from([
|
|
24
|
+
102, 74, 139, 63, 237, 243, 193, 181, 128, 93, 61, 165
|
|
25
|
+
]);
|
|
26
|
+
const ciphertext = Buffer.from([
|
|
27
|
+
96, 225, 81, 27, 80, 6, 153, 127, 14, 150, 85, 211
|
|
28
|
+
]);
|
|
29
|
+
const tag = Buffer.from([
|
|
30
|
+
73, 196, 242, 175, 124, 206, 144, 15, 144, 25, 232, 101, 110, 198, 29, 132
|
|
31
|
+
]);
|
|
32
|
+
const encrypted = ciphertexts.create({keyId, iv, ciphertext, tag});
|
|
33
|
+
expect(encrypted).toEqual(Buffer.from([
|
|
34
|
+
1, // version
|
|
35
|
+
113, 98, 205, 76, // key id as 4-byte BE int
|
|
36
|
+
102, 74, 139, 63, 237, 243, 193, 181, 128, 93, 61, 165, // iv
|
|
37
|
+
96, 225, 81, 27, 80, 6, 153, 127, 14, 150, 85, 211, // ciphertext
|
|
38
|
+
73, 196, 242, 175, 124, 206, 144, 15, 144, 25, 232, 101, 110, 198, 29, 132 // tag
|
|
39
|
+
]));
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
qb�LfJ�?�����]=�`�QP��U�I��|ΐ��en��
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const { Aead } = require('../src/index');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
jest.mock('@aws-sdk/client-kms', () => {
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const protobuf = fs.readFileSync('./tests/keyset.protobuf');
|
|
8
|
+
|
|
9
|
+
const originalModule = jest.requireActual("@aws-sdk/client-kms");
|
|
10
|
+
return {
|
|
11
|
+
...originalModule,
|
|
12
|
+
KMSClient: jest.fn(() => ({
|
|
13
|
+
send: jest.fn().mockImplementation((command) => {
|
|
14
|
+
if (command instanceof originalModule.DecryptCommand) {
|
|
15
|
+
// Mocked response for the decrypt command
|
|
16
|
+
return Promise.resolve({
|
|
17
|
+
Plaintext: protobuf
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
throw new Error("Unmocked command");
|
|
21
|
+
})
|
|
22
|
+
}))
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('jstink', () => {
|
|
27
|
+
it('should encrypt and decrypt', async () => {
|
|
28
|
+
const keyset = JSON.parse(fs.readFileSync('tests/keyset.json'));
|
|
29
|
+
const aead = new Aead(keyset);
|
|
30
|
+
|
|
31
|
+
const ciphertext = await aead.encrypt('Hello World!', 'customer-id1');
|
|
32
|
+
const plaintext = await aead.decrypt(ciphertext, 'customer-id1');
|
|
33
|
+
expect(plaintext).toBe('Hello World!');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should decrypt', async () => {
|
|
37
|
+
const keyset = JSON.parse(fs.readFileSync('tests/keyset.json'));
|
|
38
|
+
const aead = new Aead(keyset);
|
|
39
|
+
const ciphertext = fs.readFileSync('tests/encrypted.dat');
|
|
40
|
+
const plaintext = await aead.decrypt(ciphertext, 'customer-id1');
|
|
41
|
+
expect(plaintext).toBe('Hello World!');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"encryptedKeyset":"AQICAHg+l9t3jKGYAMIaeoH1wGK7KN9UlgWeOQ1DoXOs4LzszgF+cueWYZwVrb4D/31p25f/AAAAzzCBzAYJKoZIhvcNAQcGoIG+MIG7AgEAMIG1BgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDPvymtKGRuYjG6v7aAIBEICBhzaswiK7Z1VYBP1J86qS9Ooahr/W21Azj6FyKAR13KeM7n7fUNt4Z1KuzA7U3aGJmYU58ACqNnXEwTmeb7PuUV3HrePL64HqIsgfJhV4n7dDa84a6hmLf/TAdDxDVgQRhkPvMqQA1Yw8E0qo9YUFux1nJWoEKIRIod1ZsjA5TIHHaPsYQTNDGg==","keysetInfo":{"primaryKeyId":1902300492,"keyInfo":[{"typeUrl":"type.googleapis.com/google.crypto.tink.AesGcmKey","status":"ENABLED","keyId":1902300492,"outputPrefixType":"TINK"}]}}
|
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const keysets = require('../src/keysets');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
describe('keysets', () => {
|
|
5
|
+
it('should parse keyset from protobuf', () => {
|
|
6
|
+
const protobuf = fs.readFileSync('./tests/keyset.protobuf');
|
|
7
|
+
const keyset = keysets.create(protobuf);
|
|
8
|
+
const testKeyId = '1902300492';
|
|
9
|
+
|
|
10
|
+
expect(keyset).toHaveProperty(testKeyId);
|
|
11
|
+
expect(keyset[testKeyId]).toEqual(new Uint8Array([
|
|
12
|
+
66, 178, 69, 234, 142, 47, 134, 16, 40, 116, 14, 29, 11, 66, 208,
|
|
13
|
+
227, 3, 218, 151, 211, 193, 210, 42, 252, 234, 12, 0, 23, 82, 14,
|
|
14
|
+
200, 24,
|
|
15
|
+
]));
|
|
16
|
+
});
|
|
17
|
+
});
|