• RSA加密、解密、签名、验签的原理及方法


    https://www.cnblogs.com/pcheng/p/9629621.html

    package com.zhhs.project.yazq.app.utils;
    
    import org.apache.commons.codec.binary.Base64;
    
    import javax.crypto.Cipher;
    import java.io.*;
    import java.security.*;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    /**
     * @Date 2015-02-08 11:25:21
     * <p>
     * rsa 加密工具 【非对称加密】
     */
    public class RSAUtils {
        /**
         * 加密算法RSA
         */
        private static final String KEY_ALGORITHM = "RSA";
        /**
         * 签名算法
         */
        private static final String SIGNATURE_ALGORITHM = "MD5withRSA";
        /**
         * RSA最大加密明文大小
         */
        private static final int MAX_ENCRYPT_BLOCK = 244;
        /**
         * RSA最大解密密文大小
         */
        private static final int MAX_DECRYPT_BLOCK = 256;
    
    
        /**
         * 创建私钥公钥
         */
        public static void generateSecretKey(String fileAbsolutePath) throws Exception {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            keyPairGen.initialize(2048);
            KeyPair keyPair = keyPairGen.generateKeyPair();
            Key publicKey = (Key) keyPair.getPublic();
            Key privateKey = (Key) keyPair.getPrivate();
            StringBuilder str = new StringBuilder();
            str.append("publicKey:\n").append(encode(publicKey.getEncoded())).append("\n");
            str.append("privateKey:\n").append(encode(privateKey.getEncoded())).append("\n");
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(fileAbsolutePath)))) {
                writer.write(str.toString());
                writer.flush();
                System.out.println("生成完成!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * <p>
         * 用私钥对信息生成数字签名
         * </p>
         *
         * @param data       已加密数据
         * @param privateKey 私钥(BASE64编码)
         * @return
         * @throws Exception
         */
        public static String sign(byte[] data, String privateKey) throws Exception {
            byte[] keyBytes = decode(privateKey);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(privateK);
            signature.update(data);
            return encode(signature.sign());
        }
    
        /**
         * <p>
         * 校验数字签名
         * </p>
         *
         * @param data      已加密数据
         * @param publicKey 公钥(BASE64编码)
         * @param sign      数字签名
         * @return
         * @throws Exception
         */
        public static boolean verify(byte[] data, String publicKey, String sign)
                throws Exception {
            byte[] keyBytes = decode(publicKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PublicKey publicK = keyFactory.generatePublic(keySpec);
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initVerify(publicK);
            signature.update(data);
            return signature.verify(decode(sign));
        }
    
        /**
         * <P>
         * 私钥解密
         * </p>
         *
         * @param str        已加密数据
         * @param privateKey 私钥(BASE64编码)
         * @return
         * @throws Exception
         */
        public static String decryptByPrivateKey(String str, String privateKey)
                throws Exception {
    
            byte[] encryptedData = decode(str);
    
    
            byte[] keyBytes = decode(privateKey);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, privateK);
            int inputLen = encryptedData.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段解密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                    cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_DECRYPT_BLOCK;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            return new String(decryptedData);
        }
    
        /**
         * <p>
         * 公钥解密
         * </p>
         *
         * @param str       已加密数据
         * @param publicKey 公钥(BASE64编码)
         * @return
         * @throws Exception
         */
        public static String decryptByPublicKey(String str, String publicKey)
                throws Exception {
    
            byte[] encryptedData = decode(str);
    
    
            byte[] keyBytes = decode(publicKey);
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key publicK = keyFactory.generatePublic(x509KeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, publicK);
            int inputLen = encryptedData.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段解密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                    cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_DECRYPT_BLOCK;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            return new String(decryptedData);
        }
    
        /**
         * <p>
         * 公钥加密
         * </p>
         *
         * @param str       源数据
         * @param publicKey 公钥(BASE64编码)
         * @return
         * @throws Exception
         */
        public static String encryptByPublicKey(String str, String publicKey)
                throws Exception {
    
            byte[] data = str.getBytes();
            byte[] keyBytes = decode(publicKey);
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key publicK = keyFactory.generatePublic(x509KeySpec);
            // 对数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, publicK);
            int inputLen = data.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段加密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_ENCRYPT_BLOCK;
            }
            byte[] encryptedData = out.toByteArray();
            out.close();
            byte[] encryptedData1 = encryptedData;
            String encode = encode(encryptedData1);
    
    
            return encode;
        }
    
        /**
         * <p>
         * 私钥加密
         * </p>
         *
         * @param str        源数据
         * @param privateKey 私钥(BASE64编码)
         * @return
         * @throws Exception
         */
        public static String encryptByPrivateKey(String str, String privateKey)
                throws Exception {
            //获取str的byte
            byte[] data = str.getBytes();
    
    
            byte[] keyBytes = decode(privateKey);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    
            cipher.init(Cipher.ENCRYPT_MODE, privateK);
            int inputLen = data.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段加密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_ENCRYPT_BLOCK;
            }
            byte[] encryptedData = out.toByteArray();
            out.close();
            //进行Base64加密
            byte[] encryptedData1 = encryptedData;
            String encode = encode(encryptedData1);
            return encode;
        }
    
        /**
         * base64 编码
         *
         * @param bytes
         * @return
         * @throws Exception
         */
        public static String encode(byte[] bytes) throws Exception {
            return new String(Base64.encodeBase64(bytes));
        }
    
        /**
         * base64 解码
         *
         * @param base64
         * @return
         * @throws Exception
         */
        public static byte[] decode(String base64) throws Exception {
            return Base64.decodeBase64(base64.getBytes());
        }
    
        /**
         * 将 2 进制转换成 16 进制字符串
         */
        private static String byte2Hex(byte buf[]) {
            StringBuilder sb = new StringBuilder();
            for (byte aBuf : buf) {
                String hex = Integer.toHexString(aBuf & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        }
    
        /**
         * 将 16 进制字符串转换为 2 进制
         */
        private static byte[] hex2Byte(String hexStr) {
            if (hexStr.length() < 1) {
                return null;
            }
            byte[] result = new byte[hexStr.length() / 2];
            for (int i = 0; i < hexStr.length() / 2; i++) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
    
        /**
         * 公钥加密转成16进制
         */
        public static String encryptByPublicKeyToHex(String str, String publicKey) throws Exception {
            byte[] data = str.getBytes();
            byte[] keyBytes = decode(publicKey);
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key publicK = keyFactory.generatePublic(x509KeySpec);
            // 对数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, publicK);
            int inputLen = data.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段加密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_ENCRYPT_BLOCK;
            }
            byte[] encryptedData = out.toByteArray();
            out.close();
            String hex = byte2Hex(encryptedData);
            return hex;
        }
    
        /**
         * 16进制密文解密
         */
        public static String decryptHexStrByPrivateKey(String str, String privateKey) throws Exception {
            byte[] encryptedData = hex2Byte(str);
            byte[] keyBytes = decode(privateKey);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, privateK);
            int inputLen = encryptedData.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段解密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                    cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_DECRYPT_BLOCK;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            return new String(decryptedData);
        }
    
        public static void main(String[] args) throws Exception {
           generateSecretKey("D:\\key.txt");
        }
    
    
    }
    rsa:
      privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgE..........

    调用

    String logName = RSAUtils.decryptByPrivateKey(loginName, privateKey);

    前端调用

    /*公钥*/
    const publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwOuMADLF4Wj44..........";

    /*公钥加密*/
    function encryption(text) {
    var encrypt = new JSEncrypt();
    encrypt.setPublicKey(publicKey);
    var encryptData = encrypt.encrypt(text);
    return strToHexCharCode(encryptData);
    }

    /*字符串转16进制*/
    function strToHexCharCode(str) {
    if (str === "") {
    return "";
    }
    var hexCharCode = [];
    for (var i = 0; i < str.length; i++) {
    hexCharCode.push((str.charCodeAt(i)).toString(16));
    }
    return hexCharCode.join("");
    }
  • 相关阅读:
    实验一 网络侦查与网络扫描
    网络对抗作业一
    [BSidesCF 2020]Hurdles
    [BSidesCF 2019]Mixer
    安恒期末 admin
    C#编程:正则表达式验证身份证校验码-10
    分享1-3年经验的Java面试
    SpringMVC配置web.xml文件详解(列举常用的配置)
    Hibernate全套增删改查+分页
    Node.js连接mysql数据库方法
  • 原文地址:https://www.cnblogs.com/person008/p/16069121.html
Copyright © 2020-2023  润新知