You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

网站PDF导出与内容防篡改验证方案及Node技术问题咨询

针对你开发PDF导出+篡改验证功能遇到的两个问题,给你具体的实操建议:

方案一:Node环境下PDF水印嵌入与提取实现

嵌入水印

推荐用pdf-lib这个库,它是Node环境中处理PDF的主流工具,支持可见文本水印、图片水印,也能添加不可见的元数据水印:

  1. 可见文本水印
    安装依赖:
npm install pdf-lib

嵌入代码示例:

const { PDFDocument, StandardFonts, rgb } = require('pdf-lib');
const fs = require('fs').promises;

async function addVisibleWatermark(inputPath, outputPath, watermarkText) {
  const pdfBytes = await fs.readFile(inputPath);
  const pdfDoc = await PDFDocument.load(pdfBytes);
  const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
  
  const pages = pdfDoc.getPages();
  pages.forEach(page => {
    const { width, height } = page.getSize();
    // 添加水印到页面中心,设置透明度
    page.drawText(watermarkText, {
      x: width / 2,
      y: height / 2,
      size: 40,
      font: font,
      color: rgb(0.7, 0.7, 0.7),
      opacity: 0.3,
      rotate: (45 * Math.PI) / 180, // 旋转45度
      centered: true,
    });
  });
  
  const modifiedPdfBytes = await pdfDoc.save();
  await fs.writeFile(outputPath, modifiedPdfBytes);
}
  1. 不可见水印(元数据)
    通过修改PDF的自定义元数据来添加标识,不会影响PDF显示:
async function addInvisibleWatermark(inputPath, outputPath, stampId) {
  const pdfBytes = await fs.readFile(inputPath);
  const pdfDoc = await PDFDocument.load(pdfBytes);
  // 添加自定义元数据字段,比如"X-File-Stamp"
  pdfDoc.setCustomMetadata('X-File-Stamp', stampId);
  
  const modifiedPdfBytes = await pdfDoc.save();
  await fs.writeFile(outputPath, modifiedPdfBytes);
}

提取水印

  1. 提取可见文本水印
    可以用pdf-parse提取PDF所有文本,然后匹配水印内容:
npm install pdf-parse

提取代码:

const pdfParse = require('pdf-parse');
const fs = require('fs').promises;

async function extractVisibleWatermark(pdfPath, watermarkText) {
  const dataBuffer = await fs.readFile(pdfPath);
  const pdfData = await pdfParse(dataBuffer);
  return pdfData.text.includes(watermarkText);
}
  1. 提取不可见元数据水印
    用pdf-lib读取自定义元数据:
async function extractInvisibleWatermark(pdfPath) {
  const pdfBytes = await fs.readFile(pdfPath);
  const pdfDoc = await PDFDocument.load(pdfBytes);
  const customMetadata = pdfDoc.getCustomMetadata();
  return customMetadata['X-File-Stamp'];
}
方案二:适合计算file stamp的加密算法选择

推荐用SHA-256哈希算法,理由:

  • 不可逆:无法从哈希值反推原始文件内容,安全性高
  • 低碰撞概率:几乎不可能出现两个不同文件生成相同哈希值的情况
  • 性能适中:计算速度快,适合处理PDF这类文件

Node环境中直接用内置的crypto模块即可实现,无需额外依赖:

计算file stamp的代码示例:

const crypto = require('crypto');
const fs = require('fs').promises;

async function calculateFileStamp(filePath) {
  const hash = crypto.createHash('sha256');
  const fileStream = await fs.readFile(filePath);
  
  hash.update(fileStream);
  return hash.digest('hex'); // 返回16进制哈希值,可直接存入数据库
}

验证时,重新计算上传文件的SHA-256哈希值,和数据库中存储的对比即可判断是否被篡改。如果需要更严谨,可以把文件的唯一标识(比如导出时的订单ID、用户ID)和哈希值拼接后再计算,避免不同文件偶然哈希碰撞的极端情况。

内容的提问来源于stack exchange,提问作者user824624

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 09:27:38