本文目录导读:

- 电子签章的本质:不是“图片盖章”,而是“数字签名”
- PHP 实现电子签章的核心技术栈
- 三种主流实现方案对比
- 手把手实战:基于 OpenSSL + PDF 的 PHP 签名代码示例
- 常见问题与合规避坑指南(含问答)
- 结语:技术选型建议与 SEO 延伸
PHP 怎么电子签章?从原理到实战,一文搞定合规数字签名**
目录导读
- 电子签章的本质:不是“图片盖章”,而是“数字签名”
- PHP 实现电子签章的核心技术栈(哈希、非对称加密、时间戳)
- 三种主流实现方案对比(第三方 API / 开源库 / 自研 PKI)
- 手把手实战:基于 OpenSSL + PDF 的 PHP 签名代码示例
- 常见问题与合规避坑指南(含问答)
- 技术选型建议与 SEO 关键词延伸
电子签章的本质:不是“图片盖章”,而是“数字签名”
很多 PHP 开发者最初会误解“电子签章”就是往 PDF 上贴一张红章 PNG,但真正合规的电子签章(尤其在中国《电子签名法》框架下)必须具备三个核心属性:
- 身份可信:签名者身份经过实名认证(CA 机构颁发数字证书)。
- 防篡改:签名后文档任何字节改动,验签都会失败。
- 不可抵赖:签名与文档内容、签名时间强绑定,产生法律效力。
PHP 实现电子签章的本质是利用非对称加密算法(RSA/ECC)对文档摘要进行加密,并将签名值、证书信息、时间戳嵌入文档(通常是 PDF)的特定结构(如 /Sig 签名域)。
PHP 实现电子签章的核心技术栈
| 技术组件 | 作用 | PHP 对应库/扩展 |
|---|---|---|
| 哈希算法 (SHA-256) | 计算文档唯一指纹 | hash() 原生函数 |
| 非对称加密 (RSA) | 私钥签名、公钥验签 | openssl_sign() / openssl_verify() |
| 数字证书 (X.509) | 绑定公钥与身份信息 | openssl_x509_parse() |
| PDF 签名域 | 将签名值嵌入 PDF | TCPDF / FPDI / SetaPDF(商业) |
| 时间戳服务 (TSA) | 证明签名时间合规 | 第三方 TSA 接口(如中国网证通) |
三种主流实现方案对比
| 方案类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 第三方 API(如 e签宝、法大大、腾讯电子签) | 合规性强、免运维、内置实名认证 | 按次收费、有网络依赖 | 小微企业、短期项目 |
| 开源库组合(OpenSSL + TCPDF) | 免费、可控性高 | 需自建 CA 信任链,法律效力较弱 | 内部流程、非强合规场景 |
| 企业自研 PKI(对接 CFCA / 国密 SM2) | 完全自主可控、符合国密标准 | 开发周期长、需申请证书资质 | 银行、政务、大型国企 |
SEO 提示:搜索量较高的长尾词包括“PHP pdf 电子签名库”“php sm2 国密签名”“laravel 电子签章”等,本文覆盖前两者。
手把手实战:基于 OpenSSL + PDF 的 PHP 签名代码示例
以下代码实现简化的“数字签名”(不嵌入 PDF 可视化章,但法律效力完整),若需可视化红章,可叠加 TCPDF 的图像叠加功能。
<?php
// 1. 读取待签名PDF文件内容(二进制)
$docContent = file_get_contents('contract.pdf');
// 2. 计算哈希摘要(防篡改)
$docHash = hash('sha256', $docContent, true);
// 3. 加载企业私钥(.pem格式,需密码保护)
$privateKey = openssl_pkey_get_private('file://mykey.pem', 'your_passphrase');
// 4. 执行签名(使用SHA256withRSA)
openssl_sign($docHash, $signature, $privateKey, OPENSSL_ALGO_SHA256);
// 5. 获取公钥及证书信息(用于验签方)
$certData = openssl_x509_parse(file_get_contents('mycert.pem'));
$serialNumber = $certData['serialNumberHex'];
// 6. 将签名值、签名算法、证书序列号、时间戳写入一个JSON(或PDF元数据)
$signInfo = [
'signature' => base64_encode($signature),
'algo' => 'RSA-SHA256',
'cert_sn' => $serialNumber,
'signed_at' => date('c', time()),
'digest' => base64_encode($docHash)
];
file_put_contents('signature_data.json', json_encode($signInfo));
// 7. 验签流程(供对方验证)
$publicKey = openssl_pkey_get_public(file_get_contents('mycert.pem'));
$verifyResult = openssl_verify($docHash, $signature, $publicKey, OPENSSL_ALGO_SHA256);
echo $verifyResult === 1 ? '✅ 签名有效,文档未被篡改' : '❌ 签名无效';
?>
关键说明:
- 真实生产环境需要将
signature_data.json嵌入 PDF 的/Annots或 XMP 元数据中(可使用SetaPDF-Signer库,但收费约 $99)。 - 若需符合《电子签名法》的“可靠电子签名”,必须接入第三方时间戳服务,否则法院可能不采信签名时间。
常见问题与合规避坑指南(含问答)
Q1:PHP 电子签章用 RSA 和 SM2(国密)有什么区别?
A:RSA 是国际通用算法,易与海外系统对接;SM2 是中国国密标准(GM/T 0003),银行/政务强制要求,PHP 实现 SM2 可使用扩展 openssl(PHP 7.4+ 支持 SM2 签名)或 bignum 库,若面向国内司法诉讼,建议优先选 SM2。
Q2:上传到服务器上的“白底红章”图片直接盖在 PDF 上算有效吗?
A:无效,图片可复制、可PS,无法防篡改,真正的电子签章必须包含数字签名值,且签名值绑定文档内容哈希,如果仅做内部预览,可以贴图;但法律纠纷时法院会委托鉴定机构校验数字签名。
Q3:PHP 使用 TCPDF 生成 PDF 时如何添加可视化签章域?
A:TCPDF 本身不支持数字签名(只支持图片水印),推荐方案:
- 先用 FPDI 导入现有 PDF 页面;
- 在指定坐标插入印章 PNG(
->ImageSVG()); - 再调用
TCPDF->setSignature()(但该函数只是嵌入证书,不执行标准 PAdES)。
真正合规可试用开源库KraftHaus/Hydra或商业SetaPDF-Signer。
Q4:验证签名的 PHP 代码需要给客户哪些“零件”?
A:通常提供三样:
- 原始 PDF 文件(带签名数据)
- 签名方公钥证书(.cer)
- 验签 PHP 脚本(或在线验签页面)
关键:私钥绝不能泄露;证书过期前需重新签名。
技术选型建议与 SEO 延伸
综合来看,如果你的项目面向企业外部合同,强烈建议直接购买第三方电子签 API(如 e签宝、法大大),因为它们已做了人脸识别、短信验证、时间戳、司法存证全链路,PHP 只需调用 curl 接口即可,开发成本低于自研的 1/10。
若仅用于内部流程(如审批单、报销单),用本文的 OpenSSL 方案即可,但需自己维护证书生命周期。
SEO 延伸阅读(其他用户也在搜):
- “php 防止文件篡改”
- “pdf 数字化签名 php library”
- “electron signature php codeigniter”
- “国密 SM2 php openssl 不支持怎么办”(答案:安装
openssl1.1.1+ 并启用sm2参数,或使用sodium扩展)
希望这篇 PHP 电子签章全解析能帮到你,动手前先小范围测试,尤其是 证书链验证 和 PDF 兼容性(某些 PDF 阅读器会拒绝无法识别的签名域)。