RSA-公钥加密,私钥解密 、私钥加密,公钥解密、私钥加签,公钥验签

版权声明:转发请注明,谢谢配合 https://blog.csdn.net/qq_31289187/article/details/85234044

一、案例内容:

RSA 公钥加密,私钥解密;
RSA 私钥加密,公钥解密;
RSA 私钥加签,公钥验签(SHA1WithRSA或者SHA256WithRSA-数字签名)

二、引入的jar包

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
        <dependency>
            <!-- Base64编码 -->
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.11</version>
</dependency>

三、案例代码

package com.cn.dl;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * 1、RSA 公钥加密,私钥解密
 * 2、RSA 私钥加密,公钥解密
 * 3、RSA 私钥加签,公钥验签(SHA1WithRSA或者SHA256WithRSA-数字签名)
 *
 * Created by yanshao on 2018/12/12.
 */
public class NewRSAUtils {

    //加密算法
    private static final String  SHA256WithRSA = "SHA256WithRSA";
    //public static final String  SIGN_ALGORITHMS = "SHA1WithRSA";
    private static final String   RSA = "RSA";

    //编码
    private static final String CHARSET_UTF_8 = "utf-8";

    //私钥
    private static final String privateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCqrpUHZx/NSRsK" +
            "jQc9i/gCGzU9Q3qRf44pm0lML9FfJf+m9mo9qdAEsMl3N0Y/nVcdGWb8VBry+dyl" +
            "mKNR4VPfFNGQKWW8OtvUlT9l3I9/MTd/ZsoVt2dQdBvOp7+9hrClS+rmw/HFz81l" +
            "RCFcku8HIIIcFxPQylRgSxHI8PMVJEodBsQSRvOzGtzWTfhTfG0Y0sgZPt75hKjd" +
            "J1rTo4264AG3YzlxHlmqrrQxxmYEKEnNplmNVga2bXvPICZ2VPbl9w/52mlSobg3" +
            "6VPKMzdlhTUgFsADPMaG2Pf3GqOa2GTSupzgTyz/54LyF6gCbXcAknRFgH5eyAv5" +
            "tPqV9CsrAgMBAAECggEAAXIHCxABgfCLjRRSql/EEuh+E+29XPwSjSGmhkGlaUPe" +
            "HWDa13jXrSJ+IkdSjflcIn/zklF4BPS+vJxFTc01s57ug2UGWoi5EdzNs6Qhhvc4" +
            "vBh3v6VU96Z0EdTz17wLROsWqyufoYg3+hKQocMQySOqVmiPn2YHPuWD2grIVDZ9" +
            "68mC1FykGEcv9De0m6yVEsfZDXNUxm3cz1758iBqakvyOVxGsI+V+e7/iSxJiwIB" +
            "6f3NSGQVtEsqwyhnl6dZRYDtnq5iUiwUOshl5Z2CYBfBcyTpMKC2RuHp3u9THHpc" +
            "3TFE4I1Li5HkiFy+ai6QKl2M85ce3GCXmjyw7n2vmQKBgQDTHihNX6uu6YlVFcRa" +
            "XhhGigyLrIP8LbLd4r/dKMXuGa8XqkLPlDtXelh2n565Lo5DPGlpANi3Jp495Hzn" +
            "bL+YnHJs7boVOGtORB0XHUbiMaTlT85snpvVjwFngHvY/ZxtXclpsnX563AvzCyl" +
            "amrKEhV17BFZbRQOTEL1UNp57QKBgQDO98AyfVgs1tCdtLOsFSFiWrAsJJimBS7b" +
            "ec+W/UPGDAl3hFzQzJ2SUvF4EneatYVOEDdHLUzVnT7XXeA/eMZL56N8BTSffh8q" +
            "XK0E21K8tW4hRbze6CIjbsJ1x7ZLZaoM4Ub2YAvkulF0PcasX0kWl+bv/DnkI09x" +
            "/n3vgbO2dwKBgQCoAnj6UmeztEDJiKARdo6FHHmtciY7Ozb8Y+Zin38c5C22fJXc" +
            "0k+DZ2cdSBwtrQIkOeB9YuIUp1QJV1ubZKz5S4+4ZlvPZW3oBEbOTUtK2U0r/J3/" +
            "TR4hD0SD1Pk6j2G8m4Wdaxt+P8KxFyB0p8LCey++/5Yy/56VXlVvGuAzZQKBgQCU" +
            "VfcXeMTIplGwpkGcFSzvLCZWDQim/NH/lYdWJUD84cWrNl+7ett4cyADueClLnJT" +
            "Z8Xmqq4F8ASJIQxHEY21+1gt3CFCKoe1ueR7taHQBIzhJfVfIarOEGUpOzEJSt0d" +
            "DBzrGh2MGomksV4CTuy4V7i5yeHIBBK9lfO2xBQEswKBgQCIzYO53kTFl6YGjmWO" +
            "qUJsT+5WegR4GdxtqYpQGPC1RmU7ig1TZzen+X3xB+lIHqgA1HvTr6M+tPkmnMwU" +
            "iARPOgjXY0zmsStXaHQYKruT3EjZRs2GnmVpVOAj1asqi+/2t0NgLgB5gPLYMXS+" +
            "BGf01OehvUt5Ge+OChDBXSW5Bw==";

