nuralem-bult-sdk 1.1.0 → 1.2.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.
@@ -1,14 +1,18 @@
1
1
  /**
2
2
  * @license
3
- * Nuralem Bult Ecosystem - NuralemBult SDK (v1.1.0 - Performance & Security Upgrade)
3
+ * Nuralem Bult Ecosystem - NuralemBult SDK (v1.2.0 - Enterprise Grade Security Hardening)
4
4
  * Copyright (c) 2026 Tulen Nursayat. All rights reserved.
5
5
  * Created by Tulen Nursayat (CTO & Principal Systems Engineer)
6
6
  *
7
- * Бұл нұсқада келесі жаңартулар енгізілді:
8
- * 1. Opaque RGB Steganography: Түстердің қысылуы мен бұрмалануын (Color Quantization) болдырмау үшін
9
- * деректер тек R, G, B арналарына жазылады, ал Alpha арнасы қатаң түрде 255 (толық ашық емес) болып қалады.
10
- * 2. 3x Exponential Backoff Retry: Файл бөліктерін (chunks) жүктеу кезінде желілік қате болса, автоматты түрде 3 рет қайталайды.
11
- * 3. L2 Cache TTL & LRU Eviction: IndexedDB кэшіне 24 сағаттық TTL және сыйымдылық 100 нотадан асқанда ескі құжаттарды автоматты өшіру (LRU).
7
+ * Бұл нұсқада келесі халықаралық банк деңгейіндегі қауіпсіздік қалқандары енгізілді:
8
+ * 1. PBKDF2 Key Derivation Function: Әлсіз SHA-256 хэштеуді тоқтатып, пайдаланушы кілтін қорғау үшін
9
+ * HMAC-SHA256, 100,000 итерация және бірегей "Salt" негізіндегі нативті PBKDF2 алгоритмі біріктірілді.
10
+ * 2. Keystream CSPRNG Steganography: Mulberry32 (ойыншық PRNG) толық жойылып, оның орнына
11
+ * Web Crypto API нативті AES-GCM (Keystream) негізіндегі детерминистік криптографиялық қауіпсіз
12
+ * кездейсоқ секіру (CSPRNG Spacing) алгоритмі әзірленді.
13
+ * 3. Encrypted L2 Cache (IndexedDB): Кэштегі деректерді XSS шабуылдары мен зиянды кеңейтілімдерден қорғау үшін,
14
+ * ашық мәтін (plaintext) сақтау тоқтатылды. IndexedDB қоймасына жазылатын әрбір мәлімет
15
+ * тек браузердің белсенді жадында (Session Runtime Memory) өмір сүретін AES-256-GCM кілтімен шифрланады.
12
16
  */
