Java实现两种方式 RSA签名, RSA签名校验

通过 .keystore密钥文件实现

生成密钥文件 test2.keystore

  • ./keytool -genkeypair -v -alias test2 -dname “CN=test2,OU=Wenyao,O=RnD,L=Yangpu,ST=Shanghai,C=China” -keyalg RSA -keysize 2048 -keypass 123456 -keystore d:/test2.keystore -storepass 123456 -validity 99999 -storetype JCEKS

import org.springframework.util.Base64Utils;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import static org.springframework.http.converter.FormHttpMessageConverter.DEFAULT_CHARSET;

/**
 * 通过已生成的密钥文件签名类
 * */
public class SignatureByFile {
    /** 密钥路径及文件名称*/
    private String keyStoreFilePath = "D:/test2.keystore";
    /** 密钥库口令*/
    private String keyStorePass = "123456";
    /** 密钥库算法*/
    private String keyStoreType = "JCEKS";
    /** 密钥项别名*/
    private String keyAlias = "test2";
    /** 密钥口令*/
    private String keyPass = "123456";
    /** 签名算法 [SHA256withRSA/SHA1withRSA/MD5withRSA/MD2withRSA]*/
    private String algorithm = "SHA256withRSA";

    /** 获取公钥*/
    public PublicKey getPublicKey(final String keyAlias) throws Exception {
        /** 指定密钥库算法创建实例*/
        final KeyStore ks = KeyStore.getInstance(keyStoreType);
        /** 指定要读取的密钥库文件, 创建文件输入流*/
        final InputStream is = new FileInputStream(keyStoreFilePath);
        /** 载入密钥库文件输入流*/
        ks.load(is, keyStorePass.toCharArray());
        /** 生成证书(X.509标准)*/
        final Certificate cert = ks.getCertificate(keyAlias);
        /** 从证书中获取公钥部分*/
        final PublicKey publicKey = cert.getPublicKey();
        return publicKey;
    }

    /** 获取私钥*/
    public PrivateKey getPrivateKey(final String keyAlias, final String keyAliasPass) throws Exception {
        /** 指定密钥库算法创建实例*/
        final KeyStore ks = KeyStore.getInstance(keyStoreType);
        /** 指定要读取的密钥库文件, 创建文件输入流*/
        final InputStream is = new FileInputStream(keyStoreFilePath);
        /** 载入密钥库文件输入流*/
        ks.load(is, keyStorePass.toCharArray());
        /** 通过别名和密钥口令, 从已载入的密钥库获取私钥*/
        final PrivateKey privateKey = (PrivateKey) ks.getKey(keyAlias, keyAliasPass.toCharArray());
        return privateKey;
    }

    /**
     * RSA签名
     *  @param plainText 源文本
     *  @return 签名
     **/
    public String sign(final String plainText) throws Exception {
        /** 获取私钥*/
        final PrivateKey privateKey = getPrivateKey(keyAlias, keyPass);
        /** 生成签名算法实例*/
        final Signature instance = Signature.getInstance(algorithm);
        instance.initSign(privateKey);
        instance.update(plainText.getBytes(DEFAULT_CHARSET));
        final byte[] signature = instance.sign();
        return Base64Utils.encodeToString(signature);
    }

    /**
     * RSA签名校验
     *  @param plainText 源文本
     *  @param signedText 签名
     *  @return 签名
     **/
    public boolean verify(final String plainText, final String signedText) throws Exception {
        /** 获取公钥*/
        final PublicKey publicKey = getPublicKey(keyAlias);
        /** 生成签名算法实例*/
        final Signature instance = Signature.getInstance(algorithm);
        instance.initVerify(publicKey);
        instance.update(plainText.getBytes(DEFAULT_CHARSET));
        final byte[] signature = Base64Utils.decodeFromString(signedText);
        return instance.verify(signature);
    }

}

相关使用


        final String data = "签名前数据";
        final SignatureByFile signature = new SignatureByFile();
        final String signedData = signature.sign(data);
        final boolean verify = signature.verify(data, signedData);
        System.out.println(signedData);
        System.out.println(verify);

> M5hgiRY30fX7zSo5i+YRpAzpLR0i7dNX1qN8cwN6Sf9JtjoCaVXUywSOz1PC3w311jXtixPMfK3B1+2R7qUlOjTOWPFBiMBqUYy4f0xXLFQw9kMDK/WTtn+nbVezHgqxtBjFNC1/nttmH7PSxhY+SV2KzU+RzC0F2tGhWm0JQQpCZuVQQzVdikJL8NBY8vdqT9SuEpFSX++f2gAQVFyro92ntye/zTbqOFr/qAhXF03CN2jGlvp7ZEbxkxqcMLSHjeTGF0VfzrLgDVpsQdh4qb3dr+tgrs1rgBsVKKiRKmsus4J7YKrjWzcgd/DZAIEozoMnDT/GOonAphRKG6VDMA==
> true

