spd-lib 1.1.9 → 1.2.1
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/dist/index.js +1 -0
- package/package.json +7 -2
- package/index.js +0 -321
- package/readme.md +0 -137
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const fs=require("fs"),zlib=require("zlib"),sodium=require("libsodium-wrappers"),crypto=require("crypto"),argon2=require("argon2");class SPD{constructor(){this.data=[],this.keyPair,this.userKey,this.salt,this.init()}async init(){await sodium.ready,this.keyPair=sodium.crypto_kx_keypair()}async setPassKey(a){await sodium.ready,this.init();const{pqcKey:t,salt:r}=await(new SPD).convertPasscodeToPQCKey(a),e=t.publicKey;this.userKey=e,this.salt=r}async migrateFromFile(a,t){const r=await SPD.loadFromFile(a,t);r.extractData_OLD=async()=>new Promise((async(a,t)=>{try{await sodium.ready;let r={};this.data.forEach((async a=>{try{const t=sodium.crypto_secretbox_open_easy(a.data,a.nonce,this.userKey),e=zlib.inflateSync(t,{level:9}).toString("utf8");r[a.dataName]=await this.CSTI(e,a.dataType)}catch{t()}})),a(r)}catch{t()}}));const e=await r.extractData_OLD(),i=new SPD;await i.setPassKey(t);for(let a in e)await i.addData(a,e[a]);i.saveToFile(a)}async migrateFromString(a,t){const r=await SPD.loadFromString(a,t);r.extractData_OLD=async()=>new Promise((async(a,t)=>{try{await sodium.ready;let r={};this.data.forEach((async a=>{try{const t=sodium.crypto_secretbox_open_easy(a.data,a.nonce,this.userKey),e=zlib.inflateSync(t,{level:9}).toString("utf8");r[a.dataName]=await this.CSTI(e,a.dataType)}catch{t()}})),a(r)}catch{t()}}));const e=await r.extractData_OLD(),i=new SPD;await i.setPassKey(t);for(let a in e)await i.addData(a,e[a]);return i.saveData()}async addData(a,t){const r=await this.CITS(t);await sodium.ready;const e=Buffer.from(r[0]),i=zlib.deflateSync(e,{level:9}),s=sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES),n=sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(i,null,null,s,this.userKey),o=crypto.createHash("sha3-512").update(n).digest("hex");this.data.push({dataName:a,nonce:Array.from(s),data:Array.from(n),hash:o,dataType:r[1]})}saveToFile(a){if(!(a&&"string"==typeof a&&a.trim()&&this.salt&&this.salt instanceof Uint8Array&&16===this.salt.length))throw new Error("Invalid output path or salt.");const t=JSON.stringify({data:this.data,salt:Array.from(this.salt)}),r=zlib.deflateSync(t,{level:9});fs.writeFileSync(a,r,{mode:384})}static async loadFromFile(a,t){return new Promise((async(r,e)=>{try{a&&"string"==typeof a&&a.trim()&&t&&"string"==typeof t&&t.trim()||e(new Error("Invalid SPD path or passcode.")),await sodium.ready;const i=fs.readFileSync(a),s=zlib.inflateSync(i,{level:9}).toString("utf8"),{data:n,salt:o}=JSON.parse(s),{pqcKey:y}=await(new SPD).convertPasscodeToPQCKeySalted(t,new Uint8Array(o)),c=y.publicKey,d=new SPD;d.userKey=c,d.keyPair={publicKey:c.publicKey},d.data=n.map((a=>({dataName:a.dataName,nonce:Buffer.from(a.nonce),data:Buffer.from(a.data),hash:a.hash,dataType:a.dataType}))),d.data.forEach((a=>{crypto.createHash("sha3-512").update(Buffer.from(a.data)).digest("hex")!==a.hash&&e(new Error(`Data integrity check failed for ${a.dataName}`))})),r(d)}catch{e()}}))}async extractData(){return new Promise((async(a,t)=>{try{await sodium.ready;let r={};this.data.forEach((async a=>{try{const t=sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(null,a.data,null,a.nonce,this.userKey),e=zlib.inflateSync(t,{level:9}).toString("utf8");r[a.dataName]=await this.CSTI(e,a.dataType)}catch{t()}})),a(r)}catch{t()}}))}static async derivePBK(a,t){if(!(a&&"string"==typeof a&&a.trim()&&t&&t instanceof Uint8Array&&16===t.length))throw new Error("Invalid passcode or salt.");return new Promise((async(r,e)=>{argon2.hash(a,{salt:Buffer.from(t),type:argon2.argon2id}).then((a=>{r({pbk:a,salt:t})})).catch((a=>{e(a)}))}))}saveData(){const a=JSON.stringify({data:this.data,salt:Array.from(this.salt)});return zlib.deflateSync(a,{level:9})}static async loadFromString(a,t){return new Promise((async(r,e)=>{try{a&&"string"==typeof a&&a.trim()&&t&&"string"==typeof t&&t.trim()||e(new Error("Invalid SPD path or passcode.")),await sodium.ready;const i=Buffer.from(a,"base64"),s=zlib.inflateSync(i,{level:9}).toString("utf8"),{data:n,salt:o}=JSON.parse(s),{pqcKey:y}=await(new SPD).convertPasscodeToPQCKeySalted(t,new Uint8Array(o)),c=y.publicKey,d=new SPD;d.userKey=c,d.keyPair={publicKey:c.publicKey},d.data=n.map((a=>({dataName:a.dataName,nonce:Buffer.from(a.nonce),data:Buffer.from(a.data),hash:a.hash,dataType:a.dataType}))),d.data.forEach((a=>{crypto.createHash("sha3-512").update(Buffer.from(a.data)).digest("hex")!==a.hash&&e(new Error(`Data integrity check failed for ${a.dataName}`))})),r(d)}catch{e()}}))}async convertPasscodeToPQCKeySalted(a,t){if(!a||"string"!=typeof a||!a.trim()||a.length<8||!t||!(t instanceof Uint8Array)||16!==t.length)throw new Error("Invalid passcode or salt.");const{pbk:r}=await SPD.derivePBK(a,t);await sodium.ready;return{pqcKey:{publicKey:sodium.crypto_kx_seed_keypair(r.slice(0,sodium.crypto_kx_SEEDBYTES)).publicKey},salt:t}}async convertPasscodeToPQCKey(a){if(!a||"string"!=typeof a||!a.trim()||a.length<8)throw new Error("Invalid passcode.");const{pbk:t,salt:r}=await SPD.derivePBK(a,crypto.getRandomValues(new Uint8Array(16)));await sodium.ready;return{pqcKey:{publicKey:sodium.crypto_kx_seed_keypair(t.slice(0,sodium.crypto_kx_SEEDBYTES)).publicKey},salt:r}}async TDT(a){return{"[object Array]":"Array","[object Uint8Array]":"Uint8Array","[object Uint16Array]":"Uint16Array","[object Uint32Array]":"Uint32Array","[object BigInt64Array]":"BigInt64Array","[object BigUint64Array]":"BigUint64Array","[object Float32Array]":"Float32Array","[object Float64Array]":"Float64Array","[object Map]":"Map","[object Set]":"Set","[object Date]":"Date","[object RegExp]":"RegExp","[object Error]":"Error"}[Object.prototype.toString.call(a)]}async isNumArr(a){if("Uint8Array"===a||"Uint16Array"===a||"Uint32Array"===a||"BigInt64Array"===a||"BigUint64Array"===a||"Float32Array"===a||"Float64Array"===a)return 1}async isSWM(a){if("Map"===a||"Set"===a||"WeakMap"===a||"WeakSet"===a)return 1}async isDRE(a){if("Date"===a||"RegExp"===a||"Error"===a)return 1}async CITS(a){const t=typeof a;if("string"===t||"number"===t||"boolean"===t)return[a.toString(),t];if("object"==typeof a){const t=await this.TDT(a);return"Array"===t?[JSON.stringify(a),"Array"]:await this.isNumArr(t)?[JSON.stringify(Array.from(a)),t]:await this.isSWM(t)?[JSON.stringify([...a]),t]:await this.isDRE(t)?[a.toString(),t]:[JSON.stringify(a),typeof a]}}async CSTI(a,t){return"string"===t?a:"number"===t?parseFloat(a):"boolean"===t?"true"===a&&"false"!==a:"object"===t||"Array"===t?JSON.parse(a):"Uint8Array"===t?new Uint8Array(JSON.parse(a)):"Uint16Array"===t?new Uint16Array(JSON.parse(a)):"Uint32Array"===t?new Uint32Array(JSON.parse(a)):"BigInt64Array"===t?new BigInt64Array(JSON.parse(a)):"BigUint64Array"===t?new BigUint64Array(JSON.parse(a)):"Float32Array"===t?new Float32Array(JSON.parse(a)):"Float64Array"===t?new Float64Array(JSON.parse(a)):"Map"===t?new Map(JSON.parse(a)):"Set"===t?new Set(JSON.parse(a)):"WeakMap"===t?new WeakMap(JSON.parse(a)):"WeakSet"===t?new WeakSet(JSON.parse(a)):"Date"===t?new Date(a):"RegExp"===t?new RegExp(a):"Error"===t?new Error(a):void 0}}module.exports={SPD};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spd-lib",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "SPD or Secure Packaged Data is a compress PQC protected file format to store sensitive data localy",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
8
|
},
|
|
@@ -21,6 +21,11 @@
|
|
|
21
21
|
"author": "ALS-OPSS",
|
|
22
22
|
"license": "ISC",
|
|
23
23
|
"dependencies": {
|
|
24
|
+
"argon2": "^0.41.1",
|
|
24
25
|
"libsodium-wrappers": "^0.7.15"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"javascript-obfuscator": "^4.1.1",
|
|
29
|
+
"terser": "^5.39.0"
|
|
25
30
|
}
|
|
26
31
|
}
|
package/index.js
DELETED
|
@@ -1,321 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const zlib = require('zlib');
|
|
3
|
-
const sodium = require('libsodium-wrappers');
|
|
4
|
-
const crypto = require('crypto');
|
|
5
|
-
|
|
6
|
-
class SPD {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
constructor() {
|
|
10
|
-
this.data = [];
|
|
11
|
-
this.keyPair; // Generate a key pair for encryption/decryption
|
|
12
|
-
this.userKey;
|
|
13
|
-
this.salt;
|
|
14
|
-
this.init();
|
|
15
|
-
}
|
|
16
|
-
async init() {
|
|
17
|
-
await sodium.ready;
|
|
18
|
-
this.keyPair = sodium.crypto_box_keypair()
|
|
19
|
-
}
|
|
20
|
-
async setPassKey(passcode){
|
|
21
|
-
await sodium.ready;
|
|
22
|
-
this.init()
|
|
23
|
-
const { pqcKey, salt } = await new SPD().convertPasscodeToPQCKey(passcode);
|
|
24
|
-
const userKey = pqcKey.publicKey;
|
|
25
|
-
this.userKey = userKey;
|
|
26
|
-
this.salt = salt;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async addData(name, data) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const dmap = await this.CITS(data)
|
|
33
|
-
await sodium.ready;
|
|
34
|
-
const dat = Buffer.from(dmap[0]);
|
|
35
|
-
const compressedData = zlib.deflateSync(dat,{
|
|
36
|
-
level:9
|
|
37
|
-
});
|
|
38
|
-
const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
|
|
39
|
-
const encryptedData = sodium.crypto_secretbox_easy(compressedData, nonce, this.userKey);
|
|
40
|
-
const hash = crypto.createHash('sha256').update(encryptedData).digest('hex');
|
|
41
|
-
this.data.push({ dataName: name, nonce: Array.from(nonce), data: Array.from(encryptedData), hash, dataType: dmap[1] });
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
saveToFile(outputPath) {
|
|
45
|
-
if (!outputPath || typeof outputPath !== 'string' || !outputPath.trim() || !this.salt || !(this.salt instanceof Uint8Array) || this.salt.length !== 16) {
|
|
46
|
-
throw new Error('Invalid output path or salt.');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const spdData = JSON.stringify({ data: this.data, salt: Array.from(this.salt) });
|
|
50
|
-
const compressedSpdData = zlib.deflateSync(spdData,{
|
|
51
|
-
level:9
|
|
52
|
-
});
|
|
53
|
-
fs.writeFileSync(outputPath, compressedSpdData, { mode: 0o600 });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
static async loadFromFile(spdPath, passcode) {
|
|
58
|
-
return new Promise(async (res,rej)=>{
|
|
59
|
-
try{
|
|
60
|
-
if (!spdPath || typeof spdPath !== 'string' || !spdPath.trim() || !passcode || typeof passcode !== 'string' || !passcode.trim()) {
|
|
61
|
-
rej(new Error('Invalid SPD path or passcode.'));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
await sodium.ready;
|
|
65
|
-
const compressedSpdData = fs.readFileSync(spdPath);
|
|
66
|
-
const spdData = zlib.inflateSync(compressedSpdData,{level:9}).toString('utf8');
|
|
67
|
-
const { data, salt } = JSON.parse(spdData);
|
|
68
|
-
|
|
69
|
-
const { pqcKey } = await new SPD().convertPasscodeToPQCKeySalted(passcode, new Uint8Array(salt));
|
|
70
|
-
const pbk = pqcKey.publicKey;
|
|
71
|
-
const spd = new SPD();
|
|
72
|
-
spd.userKey = pbk;
|
|
73
|
-
spd.keyPair = {
|
|
74
|
-
publicKey: pbk.publicKey
|
|
75
|
-
};
|
|
76
|
-
spd.data = data.map(dat => ({
|
|
77
|
-
dataName: dat.dataName,
|
|
78
|
-
nonce: Buffer.from(dat.nonce),
|
|
79
|
-
data: Buffer.from(dat.data),
|
|
80
|
-
hash: dat.hash,
|
|
81
|
-
dataType: dat.dataType
|
|
82
|
-
}));
|
|
83
|
-
spd.data.forEach(dat => {
|
|
84
|
-
const calculatedHash = crypto.createHash('sha256').update(Buffer.from(dat.data)).digest('hex');
|
|
85
|
-
if (calculatedHash !== dat.hash) {
|
|
86
|
-
rej(new Error(`Data integrity check failed for ${dat.dataName}`));
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
res(spd);
|
|
90
|
-
}catch{
|
|
91
|
-
rej()
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async extractData() {
|
|
97
|
-
return new Promise(async(res,rej)=>{
|
|
98
|
-
try{
|
|
99
|
-
await sodium.ready;
|
|
100
|
-
let extractedFiles = {};
|
|
101
|
-
this.data.forEach(async dat => {
|
|
102
|
-
try{
|
|
103
|
-
const decryptedData = sodium.crypto_secretbox_open_easy(dat.data, dat.nonce, this.userKey);
|
|
104
|
-
const decompressedData = zlib.inflateSync(decryptedData,{level:9});
|
|
105
|
-
const dt = decompressedData.toString('utf8');
|
|
106
|
-
extractedFiles[dat.dataName] = await this.CSTI(dt, dat.dataType);
|
|
107
|
-
}catch{
|
|
108
|
-
rej()
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
res(extractedFiles);
|
|
112
|
-
}catch{
|
|
113
|
-
rej()
|
|
114
|
-
}
|
|
115
|
-
})
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
static async derivePBK(passcode, salt) {
|
|
121
|
-
if (!passcode || typeof passcode !== 'string' || !passcode.trim() || !salt || !(salt instanceof Uint8Array) || salt.length !== 16) {
|
|
122
|
-
throw new Error('Invalid passcode or salt.');
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return new Promise((resolve, reject) => {
|
|
126
|
-
crypto.pbkdf2(passcode, salt, 100000, 32, 'sha256', (err, derivedKey) => {
|
|
127
|
-
if (err) {
|
|
128
|
-
reject(err);
|
|
129
|
-
} else {
|
|
130
|
-
resolve({ pbk: derivedKey, salt: salt });
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
saveData() {
|
|
137
|
-
const spdData = JSON.stringify({ data: this.data, salt: Array.from(this.salt) });
|
|
138
|
-
const compressedSpdData = zlib.deflateSync(spdData,{level:9});
|
|
139
|
-
return compressedSpdData;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
static async loadFromString(spdData, passcode) {
|
|
143
|
-
return new Promise(async (res,rej)=>{
|
|
144
|
-
try{
|
|
145
|
-
if (!spdData || typeof spdData !== 'string' || !spdData.trim() || !passcode || typeof passcode !== 'string' || !passcode.trim()) {
|
|
146
|
-
rej(new Error('Invalid SPD path or passcode.'));
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
await sodium.ready;
|
|
150
|
-
const spdDataBuffer = Buffer.from(spdData, 'base64');
|
|
151
|
-
const spdData2 = zlib.inflateSync(spdDataBuffer,{level:9}).toString('utf8');
|
|
152
|
-
const { data, salt } = JSON.parse(spdData2);
|
|
153
|
-
const { pqcKey } = await new SPD().convertPasscodeToPQCKeySalted(passcode, new Uint8Array(salt));
|
|
154
|
-
const pbk = pqcKey.publicKey;
|
|
155
|
-
const spd = new SPD();
|
|
156
|
-
spd.userKey = pbk;
|
|
157
|
-
spd.keyPair = {
|
|
158
|
-
publicKey: pbk.publicKey
|
|
159
|
-
};
|
|
160
|
-
spd.data = data.map(dat => ({
|
|
161
|
-
dataName: dat.dataName,
|
|
162
|
-
nonce: Buffer.from(dat.nonce),
|
|
163
|
-
data: Buffer.from(dat.data),
|
|
164
|
-
hash: dat.hash,
|
|
165
|
-
dataType: dat.dataType
|
|
166
|
-
}));
|
|
167
|
-
spd.data.forEach(dat => {
|
|
168
|
-
const calculatedHash = crypto.createHash('sha256').update(Buffer.from(dat.data)).digest('hex');
|
|
169
|
-
if (calculatedHash !== dat.hash) {
|
|
170
|
-
rej(new Error(`Data integrity check failed for ${dat.dataName}`));
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
res(spd);
|
|
174
|
-
}catch{
|
|
175
|
-
rej()
|
|
176
|
-
}
|
|
177
|
-
})
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
async convertPasscodeToPQCKeySalted(passcode, salt) {
|
|
181
|
-
if (!passcode || typeof passcode !== 'string' || !passcode.trim() || passcode.length < 8 || !salt || !(salt instanceof Uint8Array) || salt.length !== 16) {
|
|
182
|
-
throw new Error('Invalid passcode or salt.');
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const { pbk } = await SPD.derivePBK(passcode, salt);
|
|
186
|
-
await sodium.ready;
|
|
187
|
-
const keyPair = sodium.crypto_kx_seed_keypair(pbk.slice(0, sodium.crypto_kx_SEEDBYTES));
|
|
188
|
-
return { pqcKey: { publicKey: keyPair.publicKey }, salt };
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async convertPasscodeToPQCKey(passcode) {
|
|
192
|
-
if (!passcode || typeof passcode !== 'string' || !passcode.trim() || passcode.length < 8) {
|
|
193
|
-
throw new Error('Invalid passcode.');
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const { pbk, salt } = await SPD.derivePBK(passcode, crypto.getRandomValues(new Uint8Array(16)));
|
|
197
|
-
await sodium.ready;
|
|
198
|
-
const keyPair = sodium.crypto_kx_seed_keypair(pbk.slice(0, sodium.crypto_kx_SEEDBYTES));
|
|
199
|
-
return { pqcKey: { publicKey: keyPair.publicKey }, salt };
|
|
200
|
-
}
|
|
201
|
-
async TDT(data) {
|
|
202
|
-
const classTypeMap = {
|
|
203
|
-
'[object Array]': 'Array',
|
|
204
|
-
'[object Uint8Array]': 'Uint8Array',
|
|
205
|
-
'[object Uint16Array]': 'Uint16Array',
|
|
206
|
-
'[object Uint32Array]': 'Uint32Array',
|
|
207
|
-
'[object BigInt64Array]': 'BigInt64Array',
|
|
208
|
-
'[object BigUint64Array]': 'BigUint64Array',
|
|
209
|
-
'[object Float32Array]': 'Float32Array',
|
|
210
|
-
'[object Float64Array]': 'Float64Array',
|
|
211
|
-
'[object Map]': 'Map',
|
|
212
|
-
'[object Set]': 'Set',
|
|
213
|
-
'[object Date]': 'Date',
|
|
214
|
-
'[object RegExp]': 'RegExp',
|
|
215
|
-
'[object Error]': 'Error'
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
const objectType = Object.prototype.toString.call(data);
|
|
219
|
-
const mappedType = classTypeMap[objectType];
|
|
220
|
-
return mappedType;
|
|
221
|
-
}
|
|
222
|
-
async isNumArr(dataType) {
|
|
223
|
-
if(dataType === 'Uint8Array' || dataType === 'Uint16Array' || dataType === 'Uint32Array' || dataType === 'BigInt64Array' || dataType === 'BigUint64Array' || dataType === 'Float32Array' || dataType === 'Float64Array'){
|
|
224
|
-
return true;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
async isSWM(dataType) {
|
|
228
|
-
if(dataType === 'Map' || dataType === 'Set' || dataType === 'WeakMap' || dataType === 'WeakSet'){
|
|
229
|
-
return true;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
async isDRE(dataType) {
|
|
233
|
-
if(dataType === 'Date' || dataType === 'RegExp' || dataType === 'Error'){
|
|
234
|
-
return true;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
async CITS(data) {
|
|
238
|
-
const dataType = typeof data;
|
|
239
|
-
if (dataType === 'string' || dataType === 'number' || dataType === 'boolean') {
|
|
240
|
-
return [data.toString(), dataType];
|
|
241
|
-
}
|
|
242
|
-
if(typeof data === 'object'){
|
|
243
|
-
const type = await this.TDT(data)
|
|
244
|
-
if(type === 'Array'){
|
|
245
|
-
return [JSON.stringify(data),'Array'];
|
|
246
|
-
}
|
|
247
|
-
if(await this.isNumArr(type)){
|
|
248
|
-
return [JSON.stringify(Array.from(data)),type];
|
|
249
|
-
}
|
|
250
|
-
if(await this.isSWM(type)){
|
|
251
|
-
|
|
252
|
-
return [JSON.stringify([...data]),type];
|
|
253
|
-
}
|
|
254
|
-
if(await this.isDRE(type)){
|
|
255
|
-
return [data.toString(),type];
|
|
256
|
-
}
|
|
257
|
-
return [JSON.stringify(data), typeof data];
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
async CSTI(data,type) {
|
|
261
|
-
if(type === 'string') {
|
|
262
|
-
return data
|
|
263
|
-
}
|
|
264
|
-
if(type === 'number'){
|
|
265
|
-
return parseFloat(data);
|
|
266
|
-
}
|
|
267
|
-
if(type === 'boolean'){
|
|
268
|
-
return (data === 'true')&&(data !== 'false');
|
|
269
|
-
}
|
|
270
|
-
if(type === 'object' || type === 'Array'){
|
|
271
|
-
return JSON.parse(data);
|
|
272
|
-
}
|
|
273
|
-
if(type === 'Uint8Array'){
|
|
274
|
-
return new Uint8Array(JSON.parse(data));
|
|
275
|
-
}
|
|
276
|
-
if(type === 'Uint16Array'){
|
|
277
|
-
return new Uint16Array(JSON.parse(data));
|
|
278
|
-
}
|
|
279
|
-
if(type === 'Uint32Array'){
|
|
280
|
-
|
|
281
|
-
return new Uint32Array(JSON.parse(data));
|
|
282
|
-
}
|
|
283
|
-
if(type === 'BigInt64Array'){
|
|
284
|
-
return new BigInt64Array(JSON.parse(data));
|
|
285
|
-
}
|
|
286
|
-
if(type === 'BigUint64Array'){
|
|
287
|
-
return new BigUint64Array(JSON.parse(data));
|
|
288
|
-
}
|
|
289
|
-
if(type === 'Float32Array'){
|
|
290
|
-
return new Float32Array(JSON.parse(data));
|
|
291
|
-
}
|
|
292
|
-
if(type === 'Float64Array'){
|
|
293
|
-
return new Float64Array(JSON.parse(data));
|
|
294
|
-
}
|
|
295
|
-
if(type === 'Map'){
|
|
296
|
-
return new Map(JSON.parse(data));
|
|
297
|
-
}
|
|
298
|
-
if(type === 'Set'){
|
|
299
|
-
return new Set(JSON.parse(data));
|
|
300
|
-
}
|
|
301
|
-
if(type === 'WeakMap'){
|
|
302
|
-
return new WeakMap(JSON.parse(data));
|
|
303
|
-
}
|
|
304
|
-
if(type === 'WeakSet'){
|
|
305
|
-
return new WeakSet(JSON.parse(data));
|
|
306
|
-
}
|
|
307
|
-
if(type === 'Date'){
|
|
308
|
-
return new Date(data);
|
|
309
|
-
}
|
|
310
|
-
if(type === 'RegExp'){
|
|
311
|
-
return new RegExp(data);
|
|
312
|
-
}
|
|
313
|
-
if(type === 'Error'){
|
|
314
|
-
return new Error(data);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
module.exports = {
|
|
320
|
-
SPD,
|
|
321
|
-
};
|
package/readme.md
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
# Secure Packaged Data (SPD)
|
|
2
|
-
|
|
3
|
-
The Secure Packaged Data (SPD) module provides functionality to securely store and retrieve data using encryption, compression, and hashing. This README explains how to use the SPD class and its methods.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
First, ensure you have Node.js installed. Then, install the required packages:
|
|
8
|
-
|
|
9
|
-
```sh
|
|
10
|
-
npm install spd-lib
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
Below are the primary functionalities of the SPD class.
|
|
16
|
-
|
|
17
|
-
### Initialization
|
|
18
|
-
|
|
19
|
-
Create an instance of the SPD class:
|
|
20
|
-
|
|
21
|
-
```javascript
|
|
22
|
-
const { SPD } = require('spd-lib');
|
|
23
|
-
|
|
24
|
-
const spd = new SPD();
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### Setting Passcode
|
|
28
|
-
|
|
29
|
-
Set a passcode for encrypting the data:
|
|
30
|
-
|
|
31
|
-
```javascript
|
|
32
|
-
await spd.setPassKey('your-passcode');
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Adding Data
|
|
36
|
-
|
|
37
|
-
Add data to the SPD instance:
|
|
38
|
-
|
|
39
|
-
```javascript
|
|
40
|
-
await spd.addData('dataName', yourData);
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Saving Data to File
|
|
44
|
-
|
|
45
|
-
Save the encrypted and compressed data to a file:
|
|
46
|
-
|
|
47
|
-
```javascript
|
|
48
|
-
spd.saveToFile('path/to/output.spd');
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Loading Data from File
|
|
52
|
-
|
|
53
|
-
Load the data from an SPD file:
|
|
54
|
-
|
|
55
|
-
```javascript
|
|
56
|
-
const loadedSPD = await SPD.loadFromFile('path/to/output.spd', 'your-passcode');
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Extracting Data
|
|
60
|
-
|
|
61
|
-
Extract and decrypt the data from the SPD instance:
|
|
62
|
-
|
|
63
|
-
```javascript
|
|
64
|
-
const extractedData = await loadedSPD.extractData();
|
|
65
|
-
console.log(extractedData);
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Example
|
|
69
|
-
|
|
70
|
-
Here is a complete example of how to use the SPD module:
|
|
71
|
-
|
|
72
|
-
```javascript
|
|
73
|
-
const { SPD } = require('./path/to/spd.js');
|
|
74
|
-
|
|
75
|
-
(async () => {
|
|
76
|
-
const spd = new SPD();
|
|
77
|
-
await spd.setPassKey('your-passcode');
|
|
78
|
-
|
|
79
|
-
const myData = {
|
|
80
|
-
name: "Alice",
|
|
81
|
-
age: 30,
|
|
82
|
-
isMember: true,
|
|
83
|
-
preferences: ["reading", "gaming"]
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
await spd.addData('userData', myData);
|
|
87
|
-
|
|
88
|
-
spd.saveToFile('path/to/output.spd');
|
|
89
|
-
|
|
90
|
-
const loadedSPD = await SPD.loadFromFile('path/to/output.spd', 'your-passcode');
|
|
91
|
-
const extractedData = await loadedSPD.extractData();
|
|
92
|
-
|
|
93
|
-
console.log(extractedData);
|
|
94
|
-
})();
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## Methods
|
|
98
|
-
|
|
99
|
-
### `async setPassKey(passcode)`
|
|
100
|
-
|
|
101
|
-
Sets the passcode for encrypting and decrypting data.
|
|
102
|
-
|
|
103
|
-
- **Parameters**: `passcode` (string) - The passcode to be used.
|
|
104
|
-
|
|
105
|
-
### `async addData(name, data)`
|
|
106
|
-
|
|
107
|
-
Adds data to the SPD instance.
|
|
108
|
-
|
|
109
|
-
- **Parameters**:
|
|
110
|
-
- `name` (string) - The name of the data.
|
|
111
|
-
- `data` (any) - The data to be stored.
|
|
112
|
-
|
|
113
|
-
### `saveToFile(outputPath)`
|
|
114
|
-
|
|
115
|
-
Saves the encrypted and compressed data to a file.
|
|
116
|
-
|
|
117
|
-
- **Parameters**: `outputPath` (string) - The path to save the file.
|
|
118
|
-
|
|
119
|
-
### `static async loadFromFile(spdPath, passcode)`
|
|
120
|
-
|
|
121
|
-
Loads the SPD data from a file.
|
|
122
|
-
|
|
123
|
-
- **Parameters**:
|
|
124
|
-
- `spdPath` (string) - The path to the SPD file.
|
|
125
|
-
- `passcode` (string) - The passcode to decrypt the data.
|
|
126
|
-
|
|
127
|
-
- **Returns**: An instance of SPD with the loaded data.
|
|
128
|
-
|
|
129
|
-
### `async extractData()`
|
|
130
|
-
|
|
131
|
-
Extracts and decrypts the data from the SPD instance.
|
|
132
|
-
|
|
133
|
-
- **Returns**: An object with the decrypted data.
|
|
134
|
-
|
|
135
|
-
## License
|
|
136
|
-
|
|
137
|
-
This project is licensed under the MIT License.
|