13
17
  export declare class NuralemBult {
14
18
  private static instance;
@@ -46,11 +50,12 @@ export declare class NuralemBult {
46
50
  * OPAQUE RGB STEGANOGRAPHY (Түстердің қысылуы мен аномалиясынан 100% қорғалған)
47
51
  * Деректер тек R, G, B арналарының LSB-іне жазылады, ал Alpha арнасы қатаң түрде 255 болып қалады.
48
52
  * Түстердің қысылуынан (Color Quantization) қорғау үшін 32-байттық Padding және CRC32 Checksum енгізілген.
53
+ * Mulberry32 PRNG орнына Web Crypto API нативті AES (Keystream) негізіндегі детерминистік CSPRNG біріктірілген.
49
54
  */
50
55
  private injectBytesToPngNative;
51
56
  /**
52
57
  * OPAQUE RGB STEGANOGRAPHY арқылы жазылған деректі пиксельдерден оқу
53
- * CRC32 бақылау қосындысын және белсенді Padding құрылымын автоматты түрде тексереді.
58
+ * CRC32 бақылау қосындысын және белсенді Padding құрылымын автоматты түрде CSPRNG арқылы тексереді.
54
59
  */
55
60
  private extractBytesFromPngNative;
56
61
  private mergeUint8Arrays;
@@ -1,14 +1,18 @@
1
1
  /**
2
2
  * @license
3
- * Nuralem Bult Ecosystem - NuralemBult SDK (v1.1.0 - Performance & Security Upgrade)
3
+ * Nuralem Bult Ecosystem - NuralemBult SDK (v1.2.0 - Enterprise Grade Security Hardening)
4
4
  * Copyright (c) 2026 Tulen Nursayat. All rights reserved.
5
5
  * Created by Tulen Nursayat (CTO & Principal Systems Engineer)
6
6
  *
7
- * Бұл нұсқада келесі жаңартулар енгізілді:
8
- * 1. Opaque RGB Steganography: Түстердің қысылуы мен бұрмалануын (Color Quantization) болдырмау үшін
9
- * деректер тек R, G, B арналарына жазылады, ал Alpha арнасы қатаң түрде 255 (толық ашық емес) болып қалады.
10
- * 2. 3x Exponential Backoff Retry: Файл бөліктерін (chunks) жүктеу кезінде желілік қате болса, автоматты түрде 3 рет қайталайды.
11
- * 3. L2 Cache TTL & LRU Eviction: IndexedDB кэшіне 24 сағаттық TTL және сыйымдылық 100 нотадан асқанда ескі құжаттарды автоматты өшіру (LRU).
7
+ * Бұл нұсқада келесі халықаралық банк деңгейіндегі қауіпсіздік қалқандары енгізілді:
8
+ * 1. PBKDF2 Key Derivation Function: Әлсіз SHA-256 хэштеуді тоқтатып, пайдаланушы кілтін қорғау үшін
9
+ * HMAC-SHA256, 100,000 итерация және бірегей "Salt" негізіндегі нативті PBKDF2 алгоритмі біріктірілді.
10
+ * 2. Keystream CSPRNG Steganography: Mulberry32 (ойыншық PRNG) толық жойылып, оның орнына
11
+ * Web Crypto API нативті AES-GCM (Keystream) негізіндегі детерминистік криптографиялық қауіпсіз
12
+ * кездейсоқ секіру (CSPRNG Spacing) алгоритмі әзірленді.
13
+ * 3. Encrypted L2 Cache (IndexedDB): Кэштегі деректерді XSS шабуылдары мен зиянды кеңейтілімдерден қорғау үшін,
14
+ * ашық мәтін (plaintext) сақтау тоқтатылды. IndexedDB қоймасына жазылатын әрбір мәлімет
15
+ * тек браузердің белсенді жадында (Session Runtime Memory) өмір сүретін AES-256-GCM кілтімен шифрланады.
12
16
  */
13
17
  // =========================================================================
14
18
  // БАЗАЛЫҚ БАЙТТЫҚ КОНВЕРТОРЛАР (BASE64)
@@ -30,20 +34,6 @@ function base64ToBytes(base64) {
30
34
  }
31
35
  return bytes;
32
36
  }
33
- // Mulberry32 құпия кілт негізіндегі кездейсоқ сандар генераторы (Deterministic Seeded PRNG)
34
- function createRng(seedStr) {
35
- let h = 2166136261 >>> 0;
36
- for (let i = 0; i < seedStr.length; i++) {
37
- h = Math.imul(h ^ seedStr.charCodeAt(i), 16777619);
38
- }
39
- let seed = h >>> 0;
40
- return function () {
41
- let t = seed += 0x6D2B79F5;
42
- t = Math.imul(t ^ (t >>> 15), t | 1);
43
- t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
44
- return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
45
- };
46
- }
47
37
  // CRC32 бақылау қосындысын (Checksum) есептеу алгоритмі
48
38
  function crc32(bytes) {
49
39
  const table = new Uint32Array(256);
@@ -61,13 +51,36 @@ function crc32(bytes) {
61
51
  return (crc ^ -1) >>> 0;
62
52
  }
63
53
  // =========================================================================
64
- // WEB CRYPTO API БРАУЗЕРЛІК КРИПТОГРАФИЯ (AES-256-GCM)
54
+ // WEB CRYPTO API БРАУЗЕРЛІК КРИПТОГРАФИЯ (PBKDF2 & AES-256-GCM)
65
55
  // =========================================================================
56
+ /**
57
+ * Пайдаланушының құпия сөзінен PBKDF2 (HMAC-SHA256, 100,000 iterations)
58
+ * арқылы жоғары энтропиялы AES-256-GCM кілтін алу.
59
+ */
66
60
  async function deriveAesKey(secretKey) {
67
61
  const encoder = new TextEncoder();
68
62
  const keyData = encoder.encode(secretKey);
69
- const hash = await crypto.subtle.digest("SHA-256", keyData);
70
- return await crypto.subtle.importKey("raw", hash, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
63
+ // Бастапқы шифрды PBKDF2 үшін импорттау
64
+ const baseKey = await crypto.subtle.importKey("raw", keyData, { name: "PBKDF2" }, false, ["deriveKey"]);
65
+ // Тұрақты бірегей Enterprise Salt
66
+ const salt = encoder.encode("nuralem_bult_enterprise_salt_2026");
67
+ return await crypto.subtle.deriveKey({
68
+ name: "PBKDF2",
69
+ salt: salt,
70
+ iterations: 100000,
71
+ hash: "SHA-256"
72
+ }, baseKey, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
73
+ }
74
+ /**
75
+ * Web Crypto API AES-GCM көмегімен детерминистік криптографиялық қауіпсіз
76
+ * кездейсоқ байттар ағынын (keystream) генерациялау.
77
+ */
78
+ async function generateDeterministicKeystream(aesKey, length) {
79
+ const emptyBuffer = new Uint8Array(length);
80
+ // Детерминистік IV (тек қана CSPRNG keystream алу үшін қолданылады)
81
+ const iv = new Uint8Array(12); // барлығы 0
82
+ const encryptedBuffer = await crypto.subtle.encrypt({ name: "AES-GCM", iv: iv }, aesKey, emptyBuffer);
83
+ return new Uint8Array(encryptedBuffer).slice(0, length);
71
84
  }
72
85
  async function encryptDataNative(payloadJson, secretKey) {
73
86
  const cryptoKey = await deriveAesKey(secretKey);
@@ -91,14 +104,53 @@ async function decryptDataNative(encryptedBytes, secretKey) {
91
104
  const decryptedBuffer = await crypto.subtle.decrypt({ name: "AES-GCM", iv: iv }, cryptoKey, ciphertext);
92
105
  return new TextDecoder().decode(decryptedBuffer);
93
106
  }
107
+ // =========================================================================
108
+ // L2 CACHE DATA ENCRYPTION FOR INDEXEDDB SECURE STORAGE
109
+ // =========================================================================
110
+ async function encryptCacheData(data, key) {
111
+ const encoder = new TextEncoder();
112
+ const rawJson = JSON.stringify(data);
113
+ const payloadBytes = encoder.encode(rawJson);
114
+ const iv = crypto.getRandomValues(new Uint8Array(12));
115
+ const encryptedBuffer = await crypto.subtle.encrypt({ name: "AES-GCM", iv: iv }, key, payloadBytes);
116
+ const ciphertextBytes = new Uint8Array(encryptedBuffer);
117
+ const finalBytes = new Uint8Array(12 + ciphertextBytes.length);
118
+ finalBytes.set(iv, 0);
119
+ finalBytes.set(ciphertextBytes, 12);
120
+ return bytesToBase64(finalBytes);
121
+ }
122
+ async function decryptCacheData(base64Str, key) {
123
+ const finalBytes = base64ToBytes(base64Str);
124
+ if (finalBytes.length < 12) {
125
+ throw new Error("Decryption failed: Cache block truncated");
126
+ }
127
+ const iv = finalBytes.slice(0, 12);
128
+ const ciphertext = finalBytes.slice(12);
129
+ const decryptedBuffer = await crypto.subtle.decrypt({ name: "AES-GCM", iv: iv }, key, ciphertext);
130
+ const jsonStr = new TextDecoder().decode(decryptedBuffer);
131
+ return JSON.parse(jsonStr);
132
+ }
94
133
  class NuralemBultCache {
95
134
  dbName = "NuralemBultCache";
96
135
  storeName = "documents";
97
136
  db = null;
98
137
  TTL_DURATION = 24 * 60 * 60 * 1000; // 24 сағат өмір сүру уақыты
99
138
  MAX_ITEMS = 100; // LRU үшін максималды құжат саны
139
+ // Тек браузердің белсенді жадында (Session Runtime Memory) өмір сүретін кілт
140
+ sessionKey = null;
100
141
  constructor() { }
101
- async init() {
142
+ async init(secretKey) {
143
+ // 1. Пайдаланушының құпия сөзінен PBKDF2 арқылы L2 кэшті қорғайтын кілтті шығару (derived key)
144
+ const encoder = new TextEncoder();
145
+ const keyData = encoder.encode(secretKey);
146
+ const baseKey = await crypto.subtle.importKey("raw", keyData, { name: "PBKDF2" }, false, ["deriveKey"]);
147
+ const salt = encoder.encode("nuralem_bult_l2_cache_salt_2026");
148
+ this.sessionKey = await crypto.subtle.deriveKey({
149
+ name: "PBKDF2",
150
+ salt: salt,
151
+ iterations: 10000, // Кэш үшін оңтайлы жылдамдық
152
+ hash: "SHA-256"
153
+ }, baseKey, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
102
154
  return new Promise((resolve, reject) => {
103
155
  const request = indexedDB.open(this.dbName, 1);
104
156
  request.onupgradeneeded = () => {
@@ -118,7 +170,7 @@ class NuralemBultCache {
118
170
  }
119
171
  async get(key) {
120
172
  return new Promise((resolve, reject) => {
121
- if (!this.db)
173
+ if (!this.db || !this.sessionKey)
122
174
  return resolve(null);
123
175
  const transaction = this.db.transaction(this.storeName, "readonly");
124
176
  const store = transaction.objectStore(this.storeName);
@@ -133,30 +185,46 @@ class NuralemBultCache {
133
185
  await this.delete(key);
134
186
  return resolve(null);
135
187
  }
136
- // LRU саясаты үшін соңғы қолданылған уақытты жаңарту (асинхронды)
137
- ctxUpdateLastUsed(this.db, this.storeName, entry);
138
- resolve(entry.value);
188
+ try {
189
+ // Кэштегі деректі дешифрлеу (XSS қорғанысы)
190
+ const decryptedValue = await decryptCacheData(entry.encryptedValue, this.sessionKey);
191
+ // LRU саясаты үшін соңғы қолданылған уақытты жаңарту (асинхронды)
192
+ ctxUpdateLastUsed(this.db, this.storeName, entry);
193
+ resolve(decryptedValue);
194
+ }
195
+ catch (e) {
196
+ console.error(`[NuralemBult Cache] Decryption failed (Key: "${key}"). Purging corrupted cache...`, e);
197
+ await this.delete(key);
198
+ resolve(null);
199
+ }
139
200
  };
140
201
  request.onerror = () => reject(request.error);
141
202
  });
142
203
  }
143
204
  async set(key, value) {
144
205
  return new Promise(async (resolve, reject) => {
145
- if (!this.db)
146
- return reject(new Error("IndexedDB database is not initialized under Nuralem Bult"));
206
+ if (!this.db || !this.sessionKey)
207
+ return reject(new Error("IndexedDB database or sessionKey is not initialized"));
147
208
  // Сыйымдылық шегінен (LRU) асса ең ескі құжатты өшіру
148
209
  await this.enforceLruEviction();
149
- const transaction = this.db.transaction(this.storeName, "readwrite");
150
- const store = transaction.objectStore(this.storeName);
151
- const entry = {
152
- key,
153
- value,
154
- timestamp: Date.now(),
155
- lastUsed: Date.now()
156
- };
157
- const request = store.put(entry);
158
- request.onsuccess = () => resolve();
159
- request.onerror = () => reject(request.error);
210
+ try {
211
+ // Деректі L2 кілтімен шифрлау
212
+ const encryptedValue = await encryptCacheData(value, this.sessionKey);
213
+ const transaction = this.db.transaction(this.storeName, "readwrite");
214
+ const store = transaction.objectStore(this.storeName);
215
+ const entry = {
216
+ key,
217
+ encryptedValue,
218
+ timestamp: Date.now(),
219
+ lastUsed: Date.now()
220
+ };
221
+ const request = store.put(entry);
222
+ request.onsuccess = () => resolve();
223
+ request.onerror = () => reject(request.error);
224
+ }
225
+ catch (e) {
226
+ reject(e);
227
+ }
160
228
  });
161
229
  }
162
230
  async delete(key) {
@@ -230,9 +298,10 @@ export class NuralemBult {
230
298
  this.instance.routerUrl = routerUrl.replace(/\/$/, "");
231
299
  this.instance.apiKey = apiKey;
232
300
  this.instance.secretKey = secretKey;
233
- await this.instance.cache.init();
301
+ // Кэшті пайдаланушының secretKey кілті арқылы инициализациялау (PBKDF2 L2 Key)
302
+ await this.instance.cache.init(secretKey);
234
303
  this.instance.isInitialized = true;
235
- console.log("[NuralemBult] SDK v1.1.0 initialized successfully.");
304
+ console.log("[NuralemBult] SDK v1.2.0 Enterprise Hardened initialized successfully.");
236
305
  }
237
306
  return this.instance;
238
307
  }
@@ -434,76 +503,84 @@ export class NuralemBult {
434
503
  * OPAQUE RGB STEGANOGRAPHY (Түстердің қысылуы мен аномалиясынан 100% қорғалған)
435
504
  * Деректер тек R, G, B арналарының LSB-іне жазылады, ал Alpha арнасы қатаң түрде 255 болып қалады.
436
505
  * Түстердің қысылуынан (Color Quantization) қорғау үшін 32-байттық Padding және CRC32 Checksum енгізілген.
506
+ * Mulberry32 PRNG орнына Web Crypto API нативті AES (Keystream) негізіндегі детерминистік CSPRNG біріктірілген.
437
507
  */
438
- injectBytesToPngNative(payloadBytes) {
508
+ async injectBytesToPngNative(payloadBytes) {
509
+ const payloadLen = payloadBytes.length;
510
+ // CRC32 бақылау қосындысын есептеу
511
+ const payloadCrc = crc32(payloadBytes);
512
+ // Браузерлік қысу және шеткі пиксель ауытқуларынан қорғайтын 32-байттық нөлдік Padding
513
+ const paddingLen = 32;
514
+ const paddingBytes = new Uint8Array(paddingLen);
515
+ // Жалпы құрылым: [4 байт: payloadLen] [4 байт: CRC32] [payloadBytes] [32 байт: Padding]
516
+ const totalLen = 4 + 4 + payloadLen + paddingLen;
517
+ const payloadWithLen = new Uint8Array(totalLen);
518
+ // 1. Ұзындығы (Big-Endian)
519
+ const lenBytes = new Uint8Array(new Uint32Array([payloadLen]).buffer).reverse();
520
+ payloadWithLen.set(lenBytes, 0);
521
+ // 2. CRC32 Checksum (Big-Endian)
522
+ const crcBytes = new Uint8Array(new Uint32Array([payloadCrc]).buffer).reverse();
523
+ payloadWithLen.set(crcBytes, 4);
524
+ // 3. Шифрланған негізгі деректер
525
+ payloadWithLen.set(payloadBytes, 8);
526
+ // 4. Тұрақтандырушы Padding
527
+ payloadWithLen.set(paddingBytes, 8 + payloadLen);
528
+ const totalBits = payloadWithLen.length * 8;
529
+ const totalPixels = Math.ceil(totalBits / 3); // Әр пиксельде 3 бит (RGB LSB)
530
+ const size = Math.ceil(Math.sqrt(totalPixels)) + 4;
531
+ const totalRgbBytes = size * size * 3;
532
+ // Нативті PBKDF2 және AES-GCM арқылы детерминистік CSPRNG (Keystream) алу
533
+ const aesKey = await deriveAesKey(this.secretKey);
534
+ const keystream = await generateDeterministicKeystream(aesKey, totalRgbBytes);
535
+ let keystreamIdx = 0;
536
+ const getNextCryptoRand = () => {
537
+ const byteVal = keystream[keystreamIdx++];
538
+ return byteVal / 256; // 0-ден 1-ге дейінгі floating кездейсоқ санын алу
539
+ };
540
+ const canvas = document.createElement("canvas");
541
+ canvas.width = size;
542
+ canvas.height = size;
543
+ // srgb түстік кеңістігін орнату арқылы браузер деңгейіндегі бұрмалаудың алдын алу
544
+ const ctx = canvas.getContext("2d", { colorSpace: "srgb" });
545
+ const grad = ctx.createLinearGradient(0, 0, size, size);
546
+ grad.addColorStop(0, "#1f4068");
547
+ grad.addColorStop(0.5, "#162447");
548
+ grad.addColorStop(1, "#e43f5a");
549
+ ctx.fillStyle = grad;
550
+ ctx.fillRect(0, 0, size, size);
551
+ const imageData = ctx.getImageData(0, 0, size, size);
552
+ const pixels = imageData.data;
553
+ let idx = 0;
554
+ for (let i = 0; i < totalBits; i++) {
555
+ const remainingBytes = totalRgbBytes - idx;
556
+ const remainingBits = totalBits - i;
557
+ const max_step = Math.floor(remainingBytes / remainingBits);
558
+ const step = max_step > 1 ? Math.floor(getNextCryptoRand() * max_step) + 1 : 1;
559
+ idx += step;
560
+ const rgbByteIdx = idx - 1;
561
+ // Битті анықтау
562
+ const bytePos = Math.floor(i / 8);
563
+ const bitPos = 7 - (i % 8);
564
+ const bit = (payloadWithLen[bytePos] >> bitPos) & 1;
565
+ // RGB индексін pixel RGBA индексіне көшіру (Alpha қатаң түрде 255 болып қалады)
566
+ const pixelIdx = Math.floor(rgbByteIdx / 3);
567
+ const channel = rgbByteIdx % 3; // 0: R, 1: G, 2: B
568
+ const actualFlatIdx = pixelIdx * 4 + channel;
569
+ // Байттың LSB-ін жаңарту
570
+ pixels[actualFlatIdx] = (pixels[actualFlatIdx] & 0xFE) | bit;
571
+ }
572
+ // Alpha арнасын 255 (толық ашық емес) етіп бекіту
573
+ for (let p = 0; p < size * size; p++) {
574
+ pixels[p * 4 + 3] = 255;
575
+ }
576
+ ctx.putImageData(imageData, 0, 0);
439
577
  return new Promise((resolve) => {
440
- const payloadLen = payloadBytes.length;
441
- // CRC32 бақылау қосындысын есептеу
442
- const payloadCrc = crc32(payloadBytes);
443
- // Браузерлік қысу және шеткі пиксель ауытқуларынан қорғайтын 32-байттық нөлдік Padding
444
- const paddingLen = 32;
445
- const paddingBytes = new Uint8Array(paddingLen);
446
- // Жалпы құрылым: [4 байт: payloadLen] [4 байт: CRC32] [payloadBytes] [32 байт: Padding]
447
- const totalLen = 4 + 4 + payloadLen + paddingLen;
448
- const payloadWithLen = new Uint8Array(totalLen);
449
- // 1. Ұзындығы (Big-Endian)
450
- const lenBytes = new Uint8Array(new Uint32Array([payloadLen]).buffer).reverse();
451
- payloadWithLen.set(lenBytes, 0);
452
- // 2. CRC32 Checksum (Big-Endian)
453
- const crcBytes = new Uint8Array(new Uint32Array([payloadCrc]).buffer).reverse();
454
- payloadWithLen.set(crcBytes, 4);
455
- // 3. Шифрланған негізгі деректер
456
- payloadWithLen.set(payloadBytes, 8);
457
- // 4. Тұрақтандырушы Padding
458
- payloadWithLen.set(paddingBytes, 8 + payloadLen);
459
- const totalBits = payloadWithLen.length * 8;
460
- const totalPixels = Math.ceil(totalBits / 3); // Әр пиксельде 3 бит (RGB LSB)
461
- const size = Math.ceil(Math.sqrt(totalPixels)) + 4;
462
- const canvas = document.createElement("canvas");
463
- canvas.width = size;
464
- canvas.height = size;
465
- // srgb түстік кеңістігін орнату арқылы браузер деңгейіндегі бұрмалаудың алдын алу
466
- const ctx = canvas.getContext("2d", { colorSpace: "srgb" });
467
- const grad = ctx.createLinearGradient(0, 0, size, size);
468
- grad.addColorStop(0, "#1f4068");
469
- grad.addColorStop(0.5, "#162447");
470
- grad.addColorStop(1, "#e43f5a");
471
- ctx.fillStyle = grad;
472
- ctx.fillRect(0, 0, size, size);
473
- const imageData = ctx.getImageData(0, 0, size, size);
474
- const pixels = imageData.data;
475
- const totalRgbBytes = size * size * 3;
476
- const rng = createRng(this.secretKey);
477
- let idx = 0;
478
- for (let i = 0; i < totalBits; i++) {
479
- const remainingBytes = totalRgbBytes - idx;
480
- const remainingBits = totalBits - i;
481
- const max_step = Math.floor(remainingBytes / remainingBits);
482
- const step = max_step > 1 ? Math.floor(rng() * max_step) + 1 : 1;
483
- idx += step;
484
- const rgbByteIdx = idx - 1;
485
- // Битті анықтау
486
- const bytePos = Math.floor(i / 8);
487
- const bitPos = 7 - (i % 8);
488
- const bit = (payloadWithLen[bytePos] >> bitPos) & 1;
489
- // RGB индексін pixel RGBA индексіне көшіру (Alpha қатаң түрде 255 болып қалады)
490
- const pixelIdx = Math.floor(rgbByteIdx / 3);
491
- const channel = rgbByteIdx % 3; // 0: R, 1: G, 2: B
492
- const actualFlatIdx = pixelIdx * 4 + channel;
493
- // Байттың LSB-ін жаңарту
494
- pixels[actualFlatIdx] = (pixels[actualFlatIdx] & 0xFE) | bit;
495
- }
496
- // Alpha арнасын 255 (толық ашық емес) етіп бекіту
497
- for (let p = 0; p < size * size; p++) {
498
- pixels[p * 4 + 3] = 255;
499
- }
500
- ctx.putImageData(imageData, 0, 0);
501
578
  canvas.toBlob((blob) => resolve(blob), "image/png");
502
579
  });
503
580
  }
504
581
  /**
505
582
  * OPAQUE RGB STEGANOGRAPHY арқылы жазылған деректі пиксельдерден оқу
506
- * CRC32 бақылау қосындысын және белсенді Padding құрылымын автоматты түрде тексереді.
583
+ * CRC32 бақылау қосындысын және белсенді Padding құрылымын автоматты түрде CSPRNG арқылы тексереді.
507
584
  */
508
585
  async extractBytesFromPngNative(stegoPngBytes) {
509
586
  const blob = new Blob([stegoPngBytes], { type: "image/png" });
@@ -520,7 +597,14 @@ export class NuralemBult {
520
597
  const imageData = ctx.getImageData(0, 0, img.width, img.height);
521
598
  const pixels = imageData.data;
522
599
  const totalRgbBytes = img.width * img.height * 3;
523
- const rng = createRng(this.secretKey);
600
+ // Нативті PBKDF2 және AES-GCM арқылы детерминистік CSPRNG (Keystream) алу
601
+ const aesKey = await deriveAesKey(this.secretKey);
602
+ const keystream = await generateDeterministicKeystream(aesKey, totalRgbBytes);
603
+ let keystreamIdx = 0;
604
+ const getNextCryptoRand = () => {
605
+ const byteVal = keystream[keystreamIdx++];
606
+ return byteVal / 256;
607
+ };
524
608
  let idx = 0;
525
609
  // 1. Ұзындықты оқу (32 бит = 4 байт)
526
610
  const lenBytes = new Uint8Array(4);
@@ -529,7 +613,7 @@ export class NuralemBult {
529
613
  const remainingBytes = totalRgbBytes - idx;
530
614
  const remainingBits = lenBits - i;
531
615
  const max_step = Math.floor(remainingBytes / remainingBits);
532
- const step = max_step > 1 ? Math.floor(rng() * max_step) + 1 : 1;
616
+ const step = max_step > 1 ? Math.floor(getNextCryptoRand() * max_step) + 1 : 1;
533
617
  idx += step;
534
618
  const rgbByteIdx = idx - 1;
535
619
  const pixelIdx = Math.floor(rgbByteIdx / 3);
@@ -548,7 +632,7 @@ export class NuralemBult {
548
632
  const remainingBytes = totalRgbBytes - idx;
549
633
  const remainingBits = crcBits - i;
550
634
  const max_step = Math.floor(remainingBytes / remainingBits);
551
- const step = max_step > 1 ? Math.floor(rng() * max_step) + 1 : 1;
635
+ const step = max_step > 1 ? Math.floor(getNextCryptoRand() * max_step) + 1 : 1;
552
636
  idx += step;
553
637
  const rgbByteIdx = idx - 1;
554
638
  const pixelIdx = Math.floor(rgbByteIdx / 3);
@@ -571,7 +655,7 @@ export class NuralemBult {
571
655
  const remainingBytes = totalRgbBytes - idx;
572
656
  const remainingBits = totalPayloadBits - i;
573
657
  const max_step = Math.floor(remainingBytes / remainingBits);
574
- const step = max_step > 1 ? Math.floor(rng() * max_step) + 1 : 1;
658
+ const step = max_step > 1 ? Math.floor(getNextCryptoRand() * max_step) + 1 : 1;
575
659
  idx += step;
576
660
  const rgbByteIdx = idx - 1;
577
661
  const pixelIdx = Math.floor(rgbByteIdx / 3);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuralem-bult-sdk",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Serverless Decentralized Document-based polymorphic NoSQL database with client-side caching and storage abstraction adapter. Developed under Nuralem Bult Ecosystem.",
5
5
  "main": "dist/NuralemBult.js",
6
6
  "types": "dist/NuralemBult.d.ts",