📜  密码学中数字签名的Java实现

📅  最后修改于: 2022-05-13 01:58:09.313000             🧑  作者: Mango

密码学中数字签名的Java实现

数字签名是数字消息(数据)的非对称加密哈希。它是一个可以提供真实性、不可否认性和完整性保证的值。换句话说,这意味着您可以验证发件人、日期和时间以及消息内容是否被泄露或泄露。

注意:您可以参考此链接以更好地理解加密术语。

数字签名的计算

数字签名通常使用椭圆曲线加密计算,尤其是在物联网设备中,但我们将使用 RSA 进行演示。首先,由于其速度和安全性,我们将获取输入消息并使用 SHA-256 创建它的散列,然后我们将使用来自非对称密钥对的私钥加密该散列。另一方面,接收者将使用公钥对其进行解密并比较哈希以确保它们确实相同。

数字签名流程

  • 让“A”和“B”成为密码系统中的虚构角色,以便更好地理解。
  • “A”是发送者,计算消息的哈希值并附加他想要使用他的私钥发送的签名。
  • 另一方“B”对消息进行哈希处理,然后用 A 的公钥解密签名并比较两个哈希值
  • 如果“B”找到匹配的哈希,则消息没有被更改或泄露。

实施数字签名

让我们使用算法 SHA 和 RSA 实现数字签名,并验证哈希是否与公钥匹配。

方法:

  • 创建一个名为 Create_Digital_Signature() 的方法,通过传递两个参数输入消息和私钥来实现数字签名。在这个方法中,我们将获取一个传递签名算法的签名对象的实例,并为其分配一个私钥,最后传递输入,这将返回字节数组。
    public static byte[] Create_Digital_Signature(byte[] input, PrivateKey privateKey);
    signature.initSign(privateKey);
    signature.update(input);
    
  • 下一步是使用 RSA 算法和 SecureRandom 类函数生成非对称密钥对。
    SecureRandom secureRandom =new SecureRandom();
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
    
  • 最后使用公钥验证签名。 Verify_Digital_Signature() 方法用于通过向其传递输入、签名和公钥来检查签名是否匹配。
    Signature signature = Signature.getInstance(SIGNING_ALGORITHM);
            signature.initVerify(publickey);
            signature.update(input);

例子:

下面是实现:

// Java implementation for Generating
// and verifying the digital signature
  
package java_cryptography;
  
// Imports
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.util.Scanner;
  
import javax.xml.bind.DatatypeConverter;
  
public class Digital_Signature_GeeksforGeeks {
  
    // Signing Algorithm
    private static final String
        SIGNING_ALGORITHM
        = "SHA256withRSA";
    private static final String RSA = "RSA";
    private static Scanner sc;
  
    // Function to implement Digital signature
    // using SHA256 and RSA algorithm
    // by passing private key.
    public static byte[] Create_Digital_Signature(
        byte[] input,
        PrivateKey Key)
        throws Exception
    {
        Signature signature
            = Signature.getInstance(
                SIGNING_ALGORITHM);
        signature.initSign(Key);
        signature.update(input);
        return signature.sign();
    }
  
    // Generating the asymmetric key pair
    // using SecureRandom class
    // functions and RSA algorithm.
    public static KeyPair Generate_RSA_KeyPair()
        throws Exception
    {
        SecureRandom secureRandom
            = new SecureRandom();
        KeyPairGenerator keyPairGenerator
            = KeyPairGenerator
                  .getInstance(RSA);
        keyPairGenerator
            .initialize(
                2048, secureRandom);
        return keyPairGenerator
            .generateKeyPair();
    }
  
    // Function for Verification of the
    // digital signature by using the public key
    public static boolean
    Verify_Digital_Signature(
        byte[] input,
        byte[] signatureToVerify,
        PublicKey key)
        throws Exception
    {
        Signature signature
            = Signature.getInstance(
                SIGNING_ALGORITHM);
        signature.initVerify(key);
        signature.update(input);
        return signature
            .verify(signatureToVerify);
    }
  
    // Driver Code
    public static void main(String args[])
        throws Exception
    {
  
        String input
            = "GEEKSFORGEEKS IS A"
              + " COMPUTER SCIENCE PORTAL";
        KeyPair keyPair
            = Generate_RSA_KeyPair();
  
        // Function Call
        byte[] signature
            = Create_Digital_Signature(
                input.getBytes(),
                keyPair.getPrivate());
  
        System.out.println(
            "Signature Value:\n "
            + DatatypeConverter
                  .printHexBinary(signature));
  
        System.out.println(
            "Verification: "
            + Verify_Digital_Signature(
                  input.getBytes(),
                  signature, keyPair.getPublic()));
    }
}

输出: