数字签名
通过加密技术证明数字数据创建者的身份真实性以及数据未被篡改的机制。基于公钥加密和哈希函数的组合实现。
数字签名 (digital signature) 是通过加密技术保证数字文档"由谁创建"(身份认证) 和"内容是否被篡改"(完整性验证) 的机制。它相当于纸质文档上的手写签名或印章,但因有密码学的支撑,伪造极其困难。数字签名在电子合同、软件分发、电子邮件认证等场景中发挥着数字社会信任基石的作用。
数字签名的工作原理分为三个步骤。第一步,签名者计算文档的哈希值 (固定长度的摘要)。第二步,用签名者的私钥对哈希值执行签名运算,生成签名数据。第三步,验证者把签名数据、签名者的公钥,以及从文档重新计算出的哈希值一并交给验证算法,判断它们是否吻合。若吻合,就能确认文档确实由持有该私钥的人签名,且签名之后未被篡改。另外,"用私钥对哈希值加密"这一说法流传甚广,但它只是针对 RSA 的类比。在 ECDSA 和 Ed25519 中,签名与验证是与加密、解密完全不同的运算,并不存在相当于解密的处理。
字符数与数字签名的关联体现在哈希函数的特性上。SHA-256 无论输入数据长度如何,始终输出 256 位 (64 个十六进制字符) 的哈希值。1 个字符的文本和 100 万个字符的文本,哈希值长度完全相同。但只要输入文本改变哪怕 1 个字符,哈希值就会变得截然不同,这正是篡改检测的原理所在。
数字签名的数据大小因算法而异。RSA-2048 的签名为 256 字节,ECDSA (P-256) 的签名以原始值 (r 与 s 的拼接) 计为 64 字节,而实际流通形式的 DER 编码约为 70 至 72 字节。签名数据会附加到文档中,导致文档整体体积增大。PDF 的数字签名除签名数据本身外,还会嵌入证书链和时间戳,因此会增加数 KB 到数十 KB 的体积。
在日本,根据电子签名法 (《关于电子签名及认证业务的法律》,2000 年公布、2001 年 4 月施行),由本人作出的、满足一定要件的电子签名所形成的电磁记录,被推定为真实成立。其含义是与盖章的纸质文档同等对待,即在诉讼中发生争议时,由主张"并非本人所作"的一方承担举证责任。这并不意味着只要有签名,合同内容本身就永远有效。电子合同服务 (CloudSign、DocuSign、Adobe Sign 等) 正是构建在这一法律框架之上。无论合同文本字数多少,电子签名的法律效力都不会改变。
实务上的一个陷阱是,签名验证通过与签名者是否为本人是两回事。验证所能确认的只是"由与这个公钥配对的私钥签了名",而该公钥属于谁,仅凭签名无法确定。填补这一空缺的是认证机构签发的证书,需要沿着证书链追溯,确认能否到达受信任的认证机构、以及证书是否已被吊销,才谈得上身份真实性。另一个是时间的处理。证书都有有效期,一旦过期或密钥失窃,就无法再证明"签名当时证书是有效的",因此对需要长期保存的文档要配合使用时间戳。
代码签名 (code signing) 是数字签名在软件分发领域的应用。通过对应用程序的可执行文件进行签名,保证开发者身份和代码完整性。未经签名的软件会被操作系统弹出警告,因此代码签名在实际操作中已成为必备环节。