Java如何创建数字签名和签名数据?

在下面的代码片段中,您将学习如何生成数字签名来对数据或文件进行签名。要创建签名,我们将需要一对公钥和私钥。但是对于签名过程,我们将仅使用私钥。而公钥将用于验证签名。

要创建数字签名,我们需要一个实例java.security.Signature。要得到一个,我们可以调用该Signature.getInstance()方法并传递算法和提供程序参数。在此代码段中,我们将使用SHA1withDSA和SUN作为算法和提供程序。

但是在使用Signature对象之前,我们必须先使用对其进行初始化PrivateKey。您还可以在下面的代码片段中查看如何获取私钥。要初始化,请调用Signature的initSign()方法。

最后,要生成数字签名,我们需要Signature使用将要签名的数据来更新其使用。为此,我们byte[]使用的帮助将文件读入,Files.readAllBytes()并Signature使用update()方法将字节提供给对象。为了获得签名,我们调用sign()方法,该方法将返回一个字节的签名数组。

这是完整的代码片段:

package org.nhooo.example.security;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;

public class GenerateDigitalSignature {
    public static void main(String[] args) {
        try {
            // 获取实例并初始化KeyPairGenerator对象。
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
            keyGen.initialize(1024, random);

            // 从生成的密钥对中获取一个私钥。
            KeyPair keyPair = keyGen.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();

            // 获取Signature对象的实例并对其进行初始化。
            Signature signature = Signature.getInstance("SHA1withDSA", "SUN");
            signature.initSign(privateKey);

            // 将要签名的数据提供给Signature对象
            // 使用update()方法并生成数字
            // 签名。
            byte[] bytes = Files.readAllBytes(Paths.get("README"));
            signature.update(bytes);
            byte[] digitalSignature = signature.sign();

            // 将数字签名和公共密钥保存到文件中。
            Files.write(Paths.get("signature"), digitalSignature);
            Files.write(Paths.get("publickey"), keyPair.getPublic().getEncoded());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在下一个示例中,我们将验证数字签名。验证数字签名是为了确保数据是由原始创建者发送的,未经任何修改。为了验证,我们需要数字签名和密钥对的公钥。为了在上面的代码片段中获得这些信息,我们已经将数字签名和公共密钥都保存到了文件中。