@cj-tech-master/excelts 8.0.0 → 8.1.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/README.md +14 -1
- package/README_zh.md +6 -0
- package/dist/browser/modules/archive/zip/stream.d.ts +4 -0
- package/dist/browser/modules/archive/zip/stream.js +53 -0
- package/dist/browser/modules/pdf/core/crypto.d.ts +65 -0
- package/dist/browser/modules/pdf/core/crypto.js +637 -0
- package/dist/browser/modules/pdf/core/encryption.d.ts +23 -20
- package/dist/browser/modules/pdf/core/encryption.js +88 -261
- package/dist/browser/modules/pdf/core/pdf-writer.d.ts +6 -4
- package/dist/browser/modules/pdf/core/pdf-writer.js +19 -10
- package/dist/browser/modules/pdf/index.d.ts +23 -2
- package/dist/browser/modules/pdf/index.js +21 -3
- package/dist/browser/modules/pdf/reader/annotation-extractor.d.ts +63 -0
- package/dist/browser/modules/pdf/reader/annotation-extractor.js +155 -0
- package/dist/browser/modules/pdf/reader/cmap-parser.d.ts +70 -0
- package/dist/browser/modules/pdf/reader/cmap-parser.js +321 -0
- package/dist/browser/modules/pdf/reader/content-interpreter.d.ts +57 -0
- package/dist/browser/modules/pdf/reader/content-interpreter.js +715 -0
- package/dist/browser/modules/pdf/reader/font-decoder.d.ts +58 -0
- package/dist/browser/modules/pdf/reader/font-decoder.js +1513 -0
- package/dist/browser/modules/pdf/reader/form-extractor.d.ts +48 -0
- package/dist/browser/modules/pdf/reader/form-extractor.js +355 -0
- package/dist/browser/modules/pdf/reader/image-extractor.d.ts +55 -0
- package/dist/browser/modules/pdf/reader/image-extractor.js +220 -0
- package/dist/browser/modules/pdf/reader/metadata-reader.d.ts +56 -0
- package/dist/browser/modules/pdf/reader/metadata-reader.js +275 -0
- package/dist/browser/modules/pdf/reader/pdf-decrypt.d.ts +26 -0
- package/dist/browser/modules/pdf/reader/pdf-decrypt.js +443 -0
- package/dist/browser/modules/pdf/reader/pdf-document.d.ts +191 -0
- package/dist/browser/modules/pdf/reader/pdf-document.js +818 -0
- package/dist/browser/modules/pdf/reader/pdf-parser.d.ts +65 -0
- package/dist/browser/modules/pdf/reader/pdf-parser.js +285 -0
- package/dist/browser/modules/pdf/reader/pdf-reader.d.ts +143 -0
- package/dist/browser/modules/pdf/reader/pdf-reader.js +200 -0
- package/dist/browser/modules/pdf/reader/pdf-tokenizer.d.ts +101 -0
- package/dist/browser/modules/pdf/reader/pdf-tokenizer.js +543 -0
- package/dist/browser/modules/pdf/reader/reader-utils.d.ts +15 -0
- package/dist/browser/modules/pdf/reader/reader-utils.js +27 -0
- package/dist/browser/modules/pdf/reader/stream-filters.d.ts +20 -0
- package/dist/browser/modules/pdf/reader/stream-filters.js +456 -0
- package/dist/browser/modules/pdf/reader/text-reconstruction.d.ts +44 -0
- package/dist/browser/modules/pdf/reader/text-reconstruction.js +463 -0
- package/dist/cjs/modules/archive/zip/stream.js +53 -0
- package/dist/cjs/modules/pdf/core/crypto.js +649 -0
- package/dist/cjs/modules/pdf/core/encryption.js +88 -263
- package/dist/cjs/modules/pdf/core/pdf-writer.js +19 -10
- package/dist/cjs/modules/pdf/index.js +23 -4
- package/dist/cjs/modules/pdf/reader/annotation-extractor.js +158 -0
- package/dist/cjs/modules/pdf/reader/cmap-parser.js +326 -0
- package/dist/cjs/modules/pdf/reader/content-interpreter.js +718 -0
- package/dist/cjs/modules/pdf/reader/font-decoder.js +1518 -0
- package/dist/cjs/modules/pdf/reader/form-extractor.js +358 -0
- package/dist/cjs/modules/pdf/reader/image-extractor.js +223 -0
- package/dist/cjs/modules/pdf/reader/metadata-reader.js +278 -0
- package/dist/cjs/modules/pdf/reader/pdf-decrypt.js +447 -0
- package/dist/cjs/modules/pdf/reader/pdf-document.js +822 -0
- package/dist/cjs/modules/pdf/reader/pdf-parser.js +301 -0
- package/dist/cjs/modules/pdf/reader/pdf-reader.js +203 -0
- package/dist/cjs/modules/pdf/reader/pdf-tokenizer.js +517 -0
- package/dist/cjs/modules/pdf/reader/reader-utils.js +30 -0
- package/dist/cjs/modules/pdf/reader/stream-filters.js +459 -0
- package/dist/cjs/modules/pdf/reader/text-reconstruction.js +467 -0
- package/dist/esm/modules/archive/zip/stream.js +53 -0
- package/dist/esm/modules/pdf/core/crypto.js +637 -0
- package/dist/esm/modules/pdf/core/encryption.js +88 -261
- package/dist/esm/modules/pdf/core/pdf-writer.js +19 -10
- package/dist/esm/modules/pdf/index.js +21 -3
- package/dist/esm/modules/pdf/reader/annotation-extractor.js +155 -0
- package/dist/esm/modules/pdf/reader/cmap-parser.js +321 -0
- package/dist/esm/modules/pdf/reader/content-interpreter.js +715 -0
- package/dist/esm/modules/pdf/reader/font-decoder.js +1513 -0
- package/dist/esm/modules/pdf/reader/form-extractor.js +355 -0
- package/dist/esm/modules/pdf/reader/image-extractor.js +220 -0
- package/dist/esm/modules/pdf/reader/metadata-reader.js +275 -0
- package/dist/esm/modules/pdf/reader/pdf-decrypt.js +443 -0
- package/dist/esm/modules/pdf/reader/pdf-document.js +818 -0
- package/dist/esm/modules/pdf/reader/pdf-parser.js +285 -0
- package/dist/esm/modules/pdf/reader/pdf-reader.js +200 -0
- package/dist/esm/modules/pdf/reader/pdf-tokenizer.js +543 -0
- package/dist/esm/modules/pdf/reader/reader-utils.js +27 -0
- package/dist/esm/modules/pdf/reader/stream-filters.js +456 -0
- package/dist/esm/modules/pdf/reader/text-reconstruction.js +463 -0
- package/dist/iife/excelts.iife.js +703 -267
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +35 -35
- package/dist/types/modules/archive/zip/stream.d.ts +4 -0
- package/dist/types/modules/pdf/core/crypto.d.ts +65 -0
- package/dist/types/modules/pdf/core/encryption.d.ts +23 -20
- package/dist/types/modules/pdf/core/pdf-writer.d.ts +6 -4
- package/dist/types/modules/pdf/index.d.ts +23 -2
- package/dist/types/modules/pdf/reader/annotation-extractor.d.ts +63 -0
- package/dist/types/modules/pdf/reader/cmap-parser.d.ts +70 -0
- package/dist/types/modules/pdf/reader/content-interpreter.d.ts +57 -0
- package/dist/types/modules/pdf/reader/font-decoder.d.ts +58 -0
- package/dist/types/modules/pdf/reader/form-extractor.d.ts +48 -0
- package/dist/types/modules/pdf/reader/image-extractor.d.ts +55 -0
- package/dist/types/modules/pdf/reader/metadata-reader.d.ts +56 -0
- package/dist/types/modules/pdf/reader/pdf-decrypt.d.ts +26 -0
- package/dist/types/modules/pdf/reader/pdf-document.d.ts +191 -0
- package/dist/types/modules/pdf/reader/pdf-parser.d.ts +65 -0
- package/dist/types/modules/pdf/reader/pdf-reader.d.ts +143 -0
- package/dist/types/modules/pdf/reader/pdf-tokenizer.d.ts +101 -0
- package/dist/types/modules/pdf/reader/reader-utils.d.ts +15 -0
- package/dist/types/modules/pdf/reader/stream-filters.d.ts +20 -0
- package/dist/types/modules/pdf/reader/text-reconstruction.d.ts +44 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @cj-tech-master/excelts v8.
|
|
2
|
+
* @cj-tech-master/excelts v8.1.0
|
|
3
3
|
* Zero-dependency TypeScript toolkit — Excel (XLSX), PDF, CSV, Markdown, XML, ZIP/TAR, and streaming.
|
|
4
4
|
* (c) 2026 cjnoname
|
|
5
5
|
* Released under the MIT License
|
|
@@ -27555,7 +27555,7 @@ self.onmessage = async function(event) {
|
|
|
27555
27555
|
/**
|
|
27556
27556
|
* Generate random bytes.
|
|
27557
27557
|
*/
|
|
27558
|
-
function randomBytes(length) {
|
|
27558
|
+
function randomBytes$1(length) {
|
|
27559
27559
|
return getRandomValues(new Uint8Array(length));
|
|
27560
27560
|
}
|
|
27561
27561
|
/**
|
|
@@ -27709,7 +27709,7 @@ self.onmessage = async function(event) {
|
|
|
27709
27709
|
*/
|
|
27710
27710
|
async function aesEncrypt(data, password, keyStrength) {
|
|
27711
27711
|
const saltLen = AES_SALT_LENGTH[keyStrength];
|
|
27712
|
-
const salt = randomBytes(saltLen);
|
|
27712
|
+
const salt = randomBytes$1(saltLen);
|
|
27713
27713
|
const keys = await aesDerive(password, salt, keyStrength);
|
|
27714
27714
|
const ciphertext = await aesCtr(keys.encryptionKey, data, true);
|
|
27715
27715
|
const hmac = await aesComputeHmac(keys.hmacKey, ciphertext);
|
|
@@ -28531,6 +28531,12 @@ self.onmessage = async function(event) {
|
|
|
28531
28531
|
* - In browser builds the bundler aliases those imports to their browser variants.
|
|
28532
28532
|
*/
|
|
28533
28533
|
const SMART_STORE_DECIDE_BYTES = 16 * 1024;
|
|
28534
|
+
/** Input batching threshold for push(). Small chunks are accumulated in an
|
|
28535
|
+
* internal buffer and flushed to the compression pipeline once this size is
|
|
28536
|
+
* reached. 64 KB matches the standard deflate window and keeps the number
|
|
28537
|
+
* of async push() calls — each of which creates a full Promise chain in the
|
|
28538
|
+
* browser CompressionStream path — down to a manageable level. */
|
|
28539
|
+
const INPUT_BATCH_BYTES = 65536;
|
|
28534
28540
|
/**
|
|
28535
28541
|
* True Streaming ZIP File - compresses chunk by chunk
|
|
28536
28542
|
*/
|
|
@@ -28566,6 +28572,8 @@ self.onmessage = async function(event) {
|
|
|
28566
28572
|
this._dataQueue = [];
|
|
28567
28573
|
this._finalQueued = false;
|
|
28568
28574
|
this._pushChain = Promise.resolve();
|
|
28575
|
+
this._inputBuf = null;
|
|
28576
|
+
this._inputPos = 0;
|
|
28569
28577
|
this._syncDeflater = null;
|
|
28570
28578
|
this._syncZlibReady = false;
|
|
28571
28579
|
const resolvedName = options?.path ? normalizeZipPath(name, options.path) : name;
|
|
@@ -28641,7 +28649,7 @@ self.onmessage = async function(event) {
|
|
|
28641
28649
|
if (this._zipCryptoState || this._encryptionMethod !== "zipcrypto") return;
|
|
28642
28650
|
this._zipCryptoState = zipCryptoInitKeys(this._password);
|
|
28643
28651
|
const dosTimeForCheck = this.dosTime << 16 | this.dosDate;
|
|
28644
|
-
const header = zipCryptoCreateHeader(this._zipCryptoState, dosTimeForCheck, randomBytes);
|
|
28652
|
+
const header = zipCryptoCreateHeader(this._zipCryptoState, dosTimeForCheck, randomBytes$1);
|
|
28645
28653
|
this._compressedSize += header.length;
|
|
28646
28654
|
this._enqueueData(header, false);
|
|
28647
28655
|
}
|
|
@@ -28992,6 +29000,34 @@ self.onmessage = async function(event) {
|
|
|
28992
29000
|
}
|
|
28993
29001
|
return Promise.resolve();
|
|
28994
29002
|
}
|
|
29003
|
+
if (!final && data.length > 0 && data.length < INPUT_BATCH_BYTES) {
|
|
29004
|
+
if (!this._inputBuf) {
|
|
29005
|
+
this._inputBuf = new Uint8Array(INPUT_BATCH_BYTES);
|
|
29006
|
+
this._inputPos = 0;
|
|
29007
|
+
}
|
|
29008
|
+
if (this._inputPos + data.length <= INPUT_BATCH_BYTES) {
|
|
29009
|
+
this._inputBuf.set(data, this._inputPos);
|
|
29010
|
+
this._inputPos += data.length;
|
|
29011
|
+
callback?.();
|
|
29012
|
+
return Promise.resolve();
|
|
29013
|
+
}
|
|
29014
|
+
const combined = new Uint8Array(this._inputPos + data.length);
|
|
29015
|
+
combined.set(this._inputBuf.subarray(0, this._inputPos));
|
|
29016
|
+
combined.set(data, this._inputPos);
|
|
29017
|
+
this._inputPos = 0;
|
|
29018
|
+
return this._pushAsync(combined, false, callback);
|
|
29019
|
+
}
|
|
29020
|
+
if (this._inputPos > 0) {
|
|
29021
|
+
const flushData = this._inputBuf.slice(0, this._inputPos);
|
|
29022
|
+
this._inputPos = 0;
|
|
29023
|
+
const promise = this._pushChain = this._pushAsync(flushData, false).then(() => this._pushUnchained(data, final, callback), () => this._pushUnchained(data, final, callback));
|
|
29024
|
+
promise.catch(() => {});
|
|
29025
|
+
return promise;
|
|
29026
|
+
}
|
|
29027
|
+
return this._pushAsync(data, final, callback);
|
|
29028
|
+
}
|
|
29029
|
+
/** Enqueue an async push through the _pushChain serialization. */
|
|
29030
|
+
_pushAsync(data, final, callback) {
|
|
28995
29031
|
const promise = this._pushChain = this._pushChain.then(() => this._pushUnchained(data, final, callback), () => this._pushUnchained(data, final, callback));
|
|
28996
29032
|
promise.catch(() => {});
|
|
28997
29033
|
return promise;
|
|
@@ -44669,228 +44705,597 @@ onmessage = async (ev) => {
|
|
|
44669
44705
|
return err instanceof PdfError;
|
|
44670
44706
|
}
|
|
44671
44707
|
//#endregion
|
|
44672
|
-
//#region src/modules/pdf/core/
|
|
44673
|
-
/**
|
|
44674
|
-
|
|
44675
|
-
|
|
44676
|
-
|
|
44677
|
-
|
|
44678
|
-
|
|
44679
|
-
|
|
44708
|
+
//#region src/modules/pdf/core/crypto.ts
|
|
44709
|
+
/**
|
|
44710
|
+
* Shared cryptographic primitives for PDF encryption/decryption.
|
|
44711
|
+
*
|
|
44712
|
+
* Zero-dependency, pure JavaScript implementations of:
|
|
44713
|
+
* - AES (128/256-bit) CBC encrypt and decrypt
|
|
44714
|
+
* - SHA-256
|
|
44715
|
+
* - MD5
|
|
44716
|
+
* - RC4 (for reading legacy PDFs only)
|
|
44717
|
+
*
|
|
44718
|
+
* @see FIPS 197 — AES
|
|
44719
|
+
* @see FIPS 180-4 — SHA-256
|
|
44720
|
+
* @see RFC 1321 — MD5
|
|
44721
|
+
*/
|
|
44722
|
+
/** AES S-Box */
|
|
44723
|
+
const SBOX = new Uint8Array([
|
|
44724
|
+
99,
|
|
44725
|
+
124,
|
|
44726
|
+
119,
|
|
44727
|
+
123,
|
|
44728
|
+
242,
|
|
44729
|
+
107,
|
|
44730
|
+
111,
|
|
44731
|
+
197,
|
|
44732
|
+
48,
|
|
44733
|
+
1,
|
|
44734
|
+
103,
|
|
44735
|
+
43,
|
|
44736
|
+
254,
|
|
44737
|
+
215,
|
|
44738
|
+
171,
|
|
44739
|
+
118,
|
|
44740
|
+
202,
|
|
44741
|
+
130,
|
|
44742
|
+
201,
|
|
44743
|
+
125,
|
|
44744
|
+
250,
|
|
44745
|
+
89,
|
|
44746
|
+
71,
|
|
44747
|
+
240,
|
|
44748
|
+
173,
|
|
44749
|
+
212,
|
|
44750
|
+
162,
|
|
44751
|
+
175,
|
|
44752
|
+
156,
|
|
44753
|
+
164,
|
|
44754
|
+
114,
|
|
44755
|
+
192,
|
|
44756
|
+
183,
|
|
44757
|
+
253,
|
|
44758
|
+
147,
|
|
44759
|
+
38,
|
|
44760
|
+
54,
|
|
44761
|
+
63,
|
|
44762
|
+
247,
|
|
44763
|
+
204,
|
|
44764
|
+
52,
|
|
44765
|
+
165,
|
|
44766
|
+
229,
|
|
44767
|
+
241,
|
|
44768
|
+
113,
|
|
44769
|
+
216,
|
|
44770
|
+
49,
|
|
44771
|
+
21,
|
|
44772
|
+
4,
|
|
44773
|
+
199,
|
|
44774
|
+
35,
|
|
44775
|
+
195,
|
|
44776
|
+
24,
|
|
44777
|
+
150,
|
|
44778
|
+
5,
|
|
44779
|
+
154,
|
|
44780
|
+
7,
|
|
44781
|
+
18,
|
|
44782
|
+
128,
|
|
44783
|
+
226,
|
|
44784
|
+
235,
|
|
44785
|
+
39,
|
|
44786
|
+
178,
|
|
44680
44787
|
117,
|
|
44681
|
-
|
|
44682
|
-
|
|
44683
|
-
|
|
44788
|
+
9,
|
|
44789
|
+
131,
|
|
44790
|
+
44,
|
|
44791
|
+
26,
|
|
44792
|
+
27,
|
|
44793
|
+
110,
|
|
44794
|
+
90,
|
|
44795
|
+
160,
|
|
44796
|
+
82,
|
|
44797
|
+
59,
|
|
44798
|
+
214,
|
|
44799
|
+
179,
|
|
44800
|
+
41,
|
|
44801
|
+
227,
|
|
44802
|
+
47,
|
|
44803
|
+
132,
|
|
44804
|
+
83,
|
|
44805
|
+
209,
|
|
44684
44806
|
0,
|
|
44807
|
+
237,
|
|
44808
|
+
32,
|
|
44809
|
+
252,
|
|
44810
|
+
177,
|
|
44811
|
+
91,
|
|
44812
|
+
106,
|
|
44813
|
+
203,
|
|
44814
|
+
190,
|
|
44815
|
+
57,
|
|
44816
|
+
74,
|
|
44817
|
+
76,
|
|
44818
|
+
88,
|
|
44819
|
+
207,
|
|
44820
|
+
208,
|
|
44821
|
+
239,
|
|
44822
|
+
170,
|
|
44823
|
+
251,
|
|
44824
|
+
67,
|
|
44825
|
+
77,
|
|
44826
|
+
51,
|
|
44827
|
+
133,
|
|
44828
|
+
69,
|
|
44829
|
+
249,
|
|
44830
|
+
2,
|
|
44831
|
+
127,
|
|
44832
|
+
80,
|
|
44833
|
+
60,
|
|
44834
|
+
159,
|
|
44835
|
+
168,
|
|
44836
|
+
81,
|
|
44837
|
+
163,
|
|
44838
|
+
64,
|
|
44839
|
+
143,
|
|
44840
|
+
146,
|
|
44841
|
+
157,
|
|
44842
|
+
56,
|
|
44843
|
+
245,
|
|
44844
|
+
188,
|
|
44845
|
+
182,
|
|
44846
|
+
218,
|
|
44847
|
+
33,
|
|
44848
|
+
16,
|
|
44849
|
+
255,
|
|
44850
|
+
243,
|
|
44851
|
+
210,
|
|
44852
|
+
205,
|
|
44853
|
+
12,
|
|
44854
|
+
19,
|
|
44855
|
+
236,
|
|
44856
|
+
95,
|
|
44857
|
+
151,
|
|
44858
|
+
68,
|
|
44859
|
+
23,
|
|
44860
|
+
196,
|
|
44861
|
+
167,
|
|
44862
|
+
126,
|
|
44863
|
+
61,
|
|
44864
|
+
100,
|
|
44865
|
+
93,
|
|
44866
|
+
25,
|
|
44867
|
+
115,
|
|
44868
|
+
96,
|
|
44869
|
+
129,
|
|
44870
|
+
79,
|
|
44871
|
+
220,
|
|
44872
|
+
34,
|
|
44873
|
+
42,
|
|
44874
|
+
144,
|
|
44875
|
+
136,
|
|
44876
|
+
70,
|
|
44877
|
+
238,
|
|
44878
|
+
184,
|
|
44879
|
+
20,
|
|
44880
|
+
222,
|
|
44881
|
+
94,
|
|
44882
|
+
11,
|
|
44883
|
+
219,
|
|
44884
|
+
224,
|
|
44885
|
+
50,
|
|
44886
|
+
58,
|
|
44887
|
+
10,
|
|
44888
|
+
73,
|
|
44889
|
+
6,
|
|
44890
|
+
36,
|
|
44891
|
+
92,
|
|
44892
|
+
194,
|
|
44893
|
+
211,
|
|
44894
|
+
172,
|
|
44895
|
+
98,
|
|
44896
|
+
145,
|
|
44897
|
+
149,
|
|
44898
|
+
228,
|
|
44899
|
+
121,
|
|
44900
|
+
231,
|
|
44901
|
+
200,
|
|
44902
|
+
55,
|
|
44903
|
+
109,
|
|
44904
|
+
141,
|
|
44905
|
+
213,
|
|
44685
44906
|
78,
|
|
44907
|
+
169,
|
|
44908
|
+
108,
|
|
44686
44909
|
86,
|
|
44687
|
-
|
|
44688
|
-
|
|
44689
|
-
|
|
44910
|
+
244,
|
|
44911
|
+
234,
|
|
44912
|
+
101,
|
|
44913
|
+
122,
|
|
44914
|
+
174,
|
|
44690
44915
|
8,
|
|
44916
|
+
186,
|
|
44917
|
+
120,
|
|
44918
|
+
37,
|
|
44691
44919
|
46,
|
|
44692
|
-
|
|
44693
|
-
|
|
44694
|
-
|
|
44695
|
-
|
|
44696
|
-
|
|
44920
|
+
28,
|
|
44921
|
+
166,
|
|
44922
|
+
180,
|
|
44923
|
+
198,
|
|
44924
|
+
232,
|
|
44925
|
+
221,
|
|
44926
|
+
116,
|
|
44927
|
+
31,
|
|
44928
|
+
75,
|
|
44929
|
+
189,
|
|
44930
|
+
139,
|
|
44931
|
+
138,
|
|
44932
|
+
112,
|
|
44697
44933
|
62,
|
|
44698
|
-
|
|
44699
|
-
|
|
44700
|
-
|
|
44701
|
-
|
|
44702
|
-
|
|
44703
|
-
|
|
44704
|
-
|
|
44934
|
+
181,
|
|
44935
|
+
102,
|
|
44936
|
+
72,
|
|
44937
|
+
3,
|
|
44938
|
+
246,
|
|
44939
|
+
14,
|
|
44940
|
+
97,
|
|
44941
|
+
53,
|
|
44942
|
+
87,
|
|
44943
|
+
185,
|
|
44944
|
+
134,
|
|
44945
|
+
193,
|
|
44946
|
+
29,
|
|
44947
|
+
158,
|
|
44948
|
+
225,
|
|
44949
|
+
248,
|
|
44950
|
+
152,
|
|
44951
|
+
17,
|
|
44705
44952
|
105,
|
|
44706
|
-
|
|
44953
|
+
217,
|
|
44954
|
+
142,
|
|
44955
|
+
148,
|
|
44956
|
+
155,
|
|
44957
|
+
30,
|
|
44958
|
+
135,
|
|
44959
|
+
233,
|
|
44960
|
+
206,
|
|
44961
|
+
85,
|
|
44962
|
+
40,
|
|
44963
|
+
223,
|
|
44964
|
+
140,
|
|
44965
|
+
161,
|
|
44966
|
+
137,
|
|
44967
|
+
13,
|
|
44968
|
+
191,
|
|
44969
|
+
230,
|
|
44970
|
+
66,
|
|
44971
|
+
104,
|
|
44972
|
+
65,
|
|
44973
|
+
153,
|
|
44974
|
+
45,
|
|
44975
|
+
15,
|
|
44976
|
+
176,
|
|
44977
|
+
84,
|
|
44978
|
+
187,
|
|
44979
|
+
22
|
|
44707
44980
|
]);
|
|
44981
|
+
/** AES round constants */
|
|
44982
|
+
const RCON = [
|
|
44983
|
+
1,
|
|
44984
|
+
2,
|
|
44985
|
+
4,
|
|
44986
|
+
8,
|
|
44987
|
+
16,
|
|
44988
|
+
32,
|
|
44989
|
+
64,
|
|
44990
|
+
128,
|
|
44991
|
+
27,
|
|
44992
|
+
54
|
|
44993
|
+
];
|
|
44994
|
+
/** GF(2^8) multiplication by 2 */
|
|
44995
|
+
function gf2(a) {
|
|
44996
|
+
return a < 128 ? a << 1 : a << 1 ^ 283;
|
|
44997
|
+
}
|
|
44998
|
+
/**
|
|
44999
|
+
* AES key expansion. Supports AES-128 (16-byte key) and AES-256 (32-byte key).
|
|
45000
|
+
*/
|
|
45001
|
+
function aesKeyExpansion(key) {
|
|
45002
|
+
const nk = key.length / 4;
|
|
45003
|
+
const nr = nk + 6;
|
|
45004
|
+
const w = [];
|
|
45005
|
+
for (let i = 0; i < nk; i++) w.push(new Uint8Array([
|
|
45006
|
+
key[4 * i],
|
|
45007
|
+
key[4 * i + 1],
|
|
45008
|
+
key[4 * i + 2],
|
|
45009
|
+
key[4 * i + 3]
|
|
45010
|
+
]));
|
|
45011
|
+
for (let i = nk; i < 4 * (nr + 1); i++) {
|
|
45012
|
+
const temp = new Uint8Array(w[i - 1]);
|
|
45013
|
+
if (i % nk === 0) {
|
|
45014
|
+
const t0 = temp[0];
|
|
45015
|
+
temp[0] = SBOX[temp[1]] ^ RCON[i / nk - 1];
|
|
45016
|
+
temp[1] = SBOX[temp[2]];
|
|
45017
|
+
temp[2] = SBOX[temp[3]];
|
|
45018
|
+
temp[3] = SBOX[t0];
|
|
45019
|
+
} else if (nk > 6 && i % nk === 4) {
|
|
45020
|
+
temp[0] = SBOX[temp[0]];
|
|
45021
|
+
temp[1] = SBOX[temp[1]];
|
|
45022
|
+
temp[2] = SBOX[temp[2]];
|
|
45023
|
+
temp[3] = SBOX[temp[3]];
|
|
45024
|
+
}
|
|
45025
|
+
const word = new Uint8Array(4);
|
|
45026
|
+
for (let j = 0; j < 4; j++) word[j] = w[i - nk][j] ^ temp[j];
|
|
45027
|
+
w.push(word);
|
|
45028
|
+
}
|
|
45029
|
+
return w;
|
|
45030
|
+
}
|
|
45031
|
+
/**
|
|
45032
|
+
* Encrypt a single AES block (16 bytes).
|
|
45033
|
+
* State layout: column-major per FIPS 197 §3.4.
|
|
45034
|
+
*/
|
|
45035
|
+
function aesEncryptBlock(block, roundKeys) {
|
|
45036
|
+
const nr = roundKeys.length / 4 - 1;
|
|
45037
|
+
const state = new Uint8Array(16);
|
|
45038
|
+
state.set(block);
|
|
45039
|
+
for (let c = 0; c < 4; c++) for (let r = 0; r < 4; r++) state[4 * c + r] ^= roundKeys[c][r];
|
|
45040
|
+
for (let round = 1; round < nr; round++) {
|
|
45041
|
+
for (let i = 0; i < 16; i++) state[i] = SBOX[state[i]];
|
|
45042
|
+
let tmp;
|
|
45043
|
+
tmp = state[1];
|
|
45044
|
+
state[1] = state[5];
|
|
45045
|
+
state[5] = state[9];
|
|
45046
|
+
state[9] = state[13];
|
|
45047
|
+
state[13] = tmp;
|
|
45048
|
+
tmp = state[2];
|
|
45049
|
+
state[2] = state[10];
|
|
45050
|
+
state[10] = tmp;
|
|
45051
|
+
tmp = state[6];
|
|
45052
|
+
state[6] = state[14];
|
|
45053
|
+
state[14] = tmp;
|
|
45054
|
+
tmp = state[15];
|
|
45055
|
+
state[15] = state[11];
|
|
45056
|
+
state[11] = state[7];
|
|
45057
|
+
state[7] = state[3];
|
|
45058
|
+
state[3] = tmp;
|
|
45059
|
+
for (let c = 0; c < 4; c++) {
|
|
45060
|
+
const s0 = state[4 * c];
|
|
45061
|
+
const s1 = state[4 * c + 1];
|
|
45062
|
+
const s2 = state[4 * c + 2];
|
|
45063
|
+
const s3 = state[4 * c + 3];
|
|
45064
|
+
state[4 * c] = gf2(s0) ^ gf2(s1) ^ s1 ^ s2 ^ s3;
|
|
45065
|
+
state[4 * c + 1] = s0 ^ gf2(s1) ^ gf2(s2) ^ s2 ^ s3;
|
|
45066
|
+
state[4 * c + 2] = s0 ^ s1 ^ gf2(s2) ^ gf2(s3) ^ s3;
|
|
45067
|
+
state[4 * c + 3] = gf2(s0) ^ s0 ^ s1 ^ s2 ^ gf2(s3);
|
|
45068
|
+
}
|
|
45069
|
+
const keyOffset = round * 4;
|
|
45070
|
+
for (let c = 0; c < 4; c++) for (let r = 0; r < 4; r++) state[4 * c + r] ^= roundKeys[keyOffset + c][r];
|
|
45071
|
+
}
|
|
45072
|
+
for (let i = 0; i < 16; i++) state[i] = SBOX[state[i]];
|
|
45073
|
+
let tmp;
|
|
45074
|
+
tmp = state[1];
|
|
45075
|
+
state[1] = state[5];
|
|
45076
|
+
state[5] = state[9];
|
|
45077
|
+
state[9] = state[13];
|
|
45078
|
+
state[13] = tmp;
|
|
45079
|
+
tmp = state[2];
|
|
45080
|
+
state[2] = state[10];
|
|
45081
|
+
state[10] = tmp;
|
|
45082
|
+
tmp = state[6];
|
|
45083
|
+
state[6] = state[14];
|
|
45084
|
+
state[14] = tmp;
|
|
45085
|
+
tmp = state[15];
|
|
45086
|
+
state[15] = state[11];
|
|
45087
|
+
state[11] = state[7];
|
|
45088
|
+
state[7] = state[3];
|
|
45089
|
+
state[3] = tmp;
|
|
45090
|
+
for (let c = 0; c < 4; c++) for (let r = 0; r < 4; r++) state[4 * c + r] ^= roundKeys[nr * 4 + c][r];
|
|
45091
|
+
return state;
|
|
45092
|
+
}
|
|
44708
45093
|
/**
|
|
44709
|
-
*
|
|
44710
|
-
|
|
44711
|
-
|
|
44712
|
-
|
|
44713
|
-
const
|
|
44714
|
-
const
|
|
44715
|
-
|
|
44716
|
-
|
|
44717
|
-
const
|
|
44718
|
-
|
|
44719
|
-
|
|
44720
|
-
|
|
44721
|
-
|
|
44722
|
-
|
|
44723
|
-
|
|
44724
|
-
|
|
45094
|
+
* AES-CBC encryption with PKCS#7 padding.
|
|
45095
|
+
* Supports AES-128 (16-byte key) and AES-256 (32-byte key).
|
|
45096
|
+
*/
|
|
45097
|
+
function aesCbcEncrypt(plaintext, key, iv) {
|
|
45098
|
+
const padLen = 16 - plaintext.length % 16;
|
|
45099
|
+
const padded = new Uint8Array(plaintext.length + padLen);
|
|
45100
|
+
padded.set(plaintext);
|
|
45101
|
+
for (let i = plaintext.length; i < padded.length; i++) padded[i] = padLen;
|
|
45102
|
+
const roundKeys = aesKeyExpansion(key);
|
|
45103
|
+
const numBlocks = padded.length / 16;
|
|
45104
|
+
const output = new Uint8Array(padded.length);
|
|
45105
|
+
let prevBlock = iv;
|
|
45106
|
+
for (let b = 0; b < numBlocks; b++) {
|
|
45107
|
+
const block = new Uint8Array(16);
|
|
45108
|
+
for (let i = 0; i < 16; i++) block[i] = padded[b * 16 + i] ^ prevBlock[i];
|
|
45109
|
+
const encrypted = aesEncryptBlock(block, roundKeys);
|
|
45110
|
+
output.set(encrypted, b * 16);
|
|
45111
|
+
prevBlock = encrypted;
|
|
45112
|
+
}
|
|
45113
|
+
return output;
|
|
44725
45114
|
}
|
|
44726
45115
|
/**
|
|
44727
|
-
*
|
|
44728
|
-
*
|
|
45116
|
+
* AES-CBC encryption WITHOUT PKCS#7 padding.
|
|
45117
|
+
* Used when the plaintext is already block-aligned (e.g., encrypting
|
|
45118
|
+
* the 32-byte file encryption key in V=5).
|
|
45119
|
+
*
|
|
45120
|
+
* @throws if plaintext length is not a multiple of 16.
|
|
44729
45121
|
*/
|
|
44730
|
-
function
|
|
44731
|
-
|
|
44732
|
-
|
|
44733
|
-
|
|
44734
|
-
|
|
44735
|
-
|
|
44736
|
-
|
|
44737
|
-
|
|
44738
|
-
|
|
44739
|
-
|
|
44740
|
-
|
|
45122
|
+
function aesCbcEncryptRaw(plaintext, key, iv) {
|
|
45123
|
+
if (plaintext.length % 16 !== 0) throw new Error("aesCbcEncryptRaw: plaintext length must be a multiple of 16");
|
|
45124
|
+
const roundKeys = aesKeyExpansion(key);
|
|
45125
|
+
const numBlocks = plaintext.length / 16;
|
|
45126
|
+
const output = new Uint8Array(plaintext.length);
|
|
45127
|
+
let prevBlock = iv;
|
|
45128
|
+
for (let b = 0; b < numBlocks; b++) {
|
|
45129
|
+
const block = new Uint8Array(16);
|
|
45130
|
+
for (let i = 0; i < 16; i++) block[i] = plaintext[b * 16 + i] ^ prevBlock[i];
|
|
45131
|
+
const encrypted = aesEncryptBlock(block, roundKeys);
|
|
45132
|
+
output.set(encrypted, b * 16);
|
|
45133
|
+
prevBlock = encrypted;
|
|
45134
|
+
}
|
|
45135
|
+
return output;
|
|
44741
45136
|
}
|
|
44742
45137
|
/**
|
|
44743
|
-
*
|
|
45138
|
+
* AES-ECB encryption of a single 16-byte block (no padding, no IV).
|
|
45139
|
+
* Used for the /Perms value in V=5 encryption.
|
|
44744
45140
|
*/
|
|
44745
|
-
function
|
|
44746
|
-
|
|
44747
|
-
|
|
44748
|
-
|
|
44749
|
-
|
|
44750
|
-
|
|
44751
|
-
|
|
44752
|
-
|
|
44753
|
-
|
|
44754
|
-
|
|
44755
|
-
|
|
44756
|
-
|
|
44757
|
-
|
|
44758
|
-
|
|
44759
|
-
|
|
44760
|
-
|
|
44761
|
-
|
|
44762
|
-
|
|
45141
|
+
function aesEcbEncrypt(block, key) {
|
|
45142
|
+
return aesEncryptBlock(block, aesKeyExpansion(key));
|
|
45143
|
+
}
|
|
45144
|
+
/** SHA-256 initial hash values */
|
|
45145
|
+
const SHA256_H = new Uint32Array([
|
|
45146
|
+
1779033703,
|
|
45147
|
+
3144134277,
|
|
45148
|
+
1013904242,
|
|
45149
|
+
2773480762,
|
|
45150
|
+
1359893119,
|
|
45151
|
+
2600822924,
|
|
45152
|
+
528734635,
|
|
45153
|
+
1541459225
|
|
45154
|
+
]);
|
|
45155
|
+
/** SHA-256 round constants */
|
|
45156
|
+
const SHA256_K = new Uint32Array([
|
|
45157
|
+
1116352408,
|
|
45158
|
+
1899447441,
|
|
45159
|
+
3049323471,
|
|
45160
|
+
3921009573,
|
|
45161
|
+
961987163,
|
|
45162
|
+
1508970993,
|
|
45163
|
+
2453635748,
|
|
45164
|
+
2870763221,
|
|
45165
|
+
3624381080,
|
|
45166
|
+
310598401,
|
|
45167
|
+
607225278,
|
|
45168
|
+
1426881987,
|
|
45169
|
+
1925078388,
|
|
45170
|
+
2162078206,
|
|
45171
|
+
2614888103,
|
|
45172
|
+
3248222580,
|
|
45173
|
+
3835390401,
|
|
45174
|
+
4022224774,
|
|
45175
|
+
264347078,
|
|
45176
|
+
604807628,
|
|
45177
|
+
770255983,
|
|
45178
|
+
1249150122,
|
|
45179
|
+
1555081692,
|
|
45180
|
+
1996064986,
|
|
45181
|
+
2554220882,
|
|
45182
|
+
2821834349,
|
|
45183
|
+
2952996808,
|
|
45184
|
+
3210313671,
|
|
45185
|
+
3336571891,
|
|
45186
|
+
3584528711,
|
|
45187
|
+
113926993,
|
|
45188
|
+
338241895,
|
|
45189
|
+
666307205,
|
|
45190
|
+
773529912,
|
|
45191
|
+
1294757372,
|
|
45192
|
+
1396182291,
|
|
45193
|
+
1695183700,
|
|
45194
|
+
1986661051,
|
|
45195
|
+
2177026350,
|
|
45196
|
+
2456956037,
|
|
45197
|
+
2730485921,
|
|
45198
|
+
2820302411,
|
|
45199
|
+
3259730800,
|
|
45200
|
+
3345764771,
|
|
45201
|
+
3516065817,
|
|
45202
|
+
3600352804,
|
|
45203
|
+
4094571909,
|
|
45204
|
+
275423344,
|
|
45205
|
+
430227734,
|
|
45206
|
+
506948616,
|
|
45207
|
+
659060556,
|
|
45208
|
+
883997877,
|
|
45209
|
+
958139571,
|
|
45210
|
+
1322822218,
|
|
45211
|
+
1537002063,
|
|
45212
|
+
1747873779,
|
|
45213
|
+
1955562222,
|
|
45214
|
+
2024104815,
|
|
45215
|
+
2227730452,
|
|
45216
|
+
2361852424,
|
|
45217
|
+
2428436474,
|
|
45218
|
+
2756734187,
|
|
45219
|
+
3204031479,
|
|
45220
|
+
3329325298
|
|
45221
|
+
]);
|
|
45222
|
+
function rotr32(x, n) {
|
|
45223
|
+
return (x >>> n | x << 32 - n) >>> 0;
|
|
44763
45224
|
}
|
|
44764
45225
|
/**
|
|
44765
|
-
*
|
|
44766
|
-
*
|
|
45226
|
+
* SHA-256 hash function.
|
|
45227
|
+
* @returns 32-byte digest
|
|
44767
45228
|
*/
|
|
44768
|
-
function
|
|
45229
|
+
function sha256(input) {
|
|
44769
45230
|
const msgLen = input.length;
|
|
44770
|
-
const
|
|
44771
|
-
const
|
|
44772
|
-
const padded = new Uint8Array(msgLen + padLen + 8);
|
|
45231
|
+
const paddedLen = Math.ceil((msgLen + 9) / 64) * 64;
|
|
45232
|
+
const padded = new Uint8Array(paddedLen);
|
|
44773
45233
|
padded.set(input);
|
|
44774
45234
|
padded[msgLen] = 128;
|
|
44775
|
-
const
|
|
44776
|
-
view
|
|
44777
|
-
view.setUint32(
|
|
44778
|
-
|
|
44779
|
-
let
|
|
44780
|
-
let
|
|
44781
|
-
let
|
|
44782
|
-
|
|
44783
|
-
|
|
44784
|
-
|
|
44785
|
-
|
|
44786
|
-
|
|
44787
|
-
|
|
44788
|
-
|
|
44789
|
-
for (let
|
|
44790
|
-
|
|
44791
|
-
|
|
44792
|
-
|
|
44793
|
-
|
|
44794
|
-
|
|
44795
|
-
|
|
44796
|
-
|
|
44797
|
-
|
|
44798
|
-
|
|
44799
|
-
|
|
44800
|
-
|
|
44801
|
-
|
|
44802
|
-
|
|
44803
|
-
|
|
44804
|
-
|
|
44805
|
-
|
|
44806
|
-
|
|
44807
|
-
|
|
44808
|
-
|
|
44809
|
-
|
|
44810
|
-
|
|
44811
|
-
|
|
44812
|
-
|
|
44813
|
-
|
|
44814
|
-
|
|
44815
|
-
|
|
44816
|
-
|
|
44817
|
-
|
|
44818
|
-
|
|
44819
|
-
|
|
44820
|
-
|
|
44821
|
-
|
|
44822
|
-
|
|
44823
|
-
|
|
44824
|
-
|
|
44825
|
-
|
|
44826
|
-
|
|
44827
|
-
|
|
44828
|
-
|
|
44829
|
-
|
|
44830
|
-
|
|
44831
|
-
|
|
44832
|
-
|
|
44833
|
-
|
|
44834
|
-
|
|
44835
|
-
|
|
44836
|
-
|
|
44837
|
-
|
|
44838
|
-
|
|
44839
|
-
22,
|
|
44840
|
-
7,
|
|
44841
|
-
12,
|
|
44842
|
-
17,
|
|
44843
|
-
22,
|
|
44844
|
-
5,
|
|
44845
|
-
9,
|
|
44846
|
-
14,
|
|
44847
|
-
20,
|
|
44848
|
-
5,
|
|
44849
|
-
9,
|
|
44850
|
-
14,
|
|
44851
|
-
20,
|
|
44852
|
-
5,
|
|
44853
|
-
9,
|
|
44854
|
-
14,
|
|
44855
|
-
20,
|
|
44856
|
-
5,
|
|
44857
|
-
9,
|
|
44858
|
-
14,
|
|
44859
|
-
20,
|
|
44860
|
-
4,
|
|
44861
|
-
11,
|
|
44862
|
-
16,
|
|
44863
|
-
23,
|
|
44864
|
-
4,
|
|
44865
|
-
11,
|
|
44866
|
-
16,
|
|
44867
|
-
23,
|
|
44868
|
-
4,
|
|
44869
|
-
11,
|
|
44870
|
-
16,
|
|
44871
|
-
23,
|
|
44872
|
-
4,
|
|
44873
|
-
11,
|
|
44874
|
-
16,
|
|
44875
|
-
23,
|
|
44876
|
-
6,
|
|
44877
|
-
10,
|
|
44878
|
-
15,
|
|
44879
|
-
21,
|
|
44880
|
-
6,
|
|
44881
|
-
10,
|
|
44882
|
-
15,
|
|
44883
|
-
21,
|
|
44884
|
-
6,
|
|
44885
|
-
10,
|
|
44886
|
-
15,
|
|
44887
|
-
21,
|
|
44888
|
-
6,
|
|
44889
|
-
10,
|
|
44890
|
-
15,
|
|
44891
|
-
21
|
|
44892
|
-
];
|
|
44893
|
-
const K = new Uint32Array([
|
|
45235
|
+
const bitLen = msgLen * 8;
|
|
45236
|
+
const view = new DataView(padded.buffer, padded.byteOffset, padded.byteLength);
|
|
45237
|
+
view.setUint32(paddedLen - 8, 0, false);
|
|
45238
|
+
view.setUint32(paddedLen - 4, bitLen, false);
|
|
45239
|
+
let h0 = SHA256_H[0];
|
|
45240
|
+
let h1 = SHA256_H[1];
|
|
45241
|
+
let h2 = SHA256_H[2];
|
|
45242
|
+
let h3 = SHA256_H[3];
|
|
45243
|
+
let h4 = SHA256_H[4];
|
|
45244
|
+
let h5 = SHA256_H[5];
|
|
45245
|
+
let h6 = SHA256_H[6];
|
|
45246
|
+
let h7 = SHA256_H[7];
|
|
45247
|
+
const w = new Uint32Array(64);
|
|
45248
|
+
for (let offset = 0; offset < paddedLen; offset += 64) {
|
|
45249
|
+
for (let i = 0; i < 16; i++) w[i] = view.getUint32(offset + i * 4, false);
|
|
45250
|
+
for (let i = 16; i < 64; i++) {
|
|
45251
|
+
const s0 = rotr32(w[i - 15], 7) ^ rotr32(w[i - 15], 18) ^ w[i - 15] >>> 3;
|
|
45252
|
+
const s1 = rotr32(w[i - 2], 17) ^ rotr32(w[i - 2], 19) ^ w[i - 2] >>> 10;
|
|
45253
|
+
w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
|
|
45254
|
+
}
|
|
45255
|
+
let a = h0;
|
|
45256
|
+
let b = h1;
|
|
45257
|
+
let c = h2;
|
|
45258
|
+
let d = h3;
|
|
45259
|
+
let e = h4;
|
|
45260
|
+
let f = h5;
|
|
45261
|
+
let g = h6;
|
|
45262
|
+
let h = h7;
|
|
45263
|
+
for (let i = 0; i < 64; i++) {
|
|
45264
|
+
const S1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);
|
|
45265
|
+
const ch = e & f ^ ~e & g;
|
|
45266
|
+
const temp1 = h + S1 + ch + SHA256_K[i] + w[i] >>> 0;
|
|
45267
|
+
const temp2 = (rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22)) + (a & b ^ a & c ^ b & c) >>> 0;
|
|
45268
|
+
h = g;
|
|
45269
|
+
g = f;
|
|
45270
|
+
f = e;
|
|
45271
|
+
e = d + temp1 >>> 0;
|
|
45272
|
+
d = c;
|
|
45273
|
+
c = b;
|
|
45274
|
+
b = a;
|
|
45275
|
+
a = temp1 + temp2 >>> 0;
|
|
45276
|
+
}
|
|
45277
|
+
h0 = h0 + a >>> 0;
|
|
45278
|
+
h1 = h1 + b >>> 0;
|
|
45279
|
+
h2 = h2 + c >>> 0;
|
|
45280
|
+
h3 = h3 + d >>> 0;
|
|
45281
|
+
h4 = h4 + e >>> 0;
|
|
45282
|
+
h5 = h5 + f >>> 0;
|
|
45283
|
+
h6 = h6 + g >>> 0;
|
|
45284
|
+
h7 = h7 + h >>> 0;
|
|
45285
|
+
}
|
|
45286
|
+
const result = new Uint8Array(32);
|
|
45287
|
+
const resultView = new DataView(result.buffer);
|
|
45288
|
+
resultView.setUint32(0, h0, false);
|
|
45289
|
+
resultView.setUint32(4, h1, false);
|
|
45290
|
+
resultView.setUint32(8, h2, false);
|
|
45291
|
+
resultView.setUint32(12, h3, false);
|
|
45292
|
+
resultView.setUint32(16, h4, false);
|
|
45293
|
+
resultView.setUint32(20, h5, false);
|
|
45294
|
+
resultView.setUint32(24, h6, false);
|
|
45295
|
+
resultView.setUint32(28, h7, false);
|
|
45296
|
+
return result;
|
|
45297
|
+
}
|
|
45298
|
+
new Uint32Array([
|
|
44894
45299
|
3614090360,
|
|
44895
45300
|
3905402710,
|
|
44896
45301
|
606105819,
|
|
@@ -44957,64 +45362,104 @@ onmessage = async (ev) => {
|
|
|
44957
45362
|
3951481745
|
|
44958
45363
|
]);
|
|
44959
45364
|
/**
|
|
44960
|
-
*
|
|
45365
|
+
* Generate pseudo-random bytes.
|
|
45366
|
+
* Uses Math.random — adequate for PDF IVs but not cryptographically secure.
|
|
44961
45367
|
*/
|
|
44962
|
-
function
|
|
44963
|
-
const
|
|
44964
|
-
|
|
44965
|
-
|
|
44966
|
-
result.set(bytes.subarray(0, len));
|
|
44967
|
-
result.set(PASSWORD_PADDING.subarray(0, 32 - len), len);
|
|
44968
|
-
return result;
|
|
45368
|
+
function randomBytes(length) {
|
|
45369
|
+
const bytes = new Uint8Array(length);
|
|
45370
|
+
for (let i = 0; i < length; i++) bytes[i] = Math.random() * 256 | 0;
|
|
45371
|
+
return bytes;
|
|
44969
45372
|
}
|
|
44970
45373
|
/**
|
|
44971
|
-
*
|
|
44972
|
-
* Algorithm 3 from PDF spec §3.5.2.
|
|
45374
|
+
* Concatenate multiple Uint8Arrays.
|
|
44973
45375
|
*/
|
|
44974
|
-
function
|
|
44975
|
-
let
|
|
44976
|
-
for (
|
|
44977
|
-
const
|
|
44978
|
-
let
|
|
44979
|
-
for (
|
|
44980
|
-
|
|
44981
|
-
|
|
44982
|
-
result = rc4(modKey, result);
|
|
45376
|
+
function concatArrays(...arrays) {
|
|
45377
|
+
let totalLen = 0;
|
|
45378
|
+
for (const arr of arrays) totalLen += arr.length;
|
|
45379
|
+
const result = new Uint8Array(totalLen);
|
|
45380
|
+
let offset = 0;
|
|
45381
|
+
for (const arr of arrays) {
|
|
45382
|
+
result.set(arr, offset);
|
|
45383
|
+
offset += arr.length;
|
|
44983
45384
|
}
|
|
44984
45385
|
return result;
|
|
44985
45386
|
}
|
|
45387
|
+
//#endregion
|
|
45388
|
+
//#region src/modules/pdf/core/encryption.ts
|
|
45389
|
+
/**
|
|
45390
|
+
* PDF encryption support (Standard Security Handler, V=5, R=5).
|
|
45391
|
+
*
|
|
45392
|
+
* Implements AES-256 encryption compatible with PDF 2.0 (ISO 32000-2:2020).
|
|
45393
|
+
* Supports:
|
|
45394
|
+
* - User password (required to open the document)
|
|
45395
|
+
* - Owner password (grants full access)
|
|
45396
|
+
* - Permission flags (print, copy, modify, etc.)
|
|
45397
|
+
*
|
|
45398
|
+
* The file encryption key (FEK) is a random 256-bit key.
|
|
45399
|
+
* All streams and strings are encrypted using AES-256-CBC with a random
|
|
45400
|
+
* 16-byte IV prepended to each encrypted value.
|
|
45401
|
+
*
|
|
45402
|
+
* @see ISO 32000-2:2020, §7.6 — Encryption
|
|
45403
|
+
*/
|
|
44986
45404
|
/**
|
|
44987
|
-
*
|
|
44988
|
-
* Algorithm 2 from PDF spec §3.5.2.
|
|
45405
|
+
* Initialize encryption state for AES-256 (V=5, R=5).
|
|
44989
45406
|
*/
|
|
44990
|
-
function
|
|
44991
|
-
const
|
|
44992
|
-
const
|
|
44993
|
-
|
|
44994
|
-
|
|
44995
|
-
|
|
44996
|
-
|
|
44997
|
-
|
|
44998
|
-
|
|
44999
|
-
|
|
45407
|
+
function initEncryption(options) {
|
|
45408
|
+
const userPwd = truncatePassword(options.userPassword ?? "");
|
|
45409
|
+
const ownerPwd = truncatePassword(options.ownerPassword);
|
|
45410
|
+
const perms = computePermissions(options.permissions);
|
|
45411
|
+
const encryptionKey = randomBytes(32);
|
|
45412
|
+
const uValidationSalt = randomBytes(8);
|
|
45413
|
+
const uKeySalt = randomBytes(8);
|
|
45414
|
+
const oValidationSalt = randomBytes(8);
|
|
45415
|
+
const oKeySalt = randomBytes(8);
|
|
45416
|
+
const uValue = concatArrays(sha256(concatArrays(userPwd, uValidationSalt)), uValidationSalt, uKeySalt);
|
|
45417
|
+
const ueKey = sha256(concatArrays(userPwd, uKeySalt));
|
|
45418
|
+
const zeroIv = new Uint8Array(16);
|
|
45419
|
+
const ueValue = aesCbcEncryptRaw(encryptionKey, ueKey, zeroIv);
|
|
45420
|
+
const oValue = concatArrays(sha256(concatArrays(ownerPwd, oValidationSalt, uValue)), oValidationSalt, oKeySalt);
|
|
45421
|
+
const oeValue = aesCbcEncryptRaw(encryptionKey, sha256(concatArrays(ownerPwd, oKeySalt, uValue)), zeroIv);
|
|
45422
|
+
const permsBlock = new Uint8Array(16);
|
|
45423
|
+
new DataView(permsBlock.buffer).setInt32(0, perms, true);
|
|
45424
|
+
permsBlock[4] = 255;
|
|
45425
|
+
permsBlock[5] = 255;
|
|
45426
|
+
permsBlock[6] = 255;
|
|
45427
|
+
permsBlock[7] = 255;
|
|
45428
|
+
permsBlock[8] = 84;
|
|
45429
|
+
permsBlock[9] = 97;
|
|
45430
|
+
permsBlock[10] = 100;
|
|
45431
|
+
permsBlock[11] = 98;
|
|
45432
|
+
return {
|
|
45433
|
+
encryptionKey,
|
|
45434
|
+
oValue,
|
|
45435
|
+
uValue,
|
|
45436
|
+
oeValue,
|
|
45437
|
+
ueValue,
|
|
45438
|
+
permsValue: aesEcbEncrypt(permsBlock, encryptionKey),
|
|
45439
|
+
permissions: perms,
|
|
45440
|
+
fileId: randomBytes(16)
|
|
45441
|
+
};
|
|
45000
45442
|
}
|
|
45001
45443
|
/**
|
|
45002
|
-
*
|
|
45003
|
-
*
|
|
45444
|
+
* Encrypt data for a PDF object using AES-256-CBC.
|
|
45445
|
+
*
|
|
45446
|
+
* For V=5/R=5, the file encryption key is used directly (no per-object key derivation).
|
|
45447
|
+
* A random 16-byte IV is prepended to the ciphertext.
|
|
45004
45448
|
*/
|
|
45005
|
-
function
|
|
45006
|
-
const
|
|
45007
|
-
|
|
45008
|
-
|
|
45009
|
-
|
|
45010
|
-
|
|
45011
|
-
|
|
45012
|
-
|
|
45013
|
-
|
|
45014
|
-
|
|
45015
|
-
|
|
45016
|
-
|
|
45017
|
-
|
|
45449
|
+
function encryptData(data, _objectNumber, _generation, encryptionKey) {
|
|
45450
|
+
const iv = randomBytes(16);
|
|
45451
|
+
const ciphertext = aesCbcEncrypt(data, encryptionKey, iv);
|
|
45452
|
+
const result = new Uint8Array(16 + ciphertext.length);
|
|
45453
|
+
result.set(iv);
|
|
45454
|
+
result.set(ciphertext, 16);
|
|
45455
|
+
return result;
|
|
45456
|
+
}
|
|
45457
|
+
/**
|
|
45458
|
+
* Truncate password to 127 bytes (UTF-8) per PDF 2.0 spec.
|
|
45459
|
+
*/
|
|
45460
|
+
function truncatePassword(password) {
|
|
45461
|
+
const bytes = new TextEncoder().encode(password);
|
|
45462
|
+
return bytes.length > 127 ? bytes.subarray(0, 127) : bytes;
|
|
45018
45463
|
}
|
|
45019
45464
|
/**
|
|
45020
45465
|
* Compute the permissions integer (P value) from permission flags.
|
|
@@ -45031,33 +45476,24 @@ onmessage = async (ev) => {
|
|
|
45031
45476
|
if (perms?.printHighQuality) p |= 2048;
|
|
45032
45477
|
return p | 0;
|
|
45033
45478
|
}
|
|
45034
|
-
/**
|
|
45035
|
-
* Generate a random file identifier (16 bytes).
|
|
45036
|
-
*/
|
|
45037
|
-
function generateFileId() {
|
|
45038
|
-
const seed = new Uint8Array(16);
|
|
45039
|
-
const now = Date.now();
|
|
45040
|
-
const view = new DataView(seed.buffer);
|
|
45041
|
-
view.setFloat64(0, now, true);
|
|
45042
|
-
view.setFloat64(8, Math.random() * 0x38d7ea4c68000, true);
|
|
45043
|
-
return md5(seed);
|
|
45044
|
-
}
|
|
45045
45479
|
//#endregion
|
|
45046
45480
|
//#region src/modules/pdf/core/pdf-writer.ts
|
|
45047
45481
|
/**
|
|
45048
45482
|
* PDF file writer.
|
|
45049
45483
|
*
|
|
45050
|
-
* Assembles a complete PDF document from indirect objects.
|
|
45484
|
+
* Assembles a complete PDF 2.0 document from indirect objects.
|
|
45051
45485
|
* Handles the four sections of a PDF file:
|
|
45052
|
-
* 1. Header (%PDF-
|
|
45486
|
+
* 1. Header (%PDF-2.0)
|
|
45053
45487
|
* 2. Body (indirect objects)
|
|
45054
45488
|
* 3. Cross-reference table
|
|
45055
45489
|
* 4. Trailer (with document catalog reference)
|
|
45056
45490
|
*
|
|
45057
|
-
*
|
|
45491
|
+
* Encryption uses AES-256 (V=5, R=5) per ISO 32000-2:2020.
|
|
45492
|
+
*
|
|
45493
|
+
* @see ISO 32000-2:2020, Chapter 7.5 — File Structure
|
|
45058
45494
|
*/
|
|
45059
45495
|
/**
|
|
45060
|
-
* Constructs a valid PDF
|
|
45496
|
+
* Constructs a valid PDF 2.0 file from a set of indirect objects.
|
|
45061
45497
|
*
|
|
45062
45498
|
* Usage:
|
|
45063
45499
|
* 1. Allocate object numbers with allocObject()
|
|
@@ -45170,7 +45606,7 @@ onmessage = async (ev) => {
|
|
|
45170
45606
|
const encoder = new TextEncoder();
|
|
45171
45607
|
const chunks = [];
|
|
45172
45608
|
let byteOffset = 0;
|
|
45173
|
-
const headerStrBytes = encoder.encode("%PDF-
|
|
45609
|
+
const headerStrBytes = encoder.encode("%PDF-2.0\n");
|
|
45174
45610
|
chunks.push(headerStrBytes);
|
|
45175
45611
|
byteOffset += headerStrBytes.length;
|
|
45176
45612
|
const binaryComment = new Uint8Array([
|
|
@@ -45219,7 +45655,7 @@ onmessage = async (ev) => {
|
|
|
45219
45655
|
byteOffset += objFooter.length;
|
|
45220
45656
|
}
|
|
45221
45657
|
if (this.encryption) {
|
|
45222
|
-
const encContent = new PdfDict().set("Filter", "/Standard").set("V", "
|
|
45658
|
+
const encContent = new PdfDict().set("Filter", "/Standard").set("V", "5").set("R", "5").set("Length", "256").set("P", String(this.encryption.permissions)).set("O", pdfHexString(this.encryption.oValue)).set("U", pdfHexString(this.encryption.uValue)).set("OE", pdfHexString(this.encryption.oeValue)).set("UE", pdfHexString(this.encryption.ueValue)).set("Perms", pdfHexString(this.encryption.permsValue)).set("EncryptMetadata", "true").set("CF", "<< /StdCF << /Type /CryptFilter /CFM /AESV3 /AuthEvent /DocOpen /Length 32 >> >>").set("StmF", "/StdCF").set("StrF", "/StdCF").toString();
|
|
45223
45659
|
const encObj = {
|
|
45224
45660
|
objectNumber: encryptObjNum,
|
|
45225
45661
|
offset: byteOffset,
|