通过密钥生成器实现


import org.springframework.util.Base64Utils;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import static org.springframework.http.converter.FormHttpMessageConverter.DEFAULT_CHARSET;

/**
 * RSA算法签名类
 * */
public class SignatureByRSA {
    /** 签名算法 [SHA256withRSA/SHA1withRSA/MD5withRSA/MD2withRSA]*/
    private String algorithm = "MD5withRSA";
    /** 秘钥对实例*/
    private KeyPair keyPair;

    /**
     * RSA签名校验
     *  @param keyalg 密钥算法 [RSA]
     *  @param keySize 密钥位大小 [1024,2048]
     * */
    public SignatureByRSA(final String keyalg, final int keySize) throws Exception {
        final KeyPairGenerator pairGenerator = KeyPairGenerator.getInstance(keyalg);
        pairGenerator.initialize(keySize);
        /** 生成秘钥对实例*/
        keyPair = pairGenerator.generateKeyPair();
    }

    /** 获得 RSA公钥*/
    public RSAPublicKey getPublicKey() {
        return (RSAPublicKey) keyPair.getPublic();
    }

    /** 获得 RSA私钥*/
    public RSAPrivateKey getPrivateKey() {
        return (RSAPrivateKey) keyPair.getPrivate();
    }

    /**
     * RSA签名
     *  @param plainText 源文本
     *  @return 签名
     **/
    public String sign(final String plainText) throws Exception {
        /** 生成签名算法实例*/
        final Signature instance = Signature.getInstance(algorithm);
        instance.initSign(getPrivateKey());
        instance.update(plainText.getBytes(DEFAULT_CHARSET));
        final byte[] signature = instance.sign();
        return Base64Utils.encodeToString(signature);
    }

    /**
     * RSA签名校验
     *  @param plainText 源文本
     *  @param signedText 签名
     *  @return 签名
     **/
    public boolean verify(final String plainText, final String signedText) throws Exception {
        /** 生成签名算法实例*/
        final Signature instance = Signature.getInstance(algorithm);
        instance.initVerify(getPublicKey());
        instance.update(plainText.getBytes(DEFAULT_CHARSET));
        final byte[] signature = Base64Utils.decodeFromString(signedText);
        return instance.verify(signature);
    }

}

Byte数据转换成 Hex字符串


    public static String convertBytes2HexString(final byte[] data) {
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length; i++) {
            String s = Integer.toHexString(0xFF & data[i]);
            if (s.length() == 1){
                sb.append(0).append(s);
            }else {
                sb.append(s);
            }
        }
        return sb.toString();
    }
    

相关使用


        final String data = "签名前数据";
        final SignatureByRSA signature = new SignatureByRSA("RSA", 2048);
        final String signedData = signature.sign(data);
        final boolean verify = signature.verify(data, signedData);
        System.out.println(convertBytes2HexString(signature.getPublicKey().getEncoded()));
        System.out.println(convertBytes2HexString(signature.getPrivateKey().getEncoded()));
        System.out.println(signedData);
        System.out.println(verify);

