pdf-lite 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/.commitlintrc.cjs +25 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  4. package/.github/workflows/docs.yaml +93 -0
  5. package/.github/workflows/prepare-release.yaml +79 -0
  6. package/.github/workflows/release.yaml +80 -0
  7. package/.github/workflows/test.yaml +35 -0
  8. package/.husky/commit-msg +1 -0
  9. package/.husky/pre-commit +1 -0
  10. package/.prettierignore +4 -0
  11. package/.prettierrc +4 -0
  12. package/CONTRIBUTING.md +109 -0
  13. package/EXAMPLES.md +1515 -0
  14. package/LICENSE +21 -0
  15. package/README.md +285 -0
  16. package/examples/001-create-pdf.ts +112 -0
  17. package/examples/002-create-encrypted-pdf.ts +121 -0
  18. package/examples/003-sign-pdf.ts +347 -0
  19. package/examples/004-incremental-update.ts +206 -0
  20. package/examples/005-modify-acroform.ts +374 -0
  21. package/examples/006-tokeniser-example.ts +131 -0
  22. package/examples/007-decoder-example.ts +197 -0
  23. package/package.json +72 -0
  24. package/packages/pdf-lite/README.md +3 -0
  25. package/packages/pdf-lite/package.json +68 -0
  26. package/packages/pdf-lite/scripts/create-encryption-tests.sh +41 -0
  27. package/packages/pdf-lite/scripts/gen-signing-keys.sh +290 -0
  28. package/packages/pdf-lite/scripts/generate-all-signing-keys.sh +70 -0
  29. package/packages/pdf-lite/src/core/decoder.ts +454 -0
  30. package/packages/pdf-lite/src/core/generators.ts +128 -0
  31. package/packages/pdf-lite/src/core/incremental-parser.ts +221 -0
  32. package/packages/pdf-lite/src/core/index.ts +2 -0
  33. package/packages/pdf-lite/src/core/objects/pdf-array.ts +54 -0
  34. package/packages/pdf-lite/src/core/objects/pdf-boolean.ts +19 -0
  35. package/packages/pdf-lite/src/core/objects/pdf-comment.ts +50 -0
  36. package/packages/pdf-lite/src/core/objects/pdf-date.ts +74 -0
  37. package/packages/pdf-lite/src/core/objects/pdf-dictionary.ts +171 -0
  38. package/packages/pdf-lite/src/core/objects/pdf-hexadecimal.ts +54 -0
  39. package/packages/pdf-lite/src/core/objects/pdf-indirect-object.ts +137 -0
  40. package/packages/pdf-lite/src/core/objects/pdf-name.ts +19 -0
  41. package/packages/pdf-lite/src/core/objects/pdf-null.ts +15 -0
  42. package/packages/pdf-lite/src/core/objects/pdf-number.ts +98 -0
  43. package/packages/pdf-lite/src/core/objects/pdf-object-reference.ts +30 -0
  44. package/packages/pdf-lite/src/core/objects/pdf-object.ts +107 -0
  45. package/packages/pdf-lite/src/core/objects/pdf-start-xref.ts +39 -0
  46. package/packages/pdf-lite/src/core/objects/pdf-stream.ts +687 -0
  47. package/packages/pdf-lite/src/core/objects/pdf-string.ts +38 -0
  48. package/packages/pdf-lite/src/core/objects/pdf-trailer.ts +57 -0
  49. package/packages/pdf-lite/src/core/objects/pdf-xref-table.ts +264 -0
  50. package/packages/pdf-lite/src/core/parser.ts +22 -0
  51. package/packages/pdf-lite/src/core/ref.ts +102 -0
  52. package/packages/pdf-lite/src/core/serializer.ts +68 -0
  53. package/packages/pdf-lite/src/core/streams/object-stream.ts +20 -0
  54. package/packages/pdf-lite/src/core/tokeniser.ts +687 -0
  55. package/packages/pdf-lite/src/core/tokens/boolean-token.ts +20 -0
  56. package/packages/pdf-lite/src/core/tokens/byte-offset-token.ts +20 -0
  57. package/packages/pdf-lite/src/core/tokens/comment-token.ts +32 -0
  58. package/packages/pdf-lite/src/core/tokens/end-array-token.ts +10 -0
  59. package/packages/pdf-lite/src/core/tokens/end-dictionary-token.ts +10 -0
  60. package/packages/pdf-lite/src/core/tokens/end-object-token.ts +10 -0
  61. package/packages/pdf-lite/src/core/tokens/end-stream-token.ts +11 -0
  62. package/packages/pdf-lite/src/core/tokens/hexadecimal-token.ts +22 -0
  63. package/packages/pdf-lite/src/core/tokens/name-token.ts +19 -0
  64. package/packages/pdf-lite/src/core/tokens/null-token.ts +9 -0
  65. package/packages/pdf-lite/src/core/tokens/number-token.ts +164 -0
  66. package/packages/pdf-lite/src/core/tokens/object-reference-token.ts +24 -0
  67. package/packages/pdf-lite/src/core/tokens/start-array-token.ts +10 -0
  68. package/packages/pdf-lite/src/core/tokens/start-dictionary-token.ts +10 -0
  69. package/packages/pdf-lite/src/core/tokens/start-object-token.ts +28 -0
  70. package/packages/pdf-lite/src/core/tokens/start-stream-token.ts +52 -0
  71. package/packages/pdf-lite/src/core/tokens/start-xref-token.ts +10 -0
  72. package/packages/pdf-lite/src/core/tokens/stream-chunk-token.ts +8 -0
  73. package/packages/pdf-lite/src/core/tokens/string-token.ts +17 -0
  74. package/packages/pdf-lite/src/core/tokens/token.ts +43 -0
  75. package/packages/pdf-lite/src/core/tokens/trailer-token.ts +12 -0
  76. package/packages/pdf-lite/src/core/tokens/whitespace-token.ts +43 -0
  77. package/packages/pdf-lite/src/core/tokens/xref-table-entry-token.ts +65 -0
  78. package/packages/pdf-lite/src/core/tokens/xref-table-section-start-token.ts +31 -0
  79. package/packages/pdf-lite/src/core/tokens/xref-table-start-token.ts +13 -0
  80. package/packages/pdf-lite/src/crypto/ciphers/aes128.ts +63 -0
  81. package/packages/pdf-lite/src/crypto/ciphers/aes256.ts +50 -0
  82. package/packages/pdf-lite/src/crypto/ciphers/rc4.ts +82 -0
  83. package/packages/pdf-lite/src/crypto/constants.ts +10 -0
  84. package/packages/pdf-lite/src/crypto/key-derivation/key-derivation-aes256.ts +213 -0
  85. package/packages/pdf-lite/src/crypto/key-derivation/key-derivation.ts +122 -0
  86. package/packages/pdf-lite/src/crypto/key-gen/key-gen-aes256.ts +79 -0
  87. package/packages/pdf-lite/src/crypto/key-gen/key-gen-rc4-128.ts +190 -0
  88. package/packages/pdf-lite/src/crypto/key-gen/key-gen-rc4-40.ts +129 -0
  89. package/packages/pdf-lite/src/crypto/types.ts +6 -0
  90. package/packages/pdf-lite/src/crypto/utils.ts +81 -0
  91. package/packages/pdf-lite/src/filters/ascii85.ts +128 -0
  92. package/packages/pdf-lite/src/filters/asciihex.ts +55 -0
  93. package/packages/pdf-lite/src/filters/flate.ts +39 -0
  94. package/packages/pdf-lite/src/filters/lzw.ts +144 -0
  95. package/packages/pdf-lite/src/filters/pass-through.ts +37 -0
  96. package/packages/pdf-lite/src/filters/runlength.ts +92 -0
  97. package/packages/pdf-lite/src/filters/types.ts +21 -0
  98. package/packages/pdf-lite/src/index.ts +4 -0
  99. package/packages/pdf-lite/src/pdf/errors.ts +5 -0
  100. package/packages/pdf-lite/src/pdf/index.ts +4 -0
  101. package/packages/pdf-lite/src/pdf/pdf-document.ts +924 -0
  102. package/packages/pdf-lite/src/pdf/pdf-reader.ts +57 -0
  103. package/packages/pdf-lite/src/pdf/pdf-revision.ts +234 -0
  104. package/packages/pdf-lite/src/pdf/pdf-xref-lookup.ts +527 -0
  105. package/packages/pdf-lite/src/security/crypt-filters/aesv2.ts +58 -0
  106. package/packages/pdf-lite/src/security/crypt-filters/aesv3.ts +56 -0
  107. package/packages/pdf-lite/src/security/crypt-filters/base.ts +140 -0
  108. package/packages/pdf-lite/src/security/crypt-filters/identity.ts +40 -0
  109. package/packages/pdf-lite/src/security/crypt-filters/v2.ts +59 -0
  110. package/packages/pdf-lite/src/security/handlers/base.ts +625 -0
  111. package/packages/pdf-lite/src/security/handlers/pubSec.ts +413 -0
  112. package/packages/pdf-lite/src/security/handlers/utils.ts +304 -0
  113. package/packages/pdf-lite/src/security/handlers/v1.ts +225 -0
  114. package/packages/pdf-lite/src/security/handlers/v2.ts +128 -0
  115. package/packages/pdf-lite/src/security/handlers/v4.ts +379 -0
  116. package/packages/pdf-lite/src/security/handlers/v5.ts +298 -0
  117. package/packages/pdf-lite/src/security/types.ts +158 -0
  118. package/packages/pdf-lite/src/signing/document-security-store.ts +224 -0
  119. package/packages/pdf-lite/src/signing/index.ts +3 -0
  120. package/packages/pdf-lite/src/signing/signatures/adbe-pkcs7-detached.ts +154 -0
  121. package/packages/pdf-lite/src/signing/signatures/adbe-pkcs7-sha1.ts +161 -0
  122. package/packages/pdf-lite/src/signing/signatures/adbe-x509-rsa-sha1.ts +106 -0
  123. package/packages/pdf-lite/src/signing/signatures/base.ts +229 -0
  124. package/packages/pdf-lite/src/signing/signatures/etsi-cades-detached.ts +229 -0
  125. package/packages/pdf-lite/src/signing/signatures/etsi-rfc3161.ts +92 -0
  126. package/packages/pdf-lite/src/signing/signatures/index.ts +6 -0
  127. package/packages/pdf-lite/src/signing/signer.ts +120 -0
  128. package/packages/pdf-lite/src/signing/types.ts +86 -0
  129. package/packages/pdf-lite/src/signing/utils.ts +71 -0
  130. package/packages/pdf-lite/src/types.ts +44 -0
  131. package/packages/pdf-lite/src/utils/IterableReadableStream.ts +30 -0
  132. package/packages/pdf-lite/src/utils/algos.ts +446 -0
  133. package/packages/pdf-lite/src/utils/assert.ts +42 -0
  134. package/packages/pdf-lite/src/utils/bytesToHex.ts +18 -0
  135. package/packages/pdf-lite/src/utils/bytesToHexBytes.ts +27 -0
  136. package/packages/pdf-lite/src/utils/bytesToString.ts +17 -0
  137. package/packages/pdf-lite/src/utils/concatUint8Arrays.ts +26 -0
  138. package/packages/pdf-lite/src/utils/escapeString.ts +49 -0
  139. package/packages/pdf-lite/src/utils/hexBytesToBytes.ts +22 -0
  140. package/packages/pdf-lite/src/utils/hexBytesToString.ts +21 -0
  141. package/packages/pdf-lite/src/utils/hexToBytes.ts +18 -0
  142. package/packages/pdf-lite/src/utils/padBytes.ts +25 -0
  143. package/packages/pdf-lite/src/utils/predictors.ts +332 -0
  144. package/packages/pdf-lite/src/utils/replaceInBuffer.ts +56 -0
  145. package/packages/pdf-lite/src/utils/stringToBytes.ts +22 -0
  146. package/packages/pdf-lite/src/utils/stringToHexBytes.ts +23 -0
  147. package/packages/pdf-lite/src/utils/unescapeString.ts +123 -0
  148. package/packages/pdf-lite/test/acceptance/__snapshots__/versions.node.test.ts.snap +60766 -0
  149. package/packages/pdf-lite/test/acceptance/fixtures/1.3/basic.pdf +0 -0
  150. package/packages/pdf-lite/test/acceptance/fixtures/1.4/basic-aes-128.pdf +0 -0
  151. package/packages/pdf-lite/test/acceptance/fixtures/1.4/basic-aes-256.pdf +0 -0
  152. package/packages/pdf-lite/test/acceptance/fixtures/1.4/basic-rc4-128.pdf +0 -0
  153. package/packages/pdf-lite/test/acceptance/fixtures/1.4/basic-rc4-40.pdf +0 -0
  154. package/packages/pdf-lite/test/acceptance/fixtures/1.4/basic.pdf +0 -0
  155. package/packages/pdf-lite/test/acceptance/fixtures/1.5/basic.pdf +0 -0
  156. package/packages/pdf-lite/test/acceptance/fixtures/1.6/basic.pdf +0 -0
  157. package/packages/pdf-lite/test/acceptance/fixtures/1.7/basic.pdf +0 -0
  158. package/packages/pdf-lite/test/acceptance/fixtures/2.0/basic-aes-128.pdf +43 -0
  159. package/packages/pdf-lite/test/acceptance/fixtures/2.0/basic-aes-256.pdf +43 -0
  160. package/packages/pdf-lite/test/acceptance/fixtures/2.0/basic-rc4-128.pdf +43 -0
  161. package/packages/pdf-lite/test/acceptance/fixtures/2.0/basic-rc4-40.pdf +44 -0
  162. package/packages/pdf-lite/test/acceptance/fixtures/2.0/basic.pdf +79 -0
  163. package/packages/pdf-lite/test/acceptance/versions.node.test.ts +41 -0
  164. package/packages/pdf-lite/test/unit/__snapshots__/decoder.node.test.ts.snap +86947 -0
  165. package/packages/pdf-lite/test/unit/__snapshots__/tokeniser.node.test.ts.snap +131829 -0
  166. package/packages/pdf-lite/test/unit/ciphers.test.ts +61 -0
  167. package/packages/pdf-lite/test/unit/decoder.node.test.ts +21 -0
  168. package/packages/pdf-lite/test/unit/decoder.test.ts +567 -0
  169. package/packages/pdf-lite/test/unit/filters.test.ts +67 -0
  170. package/packages/pdf-lite/test/unit/fixtures/basic.pdf +0 -0
  171. package/packages/pdf-lite/test/unit/fixtures/encrypted_v1/basic-aes-128.pdf +0 -0
  172. package/packages/pdf-lite/test/unit/fixtures/encrypted_v1/basic-aes-256.pdf +0 -0
  173. package/packages/pdf-lite/test/unit/fixtures/encrypted_v1/basic-rc4-128.pdf +0 -0
  174. package/packages/pdf-lite/test/unit/fixtures/encrypted_v1/basic-rc4-40.pdf +43 -0
  175. package/packages/pdf-lite/test/unit/fixtures/protectedAdobeLivecycle.pdf +0 -0
  176. package/packages/pdf-lite/test/unit/fixtures/rsa-2048/index.ts +187 -0
  177. package/packages/pdf-lite/test/unit/fixtures/template.pdf +0 -0
  178. package/packages/pdf-lite/test/unit/incremental-update.test.ts +0 -0
  179. package/packages/pdf-lite/test/unit/objects.test.ts +0 -0
  180. package/packages/pdf-lite/test/unit/pdf-document-signing.test.ts +0 -0
  181. package/packages/pdf-lite/test/unit/pdf-revision.test.ts +195 -0
  182. package/packages/pdf-lite/test/unit/pdf.browser.test.ts +0 -0
  183. package/packages/pdf-lite/test/unit/predictors.test.ts +226 -0
  184. package/packages/pdf-lite/test/unit/ref.test.ts +158 -0
  185. package/packages/pdf-lite/test/unit/security-handlers.test.ts +645 -0
  186. package/packages/pdf-lite/test/unit/serializer.test.ts +81 -0
  187. package/packages/pdf-lite/test/unit/signature-objects.test.ts +814 -0
  188. package/packages/pdf-lite/test/unit/string-escaping.test.ts +84 -0
  189. package/packages/pdf-lite/test/unit/tokeniser.node.test.ts +38 -0
  190. package/packages/pdf-lite/test/unit/tokeniser.test.ts +1213 -0
  191. package/packages/pdf-lite/test/unit/utils.test.ts +248 -0
  192. package/packages/pdf-lite/test/unit/xref-lookup.test.ts +72 -0
  193. package/packages/pdf-lite/tsconfig.json +4 -0
  194. package/packages/pdf-lite/tsconfig.prod.json +8 -0
  195. package/packages/pdf-lite/typedoc.json +14 -0
  196. package/packages/pdf-lite/vitest.config.ts +43 -0
  197. package/pnpm-workspace.yaml +2 -0
  198. package/renovate.json +34 -0
  199. package/scripts/build-examples.ts +30 -0
  200. package/scripts/bump-version.sh +56 -0
  201. package/scripts/gen-html-docs.sh +21 -0
  202. package/scripts/gen-md-docs.sh +15 -0
  203. package/scripts/prepare-release.sh +33 -0
  204. package/tsconfig.json +22 -0
  205. package/tsconfig.prod.json +12 -0
  206. package/typedoc.json +34 -0
