在上一篇文章中,我们讨论了如何保护移动代码 。
提到的措施之一是签名代码。 这篇文章探讨了Java程序如何工作。
数字签名
数字签名的基础是密码学 ,特别是公钥密码学 。 我们使用一组加密密钥:私有密钥和公共密钥。
私钥用于签名文件,并且必须保持秘密。 公钥用于验证使用私钥生成的签名。 由于键之间的特殊数学关系,这是可能的。
签名和公钥都需要转移给接收者。
证明书
为了信任文件,需要验证该文件上的签名。 为此,需要一个与用于签署文件的私钥相对应的公钥。 那么我们如何才能信任公钥呢?
这是证书的来源。证书包含公用密钥和标识该密钥所有者的专有名称 。
信任来自证书本身已签名的事实。 因此,证书还包含签名和签名者的专有名称。
当我们控制通信的两端时,我们既可以提供证书又可以完成证书 。 例如,这对于您编写的连接到您控制的服务器的移动应用程序效果很好。
如果您不能同时控制两端,那么我们需要一个替代方案。 签名者的专有名称可用于查找签名者的证书。 使用该证书中的公钥,可以验证原始证书中的签名。
我们可以以这种方式继续创建证书链 ,直到我们明确信任的签名者为止。 这通常是公认的证书颁发机构 (CA),例如VeriSign或Thawte 。
密钥库
在Java中,私钥和证书存储在称为keystore的受密码保护的数据库中。
每个密钥/证书组合由一个称为别名的字符串标识。
代码签名工具
Java附带了两个用于代码签名的工具: keytool和jarsigner 。
使用jarsigner
程序使用存储在密钥库中的证书对jar文件进行签名。
使用keytool
程序创建私钥和相应的公钥证书,从/向/从密钥库检索/存储那些证书,以及管理密钥库。
keytool
程序无法创建由其他人签名的证书。 它可以创建证书签名请求 ,但是您可以将其发送到CA。 它还可以将CA的响应导入密钥库。
替代方法是使用支持此类CA功能的工具如OpenSSL或BSAFE 。
代码签名环境
代码签名应该在安全的环境中进行,因为涉及私钥,并且私钥需要保密。 如果私钥落入他人之手,则第三方可能会使用您的密钥对他们的代码签名 ,从而诱使客户信任该代码。
这意味着您可能不想在构建机器上维护密钥库,因为该机器可能对很多人都可用。 一种更安全的方法是引入专用的签名服务器:
您还应该使用不同的签名证书进行开发和生产。
时间戳记
证书仅在有限的时间内有效。 使用公钥证书已过期的私钥签名的任何文件都不应再受信任,因为这些文件可能已在证书过期后进行了签名。
我们可以通过给文件加上时间戳来减轻此问题。 通过将受信任的时间戳记添加到文件,即使签名证书过期,我们也可以信任它。
但是,我们如何信任时间戳? 好吧,当然可以通过使用时间戳管理局进行签名! OpenSSL
程序也可以帮助您。
超越代码签名
签名代码时,仅证明该代码来自您。 为了使客户能够信任您的代码,它必须是可信任的。 您可能希望设置一个完整的安全开发生命周期 (SDL),以确保它尽可能地多。
在这方面要考虑的另一件事是第三方代码。 大多数软件包都嵌入了商业和/或开源库。 理想情况下,这些库由其作者签名。 但是无论如何,您都需要拥有所有权,因为客户不在乎在您自己编写的代码还是在所使用的库中是否发现了漏洞。
参考: 安全软件开发博客上的JCG合作伙伴 Remon Sinnema 签署Java代码 。
翻译自: https://www.javacodegeeks.com/2012/11/signing-java-code.html