decrypt_pdf.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // scripts/decrypt_pdf.ts
  2. import * as fs from 'fs'
  3. import * as path from 'path'
  4. import * as crypto from 'crypto'
  5. import { fileURLToPath } from 'url'
  6. const __filename = fileURLToPath(import.meta.url);
  7. const __dirname = path.dirname(__filename);
  8. const PDF_DIR = path.resolve(__dirname, '../../public/pdf')
  9. function getKey(password: string): Buffer {
  10. return crypto.createHash('sha256').update(password).digest()
  11. }
  12. function decryptGCM(inputPath: string, outputPath: string): void {
  13. const input = fs.readFileSync(inputPath)
  14. const iv = input.subarray(0, 12)
  15. const lenBuf = input.subarray(input.length - 4)
  16. const pLen = lenBuf.readUint32BE()
  17. const passwordBuffer = input.subarray(input.length - pLen - 4, input.length - 4)
  18. const password = passwordBuffer.toString('base64')
  19. const authTag = input.subarray(input.length - pLen - 4 - 16, input.length - pLen - 4)
  20. const encrypted = input.subarray(12, input.length - pLen - 4 - 16)
  21. const key = getKey(password)
  22. const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv)
  23. decipher.setAuthTag(authTag)
  24. const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()])
  25. fs.writeFileSync(outputPath, Buffer.from(decrypted))
  26. console.log(`✔ Decrypted (GCM): ${path.basename(inputPath)}`)
  27. }
  28. function decryptAllPDFs(): void {
  29. const files = fs.readdirSync(PDF_DIR)
  30. for (const file of files) {
  31. const fullPath = path.join(PDF_DIR, file)
  32. if (!fs.statSync(fullPath).isFile() || !file.endsWith('.enc')) continue
  33. const decPath = fullPath + '.dec'
  34. if (fs.existsSync(decPath)) {
  35. console.log(`⏭ Skipped (already decrypted): ${file}`)
  36. continue
  37. }
  38. decryptGCM(fullPath, decPath)
  39. }
  40. }
  41. decryptAllPDFs()