PKI相關知識-002:對原文進行簽名驗籤

需求

需求是通過上次生成的Base64字符串的公私鑰,對原文進行簽名驗籤操作。

代碼

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class SignAndVerify {
    public static void main(String[] args) throws Exception{
        String publicKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh935xAb7re5Nw4z2VcGCDXdQebePxvhfZrqnjeF43CKXwtASM6O9Z3QgwI6qVQbKQCbq4p2i9kE4VgFw+4X4qQT1p+re3/iZ7K6MINaBKRL0JmiZA1cWQ06tji27C5LwRpSHSjSNAU/f1zdl6spkWn9vk6FZBOo8uGLq8Dw8QoI2jb+63nHg5HDy6GGRRBoHl/sOylsWG34FtrF1g7JdYvqPFhJsIBw/xEF3p0OaaOgiahEz0jPj1lpPIp4NhcwDMzXvrVW5hhzcWeZiI1BvgknbTEfMOxKUfO6bA/36YTamS3Wdv00YbuvYXmJo/4S8KEJ5vQmxVugTpk9b7Cj+RQIDAQAB";
        String privateKeyStr = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCH3fnEBvut7k3DjPZVwYINd1B5t4/G+F9muqeN4XjcIpfC0BIzo71ndCDAjqpVBspAJurinaL2QThWAXD7hfipBPWn6t7f+Jnsrowg1oEpEvQmaJkDVxZDTq2OLbsLkvBGlIdKNI0BT9/XN2XqymRaf2+ToVkE6jy4YurwPDxCgjaNv7receDkcPLoYZFEGgeX+w7KWxYbfgW2sXWDsl1i+o8WEmwgHD/EQXenQ5po6CJqETPSM+PWWk8ing2FzAMzNe+tVbmGHNxZ5mIjUG+CSdtMR8w7EpR87psD/fphNqZLdZ2/TRhu69heYmj/hLwoQnm9CbFW6BOmT1vsKP5FAgMBAAECggEAUcwyMvKBU5XE+5ZCOB7oTXMn4B/DT+b4iMCXX7P/L4kkFQVv7+cEgORJU6SQp+AOo9DKWOTO17MsV5tGiid+LUPvIcklpXHmObhcZOi/mhrvIrCWboxfuuYDVzXxBmbQga2qReKdgcy01r1jfpebE2Dlq9vX3D2pkNj82OVq4h7iY7gSy+7Ks8CX3xgrQ8xTPHAE8EdU6h8FUiXS/u5Zel2Hx9eo7ATWVhK/oJ6fNG2BDNw2zDBrbKtTJoRNv4aq1KAv1An57fm5zT2/xIrrkZ590YYVrQSKWgUiOTrX9/ofRACaNb02XljO3ncs5/Fqps6Zdp2cZZ8WEzHP0c4gAQKBgQC8/0kF2+0CYzWZQuebuAPxyZPo+SaY0YX6Yi0X3BhtpQaxk2mRJVt3ByrOpq9pAnadfjFLGTgiILWYOkM99qfIX3qgWApTiB5lptPImAv09nfTUNpJ+LQ/igqVv5gLqM8POrNHHe8zHEat8nYecmQc289dKu3sM1SH41W3oly7BQKBgQC4CMo7u0s15dslHp/jGEltKLK2vJIYEB7FCr0Dg+GdrJIPg0k9XofhRXA2eder+29NuuSpIp33FnTBLE2ZWDJH8BrJsy49jsmtQmNH7tuGMg/NiTWcgOaWxlvYBA3J2Uyn5Si1XpFO0xDWLteppg2bnKLdAQmVXVM15PlqIVMaQQKBgEGQUfW9YJAWeI6NXilwAbZMFoqYfCJBdTfx/PCtArBusk7B87pNelhlXR1JR8qm9x0VnOYPfqCgNj7z30XMnlHthW3AfPyTWPAsmoWY8XTuV40wHDnTFDyCl79xMr7AtevzkiPWp5dUdNR9KyrOxhoYyuvoK5doCygE3kSRB5g9AoGBAIbMEW0M87rnwMuAkfYh/O5SqAxHNO8hJ5iGFAo2GBSIqXdpX0TvL7HmTZnpRvq2sUELCp+ENpYcQaqYi8ItIq8khEqGzvDR3JDmlpfCsdKqan7O6JDYrY10fyNLXNojKw2zQU0PlnlZCfUH3Hlron3/jh84uk9IS0GnlLSS8i7BAoGASnlD04euNIt9ZQQ1Ei/8zTHxME5wN6Im96IT7WpXskMuuy91YF/34KW3oBUdV1tsMco5RhYX8aTrADB3Wny7/Rk07GBWd93HkGnhwkKxCWS96+fOBLCWO7Xa2JQLW9dt6Wm51gOVyDrdGkpql3Cd2+PQOrLpLjxRQMLnpBOBDwY=";

        String origin = "我是一段原文";
        byte[] originBytes = origin.getBytes();

        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr);

        //獲取公鑰和私鑰
        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyBytes);
        PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
        PrivateKey privateKey = keyFactory.generatePrivate(priKeySpec);

        //簽名
        Signature signature = Signature.getInstance("SHA256WithRSA");
        signature.initSign(privateKey);
        signature.update(originBytes);
        byte[] sign = signature.sign();//簽名值

        //驗籤
        signature.initVerify(publicKey);
        signature.update(originBytes);
        boolean result = signature.verify(sign);
        System.out.println("驗簽結果是:" + result);
    }
}
驗簽結果是:true

通過將Base64的公私鑰轉爲對應的PublicKey和PrivateKey來進行簽名驗籤操作。簽名算法爲:SHA256WithRSA

我在寫代碼的過程中,報了這麼兩個錯(在轉爲公私鑰的時候):

  1. Only RSAPublicKeySpec and X509EncodedKeySpec supported for RSA public keys
  2. Only RSAPrivate(Crt)KeySpec and PKCS8EncodedKeySpec supported for RSA private keys

也就是說,公鑰的KeySpec需要用X509EncodedKeySpec,私鑰的KeySpec需要用PKCS8EncodedKeySpec。至於詳情,自行搜索一下。

以上代碼也是可以通過實時生成密鑰對來進行操作,代碼量更少。

發佈了18 篇原創文章 · 獲贊 4 · 訪問量 5385
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章