    //公钥
    private static final String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqq6VB2cfzUkbCo0HPYv4" +
            "Ahs1PUN6kX+OKZtJTC/RXyX/pvZqPanQBLDJdzdGP51XHRlm/FQa8vncpZijUeFT" +
            "3xTRkCllvDrb1JU/ZdyPfzE3f2bKFbdnUHQbzqe/vYawpUvq5sPxxc/NZUQhXJLv" +
            "ByCCHBcT0MpUYEsRyPDzFSRKHQbEEkbzsxrc1k34U3xtGNLIGT7e+YSo3Sda06ON" +
            "uuABt2M5cR5Zqq60McZmBChJzaZZjVYGtm17zyAmdlT25fcP+dppUqG4N+lTyjM3" +
            "ZYU1IBbAAzzGhtj39xqjmthk0rqc4E8s/+eC8heoAm13AJJ0RYB+XsgL+bT6lfQr" +
            "KwIDAQAB";

    /**
     * 生成公私钥对
     * @return String[0]:公钥,String[1]:私钥
     */
    public static String[] generateKeyPair()
    {
        KeyPairGenerator keyPairGenerator = null;
        try
        {
            keyPairGenerator = keyPairGenerator.getInstance(RSA);
            keyPairGenerator.initialize(1024, new SecureRandom());
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            return new String[]{new Base64().encodeToString(publicKey.getEncoded()),
                     new Base64().encodeToString(privateKey.getEncoded())};
        }
        catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 使用私钥给入参签名
     * @param privateKey 私钥
     * @param param      签名的数据
     * @return            返回入参签名16进制字符串
     * */
    public static String sign(String privateKey, String param) {
        try {
            //获取privatekey
            byte[] privateKeyByte = new Base64().decode(privateKey);
            KeyFactory keyfactory = KeyFactory.getInstance(RSA);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyByte);
            PrivateKey key = keyfactory.generatePrivate(pkcs8EncodedKeySpec);

            //用私钥给入参加签
            Signature sign = Signature.getInstance(SHA256WithRSA);
            sign.initSign(key);
            sign.update(param.getBytes());

            byte[] signature = sign.sign();
            //将签名的入参转换成16进制字符串
            return bytesToHexStr(signature);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 用公钥验证签名
     * @param param       入参
     * @param signature   使用私钥签名的入参字符串
     * @param publicKey   公钥
     * @return             返回验证结果
     * */

    public static boolean verifySign(String param,String signature,String publicKey){
        try {
            //获取公钥
            KeyFactory keyFactory = KeyFactory.getInstance(RSA);
            byte[] publicKeyByte = new Base64().decode(publicKey);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyByte);
            PublicKey key= keyFactory.generatePublic(x509EncodedKeySpec);

            //用获取到的公钥对   入参中未加签参数param 与  入参中的加签之后的参数signature 进行验签
            Signature sign=Signature.getInstance(SHA256WithRSA);
            sign.initVerify(key);
            sign.update(param.getBytes());

            //将16进制码转成字符数组
            byte[] hexByte = hexStrToBytes(signature);
            //验证签名
            return sign.verify(hexByte);

        }  catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 使用公钥加密
     * @param publicKey  公钥
     * @param param      私钥
     * @return  加密后的字符串
     * */
    public static String RSAPublicEncrypt(String publicKey, String param) throws Exception {

        try {
            byte[] publicKeyByte = new Base64().decode(publicKey);
            KeyFactory keyfactory = KeyFactory.getInstance(RSA);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyByte);
            RSAPublicKey key = (RSAPublicKey)keyfactory.generatePublic(x509EncodedKeySpec);
            // 使用默认RSA
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.ENCRYPT_MODE,key);
            byte[] output = cipher.doFinal(param.getBytes(CHARSET_UTF_8));
            return bytesToHexStr(output);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 使用私钥解密
     * @param privateKey  私钥
     * @param encryptParam  公钥加密的字符串
     * @return  解密后的字符串
     * */
    public static String RSAPrivateDecrypt(String privateKey,String encryptParam) throws Exception {

        Cipher cipher = null;
        try {
            // 使用默认RSA
            byte[] privateKeyByte = new Base64().decode(privateKey);
            KeyFactory keyfactory = KeyFactory.getInstance(RSA);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyByte);
            RSAPrivateKey key = (RSAPrivateKey)keyfactory.generatePrivate(pkcs8EncodedKeySpec);

            cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] output = cipher.doFinal(hexStrToBytes(encryptParam));
            return new String(output);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 私钥加密,公钥解密
     * @param privateKey   私钥
     * @param param         需要加密的数据
     * @return 返回加密后的数据
     * */
    public static String RSAPrivateEncrypt(String privateKey, String param){
        try{

            // 使用默认RSA
            byte[] privateKeyByte = new Base64().decode(privateKey);
            KeyFactory keyfactory = KeyFactory.getInstance(RSA);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyByte);
            RSAPrivateKey key = (RSAPrivateKey)keyfactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] output = cipher.doFinal(param.getBytes(CHARSET_UTF_8));
            return bytesToHexStr(output);

        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 私钥加密,公钥解密
     * @param publicKey    公钥
     * @param encryptParam   需要解密的数据
     * @return  返回解密后的数据
     * */
    public static String RSAPublicDecrypt(String publicKey, String encryptParam){
        try{
            byte[] publicKeyByte = new Base64().decode(publicKey);
            KeyFactory keyfactory = KeyFactory.getInstance(RSA);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyByte);
            RSAPublicKey key = (RSAPublicKey)keyfactory.generatePublic(x509EncodedKeySpec);
            // 使用默认RSA
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.DECRYPT_MODE,key);
            byte[] output = cipher.doFinal(hexStrToBytes(encryptParam));
            return new String(output);
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }


    /**
     * byte数组转换成十六进制字符串
     * @param bytes byte数组
     * @return      返回十六进制字符串
     */
    private static String bytesToHexStr(byte[] bytes) {
        StringBuffer stringBuffer = new StringBuffer("");
        for (int i = 0; i < bytes.length; ++i) {
            stringBuffer.append(Integer.toHexString(0x0100 + (bytes[i] & 0x00FF)).substring(1).toUpperCase());
        }
        return stringBuffer.toString();
    }

    /**
     * 十六进制字符串转成byte数组
     * @param hexStr   十六进制字符串
     * @return          返回byte数组
     * */
    private static byte[] hexStrToBytes(String hexStr) {
        byte[] bytes = new byte[hexStr.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(hexStr.substring(2 * i, 2 * i + 2), 16);
        }
        return bytes;
    }

    public static void main(String[] args) throws Exception{

        String[] keyPair = generateKeyPair();
        System.out.println("公钥>>"+keyPair[0]);
        System.out.println("私钥>>"+keyPair[1]);

        JSONObject json = new JSONObject();
        json.put("name","yanshao");
        json.put("ab","ab");
        json.put("age",25);
        json.put("address","武汉");
        String params = json.toJSONString();
        System.out.println("入参>>>"+params);
        String sign = sign(keyPair[1],params);
        System.out.println("签名后的参数>>>"+sign);
        System.out.println("验证结果>>>"+verifySign(params,sign,keyPair[0]));


        String encrypt = RSAPublicEncrypt(keyPair[0],params);
        System.out.println("公钥加密>>>"+encrypt);
        System.out.println("私钥解密>>>"+RSAPrivateDecrypt(keyPair[1],encrypt));


        String encrypt1 = RSAPrivateEncrypt(keyPair[1],params);
        System.out.println("私钥加密>>>"+encrypt1);
        System.out.println("公钥解密>>>"+RSAPublicDecrypt(keyPair[0],encrypt1));


    }

}

四、运行结果

公钥>>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9SZS0czkGetJU/+JcoVIyt3T0HYbk/s7E2kdReyEBdU06s8SPwSFIcn9D+zh2rEvzDylAYBpWIHfIWJhqkz53qxKH2GqkVrY2SipYQiVyH673mH7zmeYQWUZLW1AaAPZj+0ZJf8l82/P6c3zV1D/rgQHQDFaXS3xMwyah+KrjVQIDAQAB
私钥>>MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAL1JlLRzOQZ60lT/4lyhUjK3dPQdhuT+zsTaR1F7IQF1TTqzxI/BIUhyf0P7OHasS/MPKUBgGlYgd8hYmGqTPnerEofYaqRWtjZKKlhCJXIfrveYfvOZ5hBZRktbUBoA9mP7Rkl/yXzb8/pzfNXUP+uBAdAMVpdLfEzDJqH4quNVAgMBAAECgYEAitUhIIkyVjJXesiDenVIGLK+MR5HBkZt2axPis/IkY07q8aWcOmyQ7TW60GjVEdjHU8Nbo4OQwVlVajFgcWlllHDaXrdh1cdzR0FTpxQV+dSr/U9UyLRmuSK2q/yavn4Zp9OVvoC7jPSe/J8lEwGIo6MSGD2JwGQFyAK4l5dcLECQQD+Ccb/R15RJUqRAbwMUtFDci1l2dwR/vte95RAIybWjxZ9AxHGvlqHLX40nxWWUc9SELawdxnZJYiPLdBqRuOPAkEAvr/LRkzo0Sd9gczWkn8/JP7HuiBJOvkYZWkSRMvKuu1smO3SjWIXqjf37S/nAqxP7NKvEiEamf0pZG0JJppI2wJBANR+EzGHXhJcMhI3NDfOsnJLOEQgxp9a/KLETwKTJLKGP9ZT0fO/V/QIjq+vfhwd1GAd0OKszTdA2QiC1vl+0GsCQCa9UQ1gBVClEopQDawHB839qJaWhAjkGh5ObpVmRjAclBejBUYNi/zYDRQwzFvwnvLb/w5RhtOLZOKuelNKtk0CQQDwd7ZSgGdo57Vf+LE8q/A3tW6QaobLK8A/wBG+hJuT9oS5pdIyl9BrbVR9srpedaDUK9QDkUaL+BhN4rzV/Iei
入参>>>{"ab":"ab","address":"武汉","name":"yanshao","age":25}
签名后的参数>>>585E4FBBAF8D33D19E9CE8F7FBC9EC37C6E840BB0D1637FA84231A0D3B12942ADB768AEA15A2ADF5563C4400490254BB7F559B2B57B658C4421F408254E1F2BD759860FCED241C619FE86AE9403C5B1956AE232A1BF3B160A8D975349288421A4EB86B4AB975CE2A5788E3AA57B24E7811CFC3D8ED93BF6E8C2F3E4E599CA543
验证结果>>>true
公钥加密>>>8CB761651490298D0EBB68A78238A758E0DDC4D21CB289BF0268B50388033B2F1A1A7BB04B32BE3FD2A2911AC5C8E5EFE87340888DF193BBF17DAF67EC8D08BA24CB08C4C3086B4AEAE978E3349A1F454E87BF067101D596E77D148D2E6B092C256631D20C5D1AEA077E7765578DCC874CDC8CFC2051255009A613F159C22BB8
私钥解密>>>{"ab":"ab","address":"武汉","name":"yanshao","age":25}
私钥加密>>>360DF16454327F526FDD5B657FDBA8F2EF29210CA7797C3AD0C420A712871CD974A7ACC027009C3BF819E16344FD8EF8465D2C778A9DC8B1F839F0B60B818CC465A073A29121B736E9DFB5F82786BA1EE14155FEE9CC9145C07AC6795DF6590CA5746324DC63660560E8EA32C0722698DAD58E9BB555DBDBE961D5BBA4C93CA3
公钥解密>>>{"ab":"ab","address":"武汉","name":"yanshao","age":25}

注意:

1、
案例中的privateKeypublicKey是通过openssl生成的,可以直接用 

(参考文章:https://blog.csdn.net/qq_31289187/article/details/84973338);

2、本案例有专门生成公私钥对的方法,案例中使用了(commons-codec) 这个jar包,使用JDK8自带的base64编解码也可以。

猜你喜欢

转载自blog.csdn.net/qq_31289187/article/details/85234044