类:API 和工具用于安全代码和文件交换

本课说明了为什么需要数字签名,证书和密钥库。本类还将在生成签名方面比较工具与 JDK 安全 API 的使用。在接下来的两个类签署代码并授予其权限Exchanging Files中将演示这种工具的用法。 生成和验证签名类中演示了 API 的用法。

本课包含以下部分

代码和文档安全

如果您以电子方式向某人发送了一个或多个重要文档,或要运行的 Servlets 或应用程序,则收件人需要一种方法来验证该文档或代码是否来自您并且在传输过程中未被修改(例如,被恶意用户修改)拦截它)。数字签名,证书和密钥库都可以帮助确保您发送的文件的安全性。

Digital Signatures

使用数字签名的基本思想如下。

  • 您使用其中的一个“私钥”“签署”文档或代码,您可以使用keytool或安全性 API 方法生成该私钥。也就是说,您可以使用jarsigner工具或 Security API 方法为文档或代码生成数字签名。

  • 您将签名的文档发送给收件人。

  • 您还向收件人提供了 公钥. 此公钥与您最初用于生成签名的私钥相对应。

  • 收件人使用您的公共密钥来验证您的文档来自您,并且在到达之前没有被修改。

收件人需要先确保您的公钥本身是真实的,然后才能使用它来验证您的签名是真实的。因此,您通常会提供包含公钥的“证书”以及可以证明您密钥真实性的“证书颁发机构”的密钥。有关详细信息,请参见下一部分。

有关签名和验证的术语和概念的更多信息,以及对好处的进一步说明,请参阅“ JAR 文件中的打包程序”类的签名 JAR 文件部分。

Certificates

证书包含:

  • 公钥。

  • 其证书所在的实体(个人,公司等)的“专有名称”信息。该实体称为证书主题或所有者。专有名称信息包括以下属性(或子集):实体的名称,组织单位,组织,城市或地区,State 或省以及国家/地区代码。

  • 数字签名。证书由一个实体(发行方)签名,以证明所包含的公钥是另一实体(所有者)的实际公钥。

  • 签名者(发行者)的专有名称信息。

接收者检查证书是否有效的一种方法是使用其颁发者(签名者)的公共密钥来验证其数字签名。该密钥本身可以存储在另一个证书中,该证书的签名也可以使用该下一个证书的发行者的公钥进行验证,并且该密钥也可以存储在另一个证书中,依此类推。当您到达已经信任的公钥时,可以停止检查,并使用它来验证相应证书上的签名。

如果接收者无法构建信任链,那么他/她可以使用keytool -import-printcert命令计算证书 指纹 。指纹是一个相对较短的数字,可以唯一且可靠地标识证书。 (从技术上讲,指纹是使用消息摘要功能的证书信息的哈希值.)然后,接收者可以给证书所有者打电话,并将接收到的证书的指纹值与发送的证书进行比较。如果指纹相同,则证书相同。

因此,您可以确保证书在传输过程中没有被修改。使用证书时,另一个潜在的不确定性是发送者的身份。有时证书是“自签名的”,即使用与证书中的公钥相对应的私钥签名;发行人与主题相同。

自签名证书对于开发和测试应用程序很有用。但是,在部署给用户之前,请从可信任的第三方(称为证书颁发机构(CA))获取证书。为此,您将自签名证书签名请求(CSR)发送到 CA。 CA 可能会通过检查驾驶 License 或其他信息来验证 CSR 和您的身份上的签名。然后,CA 通过颁发证书并使用其自己的(CA 的)私钥对其进行签名,以证明您是公钥的所有者。现在,任何信任颁发 CA 的公钥的人都可以验证证书上的签名。在许多情况下,颁发 CA 本身可能会从 CA 层次结构中较高级别的 CA 获得证书,从而导致 证书链

