Sign your file with OpenSSL

在数字世界, OpenSSL 就像随身的钥匙一样的普遍.

从数据加密到数字签名.

OpenSSL ( an Open-source implementation of the SSL and TLS protocols ) [1]

前段的项目 C 有一个自动更新功能, 会从服务器检查到新版本, 然后开始: 下载/解压/安装/... blahblah [3]

如果网络中间环节出了问题, 如何保证下载回来的 xxx.tgz 不是第三方伪造的?

包装防伪

  1. 首先生成一对, 签名需要的 DSA 公私秘钥 ( Digital Signature Algorithm [2] ).
  • 然后, 此时手上已有 3 个文件:

    • my_private_key.pem 私有文件
    • my_public_key.pub 共有文件
    • xxx.tgz 目标文件
  • 签名:

# openssl dgst -dss1 -sign my_private_key.pem -out sign.txt {attr_about_xxx.tgz_file}

{attr_about_xxx.tgz_file} 这里只是做个范例.

这个参数一般来说, 就是需要签名的那个文件的某些特征. 具有文件唯一性的特征.

如: file hash (md5/sha1)

So, 代码改成 ( 用了目标文件的 sha1 hash ):

$ openssl dgst -sha1 -binary xxx.tgz | openssl dgst -dss1 -sign my_private_key.pem -out sign.txt

最终输出的 sign.txt 就是签名数据文件了. 跟着 xxx.tgz 一起发布.

客户端手上, 此时应该早已有了一份事先分发好的 my_public_key.pub 此时, 就等着收到 xxx.tgz and sign.txt

$ openssl dgst -sha1 -binary xxx.tgz | openssl dgst -dss1 -verify my_public_key.pub -signature sign.txt

Verified OK

PS: 实际使用的时候, sign.txt 一般又会是转化为 base64 encoded 字符串, 跟着 xxx.tgz 一起发布.


其它解说

dgst 参数指定需要摘要算法.

dgst -sha1 使用 SHA1 算法

dgst -dss1 配对 DSA 使用的 SHA1 算法

对比下输出:

$ openssl dgst -sha1 foo.txt 
SHA1(foo.txt)= 988881adc9fc3655077dc2d4d757d480b5ea0e11

$ openssl dgst -dss1 foo.txt
DSA(foo.txt)= 988881adc9fc3655077dc2d4d757d480b5ea0e11

附录

如何生成 DSA 秘钥对? 这个 Google 有很多.

$ openssl dsaparam 1024 > dsaparam.pem
$ openssl gendsa dsaparam.pem -out my_private_key.pem
$ openssl dsa -in my_private_key.pem -pubout -out my_public_key.pub

[1] OpenSSL

[2] DSA

[3] Why reinvent the wheel:

软件更新, 为什么不用现成的 Framework ?

* 它太大了. 精简完后还大于 1200KB.
* 而我的完整实现 (检测/下载/校验/解压/安装) 还不到 150KB.
* 需求的整个 Installer.dmg 才 500KB ( 一半是 icon Resources )
* So, this''s a better choice for me.



Sign your file with OpenSSL
Share this