PHP+MySQL签名系统:如何防止DB管理员篡改文档与签署者关联表?
解决文档-签署者关联关系不可篡改的可行方案
针对你基于PHP、jQuery、MySQL构建的电子签署系统,以下是几个能解决数据库管理员篡改关联关系问题的实用方案:
方案1:基于签署者公私钥对的关联签名验证
实现步骤
- 签署者账号创建阶段:除了存储可视化签名和密码,额外生成一对RSA公私钥对,将私钥用签署者的密码加密后存入数据库,公钥明文存储(或加密后存储,验证时解密)。
- 签署文档阶段:签署者完成密码验证后,用密码解密自身的私钥,对字符串
文档ID|签署者ID|签署时间戳进行签名,将签名值、文档ID、签署者ID、时间戳一起写入关联表。 - 验证阶段:查看签署记录时,取出关联表中的文档ID、签署者ID、时间戳和签名值,用对应签署者的公钥验证签名。如果签名验证通过,说明关联关系未被篡改;若DB管理员修改了文档ID或签署者ID,签名验证会失败。
PHP代码示例(签名部分)
// 假设已通过密码解密得到签署者的私钥$privateKey $content = $docId . '|' . $signerId . '|' . time(); openssl_sign($content, $signature, $privateKey, OPENSSL_ALGO_SHA256); // 将base64编码后的$signature存入数据库关联表
优缺点
- ✅ 无需额外组件,适配现有技术栈,改造成本低
- ❌ 需妥善处理公私钥的存储安全,避免私钥泄露
方案2:轻量级私有区块链存储关联关系
实现步骤
- 部署一个轻量级私有区块链节点(可用PHP实现简易链式结构,或使用现成轻量链框架)
- 每次创建文档-签署者关联时,计算当前关联数据的哈希值:
SHA256(文档ID|签署者ID|签署时间|上一条区块的哈希值),将这个哈希和关联数据打包成新的区块,添加到区块链中。 - 原关联表仅存储区块链区块的索引ID,不直接存储关联关系;查看时从区块链中读取对应区块的关联数据。
验证逻辑
区块链的链式哈希特性决定了:任何一个区块的关联数据被篡改,都会导致后续所有区块的哈希值不匹配,无法通过哈希链的验证,从而快速发现篡改行为。
优缺点
- ✅ 篡改难度极高,数据可信度强
- ❌ 需要额外部署和维护区块链节点,适合少量签署者的小规模场景
方案3:独立只读存储的签署凭证
实现步骤
- 签署完成后,服务器生成结构化签署凭证(JSON格式):
{ "doc_id": "DOC_123", "signer_id": "USER_456", "sign_time": "2024-05-20 14:30:00" } - 用服务器私钥对凭证签名,将签名后的凭证存入只读存储介质(如单独的只读MySQL库、不可修改的云存储文件、本地只读文件)。
- 原关联表保留关联关系,但验证时优先对比只读存储中的凭证数据。
验证逻辑
查看签署记录时,从只读存储取出凭证,用服务器公钥验证签名有效性,同时对比凭证中的关联关系和数据库记录。若两者不一致,说明数据库关联关系被篡改。
优缺点
- ✅ 实现简单,只读存储的篡改难度远高于普通数据库
- ❌ 需要额外存储资源,且需保证只读存储的可用性
内容的提问来源于stack exchange,提问作者willmbanfield
相关产品推荐
相关产品推荐