您信任的实体的证书通常作为“ 可信证书 ”导入到密钥库中。然后,每个这样的证书中的公钥可用于验证使用相应私钥生成的签名。可以通过以下方式完成此类验证:

  • jarsigner工具(如果文档/代码和签名出现在 JAR 文件中),

  • API 方法,或

  • 在运行时系统中,当try进行资源访问并且策略文件指定如果其签名是真实的,则允许对该try访问的代码进行资源访问。代码的类文件和签名必须位于 JAR 文件中。

如果要将签名的代码或文档发送给其他人,则需要向他们提供包含与用于签名代码/文档的私钥相对应的公钥的证书。 keytool -export命令或 API 方法可以将证书从密钥库导出到文件中,然后可以将其发送给需要它的任何人。接收证书的人可以使用例如 API 方法或keytool -import命令将其作为受信任证书导入密钥库。

如果使用jarsigner工具为 JAR 文件生成签名,则该工具将从密钥库中检索证书及其支持的证书链。然后,该工具将它们以及签名存储在 JAR 文件中。

Keystores

私钥及其关联的公钥证书存储在称为 keystores 的受密码保护的数据库中。密钥库可以包含两种类型的条目:上面讨论的可信证书条目,以及密钥/证书条目,每种条目都包含一个私钥和相应的公钥证书。密钥库中的每个条目都由* alias *标识。

密钥库所有者可以在密钥库中具有多个密钥,可以通过不同的别名进行访问。别名通常以密钥库所有者在其中使用关联密钥的特定角色命名。别名也可以标识密钥的用途。例如,别名signPersonalEmail可以用于标识其私钥用于签名个人电子邮件的密钥库条目,别名signJarFiles可以用于标识其私钥用于签名 JAR 文件的条目。

keytool工具可用于

  • 创建私钥及其关联的公钥证书

  • 发出证书请求,然后将其发送给相应的证书颁发机构

  • 从您联系的证书颁发机构获得的导入证书答复

  • 导入属于其他方的公钥证书作为可信证书

  • 管理 您的密钥库

API 方法还可用于访问和修改密钥库。

工具和 API注解

请注意以下有关与数字签名相关的工具和 API 的用法。

  • 您可以使用 JDK 安全 API,工具或组合来生成密钥和签名并导入证书。您可以使用这些 API 或工具功能与他人安全地交换文档。

  • 要使用这些工具进行文档交换,必须将文档放在 JAR(Java ARchive)文件中,该文件可以由jar工具创建。 JAR 文件是一种将多个文件封装在一个位置的好方法。对文件进行“签名”时,需要将生成的数字签名字节存储在某个位置。对 JAR 文件进行签名后,签名可以放入 JAR 文件本身。使用jarsigner工具对 JAR 文件进行签名时,就会发生这种情况。

  • 如果要创建要签名的 Servlets 代码,则需要将其放置在 JAR 文件中。如果您创建的应用程序代码也可能通过使用安全 管理 器运行而受到类似的限制,则情况同样如此。您需要 JAR 文件的原因是,当策略文件指定允许由特定实体签名的代码一个或多个操作(例如,对特定文件的读取或写入)时,该代码应来自已签名的 JAR 文件。 (术语“签名的代码”是“在已签名的 JAR 文件中显示的类文件中的代码的缩写”.)

  • 为了使运行时系统检查代码签名,将首先运行代码的人员/组织需要将一个证书进行身份验证,该证书认证与用于签名代码的私钥相对应的公钥。

  • 为了使jarsigner工具验证 JAR 文件签名的真实性,接收 JAR 文件的人员/组织首先需要将一个证书进行身份验证,该证书对与用于签名代码的私钥相对应的公钥进行身份验证。

  • 目前没有用于创建证书的 API。

使用 JDK 安全 API 签署文档

生成和验证签名向您展示如何使用 JDK Security API 签署文档。该类显示了拥有原始文档的人执行的一个程序将如何处理

  • generate keys,

  • 使用私钥为数据生成数字签名,并

  • 将公钥和签名导出到文件中。

然后,它显示了另一个程序的示例,该程序由数据,签名和公钥的接收者执行。它显示了程序

  • 导入公钥

  • 验证签名的真实性。