> 30820122300d06092a864886f70d01010105000382010f003082010a0282010100a0830541f5d36f87f02b2b5b4da4717fc6a6f6466f73ac6df0a6f5ac58494632f4ca6b524c96a8086e4d92fa2db90f8b74a98e4d647530974c5bb050b7eb103b3f60a29a98511ed8c14a58ca2caffa20be79f961a91daabf6311f58a9c3cf4df065b6943eea139c41fd982fca0172f6e0500d0a0fae1ec9891d488d78fb476b09aa278f2128f6cf41d0548af9057a967bf0f91405de2564221129d1a7b56ac8c6366fa507166a5549fd80c5297bb9f73add9ff2fe4d91e9c2fb0c7119762ed0f1441d1786340b8550760a9f8a752bc134754432c2ded1f6cfd8ae2a3b8a6f6febac7fbbd8201c668cdbacbde740f61fd3d3bb56c359a4e68b17054074f23d8670203010001
> 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100a0830541f5d36f87f02b2b5b4da4717fc6a6f6466f73ac6df0a6f5ac58494632f4ca6b524c96a8086e4d92fa2db90f8b74a98e4d647530974c5bb050b7eb103b3f60a29a98511ed8c14a58ca2caffa20be79f961a91daabf6311f58a9c3cf4df065b6943eea139c41fd982fca0172f6e0500d0a0fae1ec9891d488d78fb476b09aa278f2128f6cf41d0548af9057a967bf0f91405de2564221129d1a7b56ac8c6366fa507166a5549fd80c5297bb9f73add9ff2fe4d91e9c2fb0c7119762ed0f1441d1786340b8550760a9f8a752bc134754432c2ded1f6cfd8ae2a3b8a6f6febac7fbbd8201c668cdbacbde740f61fd3d3bb56c359a4e68b17054074f23d86702030100010282010021f5d6a4f007fe2efac78772d7e89502fddad17c71943dc53d07762f32b6be1d85e155f7a1b0b678a22dd38d0f237a807cfc6ad94109f26ff07dedbe064bbbb16d655ac1eebc2b149d40c7ac6eec04b5ecd70dc675eb8af6d7553368524a2b5d0c9146a252d8d5ca031b1835af0178cd844d79d6b57e1b7ae44fdd6c0e419662ccc1d12d019e0ca5c89b336e06a316807bdf0fd490587ed2064456c4052179b896a1943be20c3badb49670a296672b70016c1a5cae9ab09caf46a4c189cb2ceb951347ff014f865fe027e529b9f3be6768fda01c0cb969e341302b64d6bab1f06e433cbd044d92e3c1a2d29209679964ce0d9effb7a845e660631c937b060a9102818100e5b60a8d6b16f7710eb8685096c19614feedcb81ea5923025c160b7d34decc4f67310185d813d23911bc96b9b53b2f8cf2ed82d31063e718649a760f41d6e42868e57545821c1734af883e010cf297247b114ec37bc06ef002943acbda9cc97fa57e6151d594b399dd31da14cf962ce713ff3c5fe4b7b03019fa5a3e0dcb3de502818100b2e19d0d0dc512bdb4d02e390d48960b8d7146f36f6aefeced4d4478c22d03769e4ece695ede8da73332125c74e0557a735c850ff8b15850cd5a1c211e8d7fa32bbb885b0792732108f0f3d21a8d2f9ea52d09b879a70c0cac075f3184c39a1bc9db2dee41ec841b2e010ea5a425da6db8595d969660c2f30519a553fd43f85b0281806cccf168941d77abcbfe1a2279954d81ba51653fae80f3ad0d72bf94593361f005ff572a4ef2ec726d6d36b2d51d2863893867eb926acf2d65912774088a40dcc6fa4fb6516efeaaccad2a391329dfdebe8faf0fb610aa3af1edc57f82971a75642c5cea06d07cd4d6c8e2f352735de74138761f3154b395c4e8285015f67ae50281810098724611d5e659ee6aa5f07e969f81a01ecea714d7a35f0d9fbef5d7a444106b8ac6c68a6e5b648555d01a6dc8fd565ba0ecfc497c3c4773b54e5222b793076fdbd95a7f9998699d81ad375d9b5b2f761876a58e1dbf0b39d17206e280aee22b44801248b6ce0657d380fb269719db691e6eaa9fa7509753dcc8da6915b253790281800f5db934ef6397c6081583ba35732fd8808fd9d955debbb3cfd013dde14c4bdef29dbe8577c865f7c6fb2696c55a44edef90a89b6c35969154376898dd120224218885070fb26d300837c34335052723cf44ab3d609f8ccc7430eb1e1e6e44028aa26d334c48ba426cef2cb1f78125fbe681e62f27dba8544cd9c9b2d838bef9
hoJghoDi0WDNDcmsEyED1LNoaRTnZRD439v8tBlUimeKuBezrVH7fS7iTqyyCgBc+X6cdgk4pMo7eIMEBt+JwqBlKhjpdJZXQUHSbZQG7D+MGSXk9Ip5/FCIf3Y2NBc3Y5dHiqYVy0vQ5QClj8QK0l8hPZKUuvXSHHWNo72tF7OHkqdy/gysmVRbul3Kyt/QqA7CVU4d9IkNOoePlvqYcZeAdx2yIDisS0jR+RnsrKM2UuRrRJRMaPpRcxtYz/tqnvr/x4ZeUvLT85XZZAf9pL/Me2XwmN3D5i7tyuKKG/bftMS65YOyNvFD0Kytd9fAoOaeMVilfos9R4C3rjSh1w==
> true

如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!

发布了62 篇原创文章 · 获赞 325 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qcl108/article/details/103081219