spd-lib 1.1.7 → 1.1.8

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 (2) hide show
  1. package/index.js +13 -80
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -11,27 +11,11 @@ class SPD {
11
11
  this.keyPair; // Generate a key pair for encryption/decryption
12
12
  this.userKey;
13
13
  this.salt;
14
- this.signingKeyPair;
15
14
  this.init();
16
15
  }
17
16
  async init() {
18
17
  await sodium.ready;
19
18
  this.keyPair = sodium.crypto_box_keypair()
20
- this.signingKeyPair = sodium.crypto_sign_keypair();
21
- }
22
- static async deriveSigningKeys(passcode, salt) {
23
- if (!passcode || typeof passcode !== 'string' || passcode.length < 8 ||
24
- !salt || !(salt instanceof Buffer) || salt.length !== 16) {
25
- throw new Error('Invalid passcode or salt.');
26
- }
27
-
28
- const { pbk } = await SPD.derivePBK(passcode, salt);
29
- await sodium.ready;
30
- // Derive separate keys for signing to avoid key reuse
31
- const signingSeed = pbk.slice(0, sodium.crypto_sign_SEEDBYTES);
32
- const signingKeyPair = sodium.crypto_sign_seed_keypair(signingSeed);
33
-
34
- return { signingKeyPair };
35
19
  }
36
20
  async setPassKey(passcode){
37
21
  await sodium.ready;
@@ -40,8 +24,6 @@ class SPD {
40
24
  const userKey = pqcKey.publicKey;
41
25
  this.userKey = userKey;
42
26
  this.salt = salt;
43
- const derivedKeys = await SPD.deriveSigningKeys(passcode, salt);
44
- this.signingKeyPair = derivedKeys.signingKeyPair;
45
27
  }
46
28
 
47
29
  async addData(name, data) {
@@ -54,8 +36,7 @@ const derivedKeys = await SPD.deriveSigningKeys(passcode, salt);
54
36
  const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
55
37
  const encryptedData = sodium.crypto_secretbox_easy(compressedData, nonce, this.userKey);
56
38
  const hash = crypto.createHash('sha256').update(encryptedData).digest('hex');
57
- const signature = sodium.crypto_sign_detached(encryptedData, this.signingKeyPair.privateKey);
58
- this.data.push({ dataName: name, nonce: Array.from(nonce), data: Array.from(encryptedData),signature:Array.from(signature), hash, dataType: dmap[1] });
39
+ this.data.push({ dataName: name, nonce: Array.from(nonce), data: Array.from(encryptedData), hash, dataType: dmap[1] });
59
40
  }
60
41
 
61
42
  saveToFile(outputPath) {
@@ -63,7 +44,7 @@ const derivedKeys = await SPD.deriveSigningKeys(passcode, salt);
63
44
  throw new Error('Invalid output path or salt.');
64
45
  }
65
46
 
66
- const spdData = JSON.stringify({ data: this.data, salt: Array.from(this.salt),signingPublicKey:Array.from(this.signingKeyPair.publicKey) });
47
+ const spdData = JSON.stringify({ data: this.data, salt: Array.from(this.salt) });
67
48
  const compressedSpdData = zlib.deflateSync(spdData);
68
49
  fs.writeFileSync(outputPath, compressedSpdData, { mode: 0o600 });
69
50
  }
@@ -79,7 +60,7 @@ const derivedKeys = await SPD.deriveSigningKeys(passcode, salt);
79
60
  await sodium.ready;
80
61
  const compressedSpdData = fs.readFileSync(spdPath);
81
62
  const spdData = zlib.inflateSync(compressedSpdData).toString('utf8');
82
- const { data, salt, signingPublicKey } = JSON.parse(spdData);
63
+ const { data, salt } = JSON.parse(spdData);
83
64
 
84
65
  const { pqcKey } = await new SPD().convertPasscodeToPQCKeySalted(passcode, new Uint8Array(salt));
85
66
  const pbk = pqcKey.publicKey;
@@ -88,34 +69,19 @@ const derivedKeys = await SPD.deriveSigningKeys(passcode, salt);
88
69
  spd.keyPair = {
89
70
  publicKey: pbk.publicKey
90
71
  };
91
-
92
- spd.signingKeyPair = { publicKey: Uint8Array.from(signingPublicKey) };
93
72
  spd.data = data.map(dat => ({
94
73
  dataName: dat.dataName,
95
74
  nonce: Buffer.from(dat.nonce),
96
75
  data: Buffer.from(dat.data),
97
- signature: Buffer.from(dat.signature),
98
76
  hash: dat.hash,
99
77
  dataType: dat.dataType
100
78
  }));