本课还向您展示了导入和提供密钥(包括证书)的替代方法。

使用工具对代码或文档进行签名

签署代码并授予其权限类显示了如何使用 Java 安全工具将代码放入 JAR 文件,对其进行签名以及导出公共密钥。然后显示收件人如何使用这些相同的 Java 工具导入您的公共密钥证书,然后将条目添加到策略文件中,该文件将授予您的代码访问收件人控制的系统资源所需的权限。

Exchanging Files类介绍如何使用 Java 安全工具对文档进行签名,然后使用keytool导出公共密钥的公共密钥证书。对应于用于使用keytool对该文档签名的私钥。然后,它显示了接收者如何通过安装公钥证书,然后使用jarsigner工具来验证您的签名来验证您的签名。

这两个教训有很多共同之处。在这两种情况下,代码或文档发送者的前两个步骤是:

  • 使用jar工具创建包含文档或类文件的 JAR 文件。

  • 使用keytool -genkey命令生成密钥(如果还不存在)。

接下来的两个步骤是可选的:

  • 使用keytool -certreq命令;然后将生成的证书签名请求发送到证书颁发机构(CA),例如 VeriSign。

  • 使用keytool -import命令导入 CA 的响应。

接下来的两个步骤是必需的:

  • 使用jarsigner工具和先前生成的私钥对 JAR 文件进行签名。

  • 使用keytool -export命令导出公共密钥证书。然后将签名的 JAR 文件和证书提供给接收者。

在这两种情况下,签名的 JAR 文件的接收者和证书都应使用keytool -import命令将证书作为受信任证书导入。 keytool将try从要导入的证书到密钥库中已经受信任的证书构建信任链。如果失败,则keytool将显示证书指纹并提示您进行验证。

如果发送的是代码,则接收方还需要修改策略文件,以允许所需的资源访问由与导入证书中的公钥相对应的私钥签名的代码。可以使用“Policy 工具”来执行此操作。

如果发送的是一个或多个文档,则接收方需要使用jarsigner工具来验证 JAR 文件签名的真实性。

本课讨论了两个可选步骤。接下来的两个类签署代码并授予其权限Exchanging Files将介绍其他步骤。

生成公钥证书的证书签名请求(CSR)

当使用keytool生成公钥/私钥对时,它将创建一个密钥库条目,其中包含一个私钥和一个用于公钥的自签名证书。 (也就是说,使用相应的私钥对证书进行签名.)这在开发和测试应用程序时就足够了。

但是,如果证书是由证书颁发机构(CA)签名的,则其他人更可能信任该证书。要获取由 CA 签名的证书,您首先需要通过以下命令生成证书签名请求(CSR):

keytool -certreq -alias alias -file csrFile

在此,别名用于访问包含私钥和公钥证书的密钥库条目,而 csrFile 指定用于此命令创建的 CSR 的名称。

然后,您将此文件提交给诸如 VeriSign,Inc.的 CA。CA 对您(请求者)(“主题”)进行身份验证,然后签名并返回对您的公钥进行身份验证的证书。通过签署证书,CA 证明您是公钥的所有者。

在某些情况下,CA 将返回证书链,每个证书都对链中先前证书的签名者的公钥进行身份验证。

从 CA 导入响应

向证书颁发机构(CA)提交证书签名请求(CSR)后,您需要通过导入由 CA 返回给您的证书(或证书链),用证书链替换密钥库中的原始自签名证书。 。

但是首先,您需要在密钥库(或下面描述的cacerts密钥库文件)中有一个“可信证书”条目,用于验证 CA 的公钥。通过这样的 Importing,可以验证 CA 的签名。也就是说,可以验证 CA 在证书或 CA 响应您的 CSR 发送给您的链中的final证书上的签名。

从 CA 导入证书作为“受信任的证书”

