对加密-加签的完整流程

时间:2022-07-22
本文章向大家介绍对加密-加签的完整流程,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.架构图

2.实例代码

package com.shi.encrypt.ascii;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.crypto.Cipher;
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;

/**
 * 校验完整的
 * 加密-加签-验签-解密
 * 的完整流程
 *
 * @author shiye
 * @create 2020-07-28 18:06
 */
public class CheckSignDemo {
    //加密算法
    private static String algorithm = "RSA";
    //私钥
    private static String privateKeyStr = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKdzMj8aAS28BIH6qGIB7+O0z6bun" +
            "ujjYJlBhFbtt+Ai9Mm90+rQq7cnc0g7FGAGsBvtfoF+BEKLUNMl6LkGsXM8Sz42P+UWQGslhWYqWn" +
            "Wo4f7PyCVNlLEcsRgt43JnFQ1yUbtttMKHs8whYcAgFaIyEdGw4h8aGffEVA0VxkshCHAgMBAAECn" +
            "gYBOyOmEPQT+8q6gRUJCUqz+0wy8eygNJM3qFbO26we/fN0lCcIHUQduacI/hsZDyx/B1/1J0hz0n" +
            "r6lifmUTKzjCxKvxpvQFa0iM3njqNX/z+tOpK9RX+awIW7syACbZG4ZCwCPSflB/3uoBYHT4oY5/n" +
            "WumWX1Berb8WUU1jHZ8SYQJBAOsbXsh4IubAdzmerYoKh5RWEwxF6nHd58XRQq6DnKWvRN/LNUsFn" +
            "fTDodFkhpC2VFSMxaNSelboYRvXON59rWzECQQC2VKVgu8moqfrS11fEwQ6Iq4sG+mt08/GT2BUZn" +
            "yz5z6vXCK+cTjRf4hgR4oGC01/ZlL8OhiUsgA8cprmHoiMk3AkA5/1N/cptxfxMqRKmcvwI5Jo6mn" +
            "XWz7T/mIBBpGALOY78a2ymNIMX9znDRvdGwSzo8bUmoA4WogMTL4GjoAerRRAkAksXI6vm/97n9Yn" +
            "0ReLtCJ9pLAs7laTycgTLchJUZq271EYC4fManepfycFM5liq5edk3g2WQ/yWHBLVhnEF0sPAkA7n" +
            "B/cOKB4Z0HkUSMEL0P8OT7N/afZMzv/KjpTAMKUfrgNptSTG5y2TcGEv4Bktj/+4SAegnVKF98oMn" +
            "+Vh4i9lw";
    //公钥
    private static String publiceKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnczI/GgEtvASB+qhiAe/jtM+m7ro42CZQYRW7n" +
            "bfgIvTJvdPq0Ku3J3NIOxRgBrAb7X6BfgRCi1DTJei5BrFzPEs+Nj/lFkBrJYVmKllqOH+z8glTZn" +
            "SxHLEYLeNyZxUNclG7bbTCh7PMIWHAIBWiMhHRsOIfGhn3xFQNFcZLIQhwIDAQAB";

    public static void main(String[] args) throws Exception {
        User user = new User("张三", 10, "男");
        //原文
        String input = JSONArray.toJSON(user).toString();
        System.out.println("原文:" + input);

        //1 先进行加密
        String encryption = encryption(input);
        System.out.println("密文:" + encryption);

        //2 对密文进行加签
        String sign = sign(encryption);
        System.out.println("sign:" + sign);

        //3 验签 (encryption:原文,sign:签名)
        boolean checkSign = checkSign(encryption, sign);
        System.out.println("验签的结果为:" + checkSign);

        //4 解密
        String decrypt = decrypt(encryption);
        System.out.println("解密后的结果:" + decrypt);

        User parseObject = JSONObject.parseObject(decrypt, User.class);
        System.out.println(parseObject.toString());
    }

    /**
     * 1 先进行加密
     *
     * @param input 需要进行加密的数据
     * @return
     * @throws Exception
     */
    public static String encryption(String input) throws Exception {
        //创建key工厂
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        /*===========================生成私钥对象===========================*/
        //私钥规则
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyStr));
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] doFinal = cipher.doFinal(input.getBytes());
        String encode = Base64.encode(doFinal);
        //返回密文
        return encode;
    }

    /**
     * 2 再进行加签
     *
     * @param input 需要加签的数据
     * @return
     * @throws Exception
     */
    public static String sign(String input) throws Exception {
        //创建key工厂
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        /*===========================生成私钥对象===========================*/
        //私钥规则
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyStr));
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

        //获取签名对象
        Signature signature = Signature.getInstance("sha256withrsa");
        //初始化签名
        signature.initSign(privateKey);
        //传入原文
        signature.update(input.getBytes());
        //开始签名
        byte[] sign = signature.sign();
        String encode_sign = Base64.encode(sign);
//        System.out.println("生成的签名为=" + encode_sign);
        return encode_sign;
    }


    /**
     * 3 验签
     *
     * @param input 原文
     * @param sign  传过来的签名
     * @return
     * @throws Exception
     */
    public static boolean checkSign(String input, String sign) throws Exception {
        //创建key工厂
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        /*===========================生成公钥对象===========================*/
        //公钥规则
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publiceKeyStr));
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

        //获取签名对象
        Signature signature2 = Signature.getInstance("sha256withrsa");
        //初始化校验
        signature2.initVerify(publicKey);
        //传入原文
        signature2.update(input.getBytes());
        //开始和签名对比,校验签名
        boolean verify = signature2.verify(Base64.decode(sign));
//        System.out.println("验签的结果为=" + verify);
        return verify;
    }

    /**
     * 4 解密
     *
     * @param input 密文
     * @return
     */
    public static String decrypt(String input) throws Exception {
        //创建key工厂
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        /*===========================生成公钥对象===========================*/
        //公钥规则
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(publiceKeyStr));
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

        Cipher cipher2 = Cipher.getInstance(algorithm);
        cipher2.init(Cipher.DECRYPT_MODE, publicKey);
        byte[] doFinal2 = cipher2.doFinal(Base64.decode(input));
//        System.out.println("解密后的值为===" + new String(doFinal2));
        return new String(doFinal2);
    }

    /**
     * 测试对象
     */
    static class User {
        String name;
        int age;
        String sex;

        public User() {
        }

        public User(String name, int age, String sex) {
            this.name = name;
            this.age = age;
            this.sex = sex;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public String getSex() {
            return sex;
        }

        public void setSex(String sex) {
            this.sex = sex;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + ''' +
                    ", age=" + age +
                    ", sex='" + sex + ''' +
                    '}';
        }
    }


}