@@ -0,0 +1,140 @@
1
+ import { PdfDictionary } from '../../core/objects/pdf-dictionary'
2
+ import { PdfName } from '../../core/objects/pdf-name'
3
+ import { PdfNumber } from '../../core/objects/pdf-number'
4
+ import { Cipher } from '../../crypto/types'
5
+ import { ByteArray } from '../../types'
6
+ import { PdfSecurityHandler } from '../handlers/base'
7
+ import { PdfCryptFilterDictionary } from '../types'
8
+
9
+ /**
10
+ * Configuration options for creating a crypt filter.
11
+ */
12
+ export type CryptFilterOptions = {
13
+ /** Security handler for key derivation and encryption operations. */
14
+ securityHandler?: PdfSecurityHandler
15
+ /** Crypt filter method: 'None' (identity), 'V2' (RC4), 'AESV2' (AES-128), or 'AESV3' (AES-256). */
16
+ cfm: 'None' | 'V2' | 'AESV2' | 'AESV3'
17
+ /** Event that triggers authentication: 'DocOpen' or 'EFOpen' (embedded file open). */
18
+ authEvent: 'DocOpen' | 'EFOpen'
19
+ /** Key length in bits. */
20
+ length?: number
21
+ }
22
+
23
+ /**
24
+ * Abstract base class for PDF crypt filters.
25
+ * Crypt filters define how specific types of data (strings, streams, files) are encrypted.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const filter = new AesV2CryptFilter({ authEvent: 'DocOpen' })
30
+ * filter.setSecurityHandler(securityHandler)
31
+ * const encrypted = await filter.encrypt(data, objectNumber, generationNumber)
32
+ * ```
33
+ */
34
+ export abstract class PdfCryptFilter {
35
+ /** Crypt filter method identifier. */
36
+ cfm: 'None' | 'V2' | 'AESV2' | 'AESV3'
37
+ /** Authentication event trigger. */
38
+ authEvent: 'DocOpen' | 'EFOpen'
39
+ /** Key length in bits. */
40
+ length: number
41
+ /** Security handler for cryptographic operations. */
42
+ protected securityHandler?: PdfSecurityHandler
43
+
44
+ /**
45
+ * Creates a new crypt filter with the specified options.
46
+ *
47
+ * @param options - Configuration options for the crypt filter.
48
+ */
49
+ constructor(options: CryptFilterOptions) {
50
+ const { cfm, authEvent, length, securityHandler } = options
51
+
52
+ this.securityHandler = securityHandler
53
+ this.cfm = cfm
54
+ this.authEvent = authEvent
55
+ this.length = length ?? 0
56
+ }
57
+
58
+ /**
59
+ * Sets the security handler for this crypt filter.
60
+ *
61
+ * @param handler - The security handler to use for key derivation.
62
+ */
63
+ setSecurityHandler(handler: PdfSecurityHandler) {
64
+ this.securityHandler = handler
65
+ }
66
+
67
+ /**
68
+ * Gets the current security handler.
69
+ *
70
+ * @returns The security handler, or undefined if not set.
71
+ */
72
+ getSecurityHandler(): PdfSecurityHandler | undefined {
73
+ return this.securityHandler
74
+ }
75
+
76
+ /**
77
+ * Gets a cipher instance for encrypting/decrypting data.
78
+ *
79
+ * @param objectNumber - The PDF object number for key derivation.
80
+ * @param generationNumber - The PDF generation number for key derivation.
81
+ * @returns A cipher instance for encryption/decryption operations.
82
+ */
83
+ abstract getCipher(
84
+ objectNumber?: number,
85
+ generationNumber?: number,
86
+ ): Promise<Cipher>
87
+
88
+ /**
89
+ * Encrypts data using this crypt filter.
90
+ *
91
+ * @param data - The data to encrypt.
92
+ * @param objectNumber - The PDF object number for key derivation.
93
+ * @param generationNumber - The PDF generation number for key derivation.
94
+ * @returns The encrypted data.
95
+ */
96
+ async encrypt(
97
+ data: ByteArray,
98
+ objectNumber?: number,
99
+ generationNumber?: number,
100
+ ): Promise<ByteArray> {
101
+ const cipher = await this.getCipher(objectNumber, generationNumber)
102
+ return cipher.encrypt(data)
103
+ }
104
+
105
+ /**
106
+ * Decrypts data using this crypt filter.
107
+ *
108
+ * @param data - The data to decrypt.
109
+ * @param objectNumber - The PDF object number for key derivation.
110
+ * @param generationNumber - The PDF generation number for key derivation.
111
+ * @returns The decrypted data.
112
+ */
113
+ async decrypt(
114
+ data: ByteArray,
115
+ objectNumber?: number,
116
+ generationNumber?: number,
117
+ ): Promise<ByteArray> {
118
+ const cipher = await this.getCipher(objectNumber, generationNumber)
119
+ return cipher.decrypt(data)
120
+ }
121
+
122
+ /**
123
+ * Converts this crypt filter to a PDF dictionary representation.
124
+ *
125
+ * @returns The crypt filter dictionary.
126
+ */
127
+ toDictionary(): PdfCryptFilterDictionary {
128
+ const dict: PdfCryptFilterDictionary = new PdfDictionary({
129
+ AuthEvent: new PdfName(this.authEvent),
130
+ CFM: new PdfName(this.cfm),
131
+ ...(this.length
132
+ ? {
133
+ Length: new PdfNumber(this.length),
134
+ }
135
+ : {}),
136
+ })
137
+
138
+ return dict
139
+ }
140
+ }
@@ -0,0 +1,40 @@
1
+ import { Cipher } from '../../crypto/types'
2
+ import { ByteArray } from '../../types'
3
+ import { PdfCryptFilter, CryptFilterOptions } from './base'
4
+
5
+ /**
6
+ * Identity crypt filter that passes data through without encryption.
7
+ * Used when no encryption is needed for specific content types.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const filter = new IdentityCryptFilter({ authEvent: 'DocOpen' })
12
+ * const output = await filter.encrypt(data) // Returns data unchanged
13
+ * ```
14
+ */
15
+ export class IdentityCryptFilter extends PdfCryptFilter {
16
+ /**
17
+ * Creates a new identity crypt filter.
18
+ *
19
+ * @param options - Configuration options with authentication event.
20
+ */
21
+ constructor(options: { authEvent: CryptFilterOptions['authEvent'] }) {
22
+ super({ ...options, cfm: 'None' })
23
+ }
24
+
25
+ /**
26
+ * Gets a passthrough cipher that returns data unchanged.
27
+ *
28
+ * @returns A cipher that performs no encryption or decryption.
29
+ */
30
+ async getCipher(): Promise<Cipher> {
31
+ return {
32
+ encrypt: async (data: ByteArray) => {
33
+ return data
34
+ },
35
+ decrypt: async (data: ByteArray) => {
36
+ return data
37
+ },
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,59 @@
1
+ import { rc4 } from '../../crypto/ciphers/rc4.js'
2
+ import { Cipher } from '../../crypto/types.js'
3
+ import { PdfCryptFilter, CryptFilterOptions } from './base'
4
+
5
+ /**
6
+ * V2 crypt filter using RC4 encryption.
7
+ * Implements the legacy RC4 stream cipher for PDF encryption.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const filter = new V2CryptFilter({
12
+ * authEvent: 'DocOpen',
13
+ * securityHandler,
14
+ * length: 128
15
+ * })
16
+ * const encrypted = await filter.encrypt(data, objectNumber, generationNumber)
17
+ * ```
18
+ */
19
+ export class V2CryptFilter extends PdfCryptFilter {
20
+ /**
21
+ * Creates a new V2 crypt filter with RC4 encryption.
22
+ *
23
+ * @param options - Configuration options including key length.
24
+ */
25
+ constructor(options: {
26
+ authEvent: CryptFilterOptions['authEvent']
27
+ securityHandler?: CryptFilterOptions['securityHandler']
28
+ length?: number
29
+ }) {
30
+ super({ ...options, cfm: 'V2', length: options.length || 40 })
31
+ }
32
+
33
+ /**
34
+ * Gets an RC4 cipher for encryption/decryption.
35
+ *
36
+ * @param objectNumber - The PDF object number for key derivation.
37
+ * @param generationNumber - The PDF generation number for key derivation.
38
+ * @returns An RC4 cipher instance.
39
+ * @throws Error if security handler is not set.
40
+ */
41
+ async getCipher(
42
+ objectNumber?: number,
43
+ generationNumber?: number,
44
+ ): Promise<Cipher> {
45
+ const securityHandler = this.securityHandler
46
+ if (!securityHandler) {
47
+ throw new Error('Missing security handler for V2 crypt filter')
48
+ }
49
+
50
+ const objectKey = await securityHandler.computeObjectKey(
51
+ objectNumber,
52
+ generationNumber,
53
+ )
54
+
55
+ return rc4(
56
+ objectKey.slice(0, this.length / 8), // V2 needs a key of specified length in bits
57
+ )
58
+ }
59
+ }