从 CA 导入证书答复之前,您需要在密钥库或cacerts文件中一个或多个“受信任的证书”。

  • 如果证书答复是证书链,则只需要链中的最高证书-验证该 CA 公钥的“根” CA 证书。

  • 如果证书答复是单个证书,则需要颁发 CA 的证书(对它进行签名的证书)。如果该证书不是自签名的,则其签名者需要一个证书,依此类推,最多需要一个自签名的“根” CA 证书。

cacerts文件代表带有 CA 证书的系统范围的密钥库。该文件位于 JRE 安全属性目录java.home/lib/security,其中 java.home 是 JRE 安装目录。


重要提示:验证您的cacerts文件
由于您信任cacerts文件中的 CA 作为用于签署证书并将证书颁发给其他实体的实体,因此必须仔细 管理cacerts文件。 cacerts文件应仅包含您信任的 CA 的证书。您有责任验证cacerts文件中 Binding 的受信任的根 CA 证书并做出自己的信任决定。要从cacerts文件中删除不受信任的 CA 证书,请使用keytool命令的 delete 选项。您可以在 JRE 安装目录中找到cacerts文件。如果您没有编辑此文件的权限,请与系统 管理 员联系。


cacerts文件包含许多受信任的 CA 证书。如果您将 CSR 发送给这些受信任的供应商之一(例如 VeriSign),则无需在密钥库中将供应商的根证书导入为受信任的证书。您可以转到next部分以查看如何从 CA 导入证书答复。

来自 CA 的证书通常是自签名的或由另一个 CA 签名的,在这种情况下,您还需要用于验证该 CA 的公钥的证书。假设该公司 ABC,Inc.是一个 CA,并且您获得了一个名为ABCCA.cer的文件,该文件据说是 ABC 的自签名证书,用于验证该 CA 的公钥。

在将证书作为“可信”证书导入之前,请务必小心以确保其有效!首先查看它(使用keytool -printcert命令或不带-noprompt选项的keytool -import命令),并确保显示的证书指纹与期望的证书指纹匹配。您可以致电发送证书的人员,并将看到的指纹与显示的指纹或显示的安全公钥存储库进行比较。只有在指纹相等的情况下,才能保证在传输过程中未用其他人(例如,攻击者的)证书替换证书。如果发生了这样的攻击,并且您在导入证书之前没有检查证书,那么您将final信任攻击者已签名的任何内容。

如果您相信证书有效,则可以通过以下命令将其添加到密钥库中:

keytool -import -alias alias -file ABCCA.cer -keystore storefile

此命令在密钥库中创建一个“受信任的证书”条目,其名称与存储文件中指定的名称相同。该条目包含来自文件ABCCA.cer的数据,并为其分配了指定的别名。

从 CA 导入证书回复

如上一节所述,导入了所需的受信任证书之后,或者它们已经存在于密钥库或cacerts文件中,则可以导入证书答复,从而用证书替换自签名证书。链。该链可以是 CA 为响应您的请求而返回的链(如果 CA 答复是链),也可以是通过使用证书答复和已经可用的受信任证书构造的链(如果 CA 答复是单个证书)。在密钥库或cacerts密钥库文件中。

例如,假设您已将证书签名请求发送给 VeriSign。然后,您可以通过以下方式导入答复,其中假定返回的证书在 certReplyFile 指定的文件中:

keytool -import -trustcacerts
    -keystore storefile
    -alias alias 
    -file certReplyFile

在一行上键入此命令。

通过使用来自密钥库的受信任证书以及可选地使用在cacerts密钥库文件中配置的证书(如果指定了-trustcacerts选项)来验证证书答复。使用链中更高一级的证书来验证链中的每个证书。您只需要信任链中的顶级“根” CA 证书。如果您尚未信任顶级证书,则keytool将显示该证书的指纹并询问您是否要信任它。

指定的(通过别名)条 Object 新证书链替换了与此条目关联的旧证书(或链)。仅当提供了有效的密钥密码(用于保护条 Object 私钥的密码)后,才能替换旧链。如果未提供密码,并且私钥密码与密钥库密码不同,则会提示用户 Importing 密码。

有关生成 CSR 和导入证书回复的更多详细信息,请参阅keytool文档: