# 了解签名和验证

> 原文： [https://docs.oracle.com/javase/tutorial/deployment/jar/intro.html](https://docs.oracle.com/javase/tutorial/deployment/jar/intro.html)

Java™平台使您能够对 JAR 文件进行数字签名。您对文件进行数字签名的原因与您使用笔和墨水签署纸质文档的原因相同 - 让读者知道您编写了文档，或者至少文档已获得您的批准。

例如，当您签署一封信时，每个认出您签名的人都可以确认您是否写了这封信。同样，当您对文件进行数字签名时，任何“识别”您的数字签名的人都知道该文件来自您。 “识别”电子签名的过程称为 _ 验证 _。

签名 JAR 文件时，您还可以选择为签名添加时间戳。与在纸质文档上添加日期类似，签名的时间戳标识了 JAR 文件的签名时间。时间戳可用于验证用于签署 JAR 文件的证书在签名时是否有效。

签名和验证文件的能力是 Java 平台安全架构的重要组成部分。安全性由运行时生效的安全 _ 策略 _ 控制。您可以将策略配置为向 applet 和应用程序授予安全权限。例如，您可以向 applet 授予权限以执行正常禁止的操作，例如读取和写入本地文件或运行本地可执行程序。如果您下载了一些由受信任实体签名的代码，则可以将该事实用作决定分配给代码的安全权限的标准。

一旦您（或您的浏览器）验证了 applet 来自可靠来源，您就可以让平台放宽安全限制，让 applet 执行通常被禁止的操作。受信任的 applet 可以具有由 _ 策略文件 _ 指定的自由。

Java 平台通过使用称为公共和私有 _ 键 _ 的特殊号码进行签名和验证。公钥和私钥成对出现，它们扮演互补字符。

私钥是电子“笔”，您可以使用它来签署文件。顾名思义，您的私钥只有您自己知道才能让其他人无法“伪造”您的签名。使用您的私钥签名的文件只能通过相应的公钥进行验证。

但是，单独的公钥和私钥不足以真正验证签名。即使您已验证签名文件包含匹配的密钥对，您仍需要某种方法来确认公钥实际上来自它声称来自的签名者。

因此，需要一个元素来进行签名和验证工作。该附加元素是签名者在签名的 JAR 文件中包含的 _ 证书 _。证书是来自认可的 _ 证书颁发机构 _ 的数字签名声明，表明谁拥有特定的公钥。认证机构是整个行业内可信赖的实体（通常是专门从事数字安全的公司），用于为密钥及其所有者签署和颁发证书。对于签名的 JAR 文件，证书指示谁拥有 JAR 文件中包含的公钥。

当您签署 JAR 文件时，您的公钥将与相关证书一起放在存档中，以便任何想要验证签名的人都可以轻松使用它。

总结数字签名：

*   签名者使用私钥对 JAR 文件进行签名。
*   相应的公钥与其证书一起放在 JAR 文件中，以便任何想要验证签名的人都可以使用它。

## 摘要和签名文件

当您对 JAR 文件进行签名时，归档中的每个文件都会在归档的[清单](manifestindex.html)中被提供一个摘要条目。以下是此类条目的示例：

```
Name: test/classes/ClassOne.class
SHA1-Digest: TD1GZt8G11dXY2p4olSZPc5Rj64=

```

摘要值是文件内容的哈希或编码表示，就像签名时一样。当且仅当文件本身发生变化时，文件的摘要才会发生变化。

签名 JAR 文件时，会自动生成 _ 签名 _ 文件，并将其放在 JAR 文件的 `META-INF` 目录中，该目录包含存档的清单。签名文件的文件名具有 `.SF` 扩展名。以下是签名文件内容的示例：

```
Signature-Version: 1.0
SHA1-Digest-Manifest: h1yS+K9T7DyHtZrtI+LxvgqaMYM=
Created-By: 1.7.0_06 (Oracle Corporation)

Name: test/classes/ClassOne.class
SHA1-Digest: fcav7ShIG6i86xPepmitOVo4vWY=

Name: test/classes/ClassTwo.class
SHA1-Digest: xrQem9snnPhLySDiZyclMlsFdtM=

Name: tehttps://docs.oracle.com/javase/tutorial/images/ImageOne.gif
SHA1-Digest: kdHbE7kL9ZHLgK7akHttYV4XIa0=

Name: tehttps://docs.oracle.com/javase/tutorial/images/ImageTwo.gif
SHA1-Digest: mF0D5zpk68R4oaxEqoS9Q7nhm60=

```

如您所见，签名文件包含存档文件的摘要条目，这些文件看起来类似于清单中的摘要值条目。但是，虽然清单中的摘要值是根据文件本身计算的，但签名文件中的摘要值是根据清单中的相应条目计算的。签名文件还包含整个清单的摘要值（请参阅上例中的 `SHA1-Digest-Manifest` 标头）。

在验证签名的 JAR 文件时，将重新计算其每个文件的摘要，并将其与清单中记录的摘要进行比较，以确保 JAR 文件的内容自签名以来未发生更改。作为附加检查，重新计算清单文件本身的摘要值，并与签名文件中记录的值进行比较。

您可以在 JDK™文档的[清单格式](https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#JAR_Manifest)页面上阅读有关签名文件的其他信息。

## 签名块文件

除了签名文件之外，当签署 JAR 文件时，_ 签名块 _ 文件会自动放置在 `META-INF` 目录中。与清单文件或签名文件不同，签名块文件不是人类可读的。

签名块文件包含两个必要的验证元素：

*   使用签名者的私钥生成的 JAR 文件的数字签名
*   包含签名者公钥的证书，供想要验证签名 JAR 文件的任何人使用

签名块文件名通常具有 `.DSA` 扩展名，表示它们是由默认数字签名算法创建的。如果使用与其他标准算法相关联的密钥进行签名，则可以使用其他文件扩展名。

* * *

## 相关文档

有关密钥，证书和证书颁发机构的其他信息，请参阅

*   [JDK 安全工具](https://docs.oracle.com/javase/8/docs/technotes/tools/index.html#security)
*   [X.509 证书](https://docs.oracle.com/javase/8/docs/technotes/guides/security/cert3.html)

有关 Java 平台安全体系结构的更多信息，请参阅此相关文档：

*   [Java SE 中的安全功能](../../security/index.html)
*   [Java SE 安全](http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136007.html)
*   [安全工具](https://docs.oracle.com/javase/8/docs/technotes/tools/index.html#security)