101
79
  spd.data.forEach(dat => {
102
- const encryptedBuffer = Buffer.from(dat.data);
103
- const signatureBuffer = Buffer.from(dat.signature);
104
- const signingPublicKeyBuffer = Uint8Array.from(signingPublicKey);
105
-
106
- const isValid = sodium.crypto_sign_verify_detached(signatureBuffer, encryptedBuffer, signingPublicKeyBuffer);
107
- if (!isValid) {
108
- rej(new Error(`Signature verification failed for ${dat.dataName}`));
109
- return;
110
- }
111
-
112
- const calculatedHash = crypto.createHash('sha256').update(encryptedBuffer).digest('hex');
80
+ const calculatedHash = crypto.createHash('sha256').update(Buffer.from(dat.data)).digest('hex');
113
81
  if (calculatedHash !== dat.hash) {
114
82
  rej(new Error(`Data integrity check failed for ${dat.dataName}`));
115
- return;
116
83
  }
117
84
  });
118
-
119
85
  res(spd);
120
86
  }catch{
121
87
  rej()
@@ -130,30 +96,10 @@ const derivedKeys = await SPD.deriveSigningKeys(passcode, salt);
130
96
  let extractedFiles = {};
131
97
  this.data.forEach(async dat => {
132
98
  try{
133
- const calculatedHash = crypto.createHash('sha256').update(dat.data).digest('hex');
134
- if (calculatedHash !== dat.hash) {
135
- throw new Error(`Hash mismatch for ${dat.dataName}`);
136
- }
137
-
138
- // Verify signature
139
- const isValid = sodium.crypto_sign_verify_detached(
140
- Buffer.from(dat.signature),
141
- Buffer.from(dat.data),
142
- this.signingKeyPair.publicKey
143
- );
144
- if (!isValid) {
145
- throw new Error(`Signature verification failed for ${dat.dataName}`);
146
- }
147
-
148
- // Decrypt data
149
- const decryptedData = sodium.crypto_secretbox_open_easy(
150
- Buffer.from(dat.data),
151
- Buffer.from(dat.nonce),
152
- this.userKey
153
- );
154
- const decompressedData = zlib.inflateSync(decryptedData);
155
- const dt = decompressedData.toString('utf8');
156
- extractedFiles[dat.dataName] = await this.CSTI(dt, dat.dataType);
99
+ const decryptedData = sodium.crypto_secretbox_open_easy(dat.data, dat.nonce, this.userKey);
100
+ const decompressedData = zlib.inflateSync(decryptedData);
101
+ const dt = decompressedData.toString('utf8');
102
+ extractedFiles[dat.dataName] = await this.CSTI(dt, dat.dataType);
157
103
  }catch{
158
104
  rej()
159
105
  }
@@ -199,16 +145,14 @@ const derivedKeys = await SPD.deriveSigningKeys(passcode, salt);
199
145
  await sodium.ready;
200
146
  const spdDataBuffer = Buffer.from(spdData, 'base64');
201
147
  const spdData2 = zlib.inflateSync(spdDataBuffer).toString('utf8');
202
- const { data, salt, signingPublicKey } = JSON.parse(spdData2);
148
+ const { data, salt } = JSON.parse(spdData2);
203
149
  const { pqcKey } = await new SPD().convertPasscodeToPQCKeySalted(passcode, new Uint8Array(salt));
204
-
205
150
  const pbk = pqcKey.publicKey;
206
151
  const spd = new SPD();
207
152
  spd.userKey = pbk;
208
153
  spd.keyPair = {
209
154
  publicKey: pbk.publicKey
210
155
  };
211
- spd.signingKeyPair = { publicKey: Uint8Array.from(signingPublicKey) };
212
156
  spd.data = data.map(dat => ({
213
157
  dataName: dat.dataName,
214
158
  nonce: Buffer.from(dat.nonce),
@@ -217,21 +161,10 @@ const derivedKeys = await SPD.deriveSigningKeys(passcode, salt);
217
161
  dataType: dat.dataType
218
162
  }));
219
163
  spd.data.forEach(dat => {
220
- const encryptedBuffer = Buffer.from(dat.data);
221
- const signatureBuffer = Buffer.from(dat.signature);
222
- const signingPublicKeyBuffer = Uint8Array.from(signingPublicKey);
223
-
224
- const isValid = sodium.crypto_sign_verify_detached(signatureBuffer, encryptedBuffer, signingPublicKeyBuffer);
225
- if (!isValid) {
226
- rej(new Error(`Signature verification failed for ${dat.dataName}`));
227
- return;
228
- }
229
-
230
- const calculatedHash = crypto.createHash('sha256').update(encryptedBuffer).digest('hex');
231
- if (calculatedHash !== dat.hash) {
232
- rej(new Error(`Data integrity check failed for ${dat.dataName}`));
233
- return;
234
- }
164
+ const calculatedHash = crypto.createHash('sha256').update(Buffer.from(dat.data)).digest('hex');
165
+ if (calculatedHash !== dat.hash) {
166
+ rej(new Error(`Data integrity check failed for ${dat.dataName}`));
167
+ }
235
168
  });
236
169
  res(spd);
237
170
  }catch{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spd-lib",
3
- "version": "1.1.7",
3
+ "version": "1.1.8",
4
4
  "description": "SPD or Secure Packaged Data is a compress PQC protected file format to store sensitive data localy",
5
5
  "main": "index.js",
6
6
  "scripts": {