數字簽名與驗籤

前言


  • 數字簽名(又稱公鑰數字簽名)是隻有發送方纔能產生的無法僞造的數字串,是對發送者發送信息真實性的有效證明。
  • 數字簽名主要是保證數據有效性(驗證是誰發的)和完整性(驗證信息是否被篡改)。
  • 數字簽名是非對稱加密和數字摘要技術的應用。

數字簽名流程


A爲客戶端,C爲服務端;

A寫郵件給C過程:

  • A用公鑰對郵件加密,C收到郵件後用私鑰進行解密;

C寫郵件給A過程:

  • C寫好郵件,用hash函數生成郵件的摘要,將摘要附在郵件上面,這就完成了數字簽名,然後,C再使用私鑰加密,最後發送給A;
  • A收到郵件後,先把數字簽名取下來,然後用公鑰解密,若取下的數字簽名中的摘要和A的一樣,則可判斷數據是C發送的。再對郵件使用hash函數,將得到的結果與上一步得到的摘要對比,若兩者一致,則可判斷數據沒有被篡改過;

數字證書


數字證書(CA)是一個權威的證書籤發機構。

爲了防止公鑰被盜竊,安全起見,服務期端C將自己的公鑰去證書中心做個認證,過程時CA證書中心會將它的私鑰對服務端C的公鑰和一些相關信息一起加密,生成數字證書;

  • 服務端C拿到數字證書後,在簽名的同時,將數字證書一起發給客戶端A;
  • A收到郵件後,用數字證書CA的公鑰解開數字證書,就可以拿到服務端C的公鑰,這樣就可以判斷數字簽名是否是服務端A的;

簽名與驗籤代碼實現


package com.cao.cipher.signature;

import com.cao.cipher.rsa.RsaDemo03;
import org.apache.tomcat.util.codec.binary.Base64;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;

/**
 * @author:秋一葉
 * @date:2020-11-18 17:59
 * 數字簽名,驗籤
 */
public class SignatureDemo {
   
       
    public static void main(String[] args) throws Exception{
   
       
        String input = "原文";
        //獲取私鑰,公鑰
        //RsaDemo03類在上一篇博客中:https://blog.csdn.net/qq_36335426/article/details/110480569
        PrivateKey privateKey = RsaDemo03.getPrivateKey("a.pri", "RSA");
        PublicKey publicKey = RsaDemo03.getPublicKey("a.pub", "RSA");
        //簽名
        String signaturedData = getSignature(input, "sha256withrsa", privateKey);
        System.out.println("生成簽名後:" + signaturedData);
        //驗籤
        boolean b = verifySignature(input, "sha256withrsa", publicKey, signaturedData);
        System.out.println("驗簽結果:" + b);

    }

    /**
     * 生成簽名
     * @param input 原文
     * @param algorithm 加密算法
     * @param privateKey    私鑰
     * @return
     * @throws Exception
     */
    private static String getSignature(String input, String algorithm, PrivateKey privateKey) throws Exception{
   
       
        //獲取簽名對象
        Signature signature = Signature.getInstance(algorithm);
        //初始化簽名
        signature.initSign(privateKey);
        //傳入原文
        signature.update(input.getBytes());
        //開始簽名
        byte[] sign = signature.sign();
        //對簽名進行Base64編碼
        return Base64.encodeBase64String(sign);
    }

    /**
     * 校驗簽名
     * @param input
     * @param algorithm
     * @param publicKey
     * @param signaturedData
     * @return
     * @throws Exception
     */
    private static boolean verifySignature(String input, String algorithm, PublicKey publicKey, String signaturedData) throws Exception{
   
       
        //獲取簽名對象
        Signature signature = Signature.getInstance(algorithm);
        //初始化簽名
        signature.initVerify(publicKey);
        //傳入原文
        signature.update(input.getBytes());
        //校驗數據
        return signature.verify(Base64.decodeBase64(signaturedData));
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章