追枫狼

导航

Java中使用RSA加解密

  最近写了好多和第三方交互需要安全加密传输的需求,涉及到了AES、DES、RSA、SM2、SM3、SM4等,此处记录RSA的使用。

生成rsa秘钥对:

        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        // 初始化密钥对生成器,密钥大小为512-4096位
        keyPairGen.initialize(1024,new SecureRandom());
        // 生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 得到私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        // 得到公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        // 得到公钥字符串
        String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
        // 得到私钥字符串
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));

        String str1 = "publicKeyString公钥:" + publicKeyString;
        writeFile(str1);
        String str2 = "privateKeyString私钥:" + privateKeyString;
        writeFile(str2);    

public static void writeFile(String content) {

        File file = new File("C:\\Users\\Administrator\\Desktop\\1.txt");

        FileOutputStream fos = null;
        OutputStreamWriter osw = null;

        try {
            if (!file.exists()) {
                boolean hasFile = file.createNewFile();
                if (hasFile) {
                    log.info("file not exists, create new file");
                }
                fos = new FileOutputStream(file);
            } else {
                fos = new FileOutputStream(file, true);
            }

            osw = new OutputStreamWriter(fos, "utf-8");
            // 写入内容
            osw.write(content);
            // 换行
            osw.write("\r\n");
        } catch (Exception e) {
            log.info("写入文件发生异常", e);
        } finally {
            // 关闭流
            try {
                if (osw != null) {
                    osw.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                log.info("关闭流异常", e);
            }
        }
    }

  公钥加密私钥模式:

/**
     * RSA私钥解密
     *
     * @param str        加密字符串
     * @param privateKey 私钥
     * @return 铭文
     * @throws Exception 解密过程中的异常信息
     */
    public static String privateKeyDecrypt(String str, String privateKey) throws Exception {
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
        //base64编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
                .generatePrivate(new PKCS8EncodedKeySpec(decoded));
        //RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
//        String outStr = new String(cipher.doFinal(inputByte));
        //当长度过长的时候,需要分割后解密 128个字节
        String outStr = new String(getMaxResultDecrypt(str, cipher));
        return outStr;
    }

    private static byte[] getMaxResultDecrypt(String str, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        byte[] inputArray = Base64.decodeBase64(str.getBytes("UTF-8"));
        int inputLength = inputArray.length;
        // 最大解密字节数,超出最大字节数需要分组加密
        int MAX_ENCRYPT_BLOCK = 128;
        // 标识
        int offSet = 0;
        byte[] resultBytes = {};
        byte[] cache = {};
        while (inputLength - offSet > 0) {
            if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
                offSet += MAX_ENCRYPT_BLOCK;
            } else {
                cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
                offSet = inputLength;
            }
            resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
            System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
        }
        return resultBytes;
    }

/**
     * RSA公钥加密
     *
     * @param str       加密字符串
     * @param publicKey 公钥
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     */
    public static String publicKeyEncrypt(String str, String publicKey) throws Exception {
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").
                generatePublic(new X509EncodedKeySpec(decoded));
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);

        //当长度过长的时候,需要分割后加密 117个字节
        byte[] resultBytes = getMaxResultEncrypt(str, cipher);

        String outStr = Base64.encodeBase64String(resultBytes);
        return outStr;
    }

    private static byte[] getMaxResultEncrypt(String str, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException {
        byte[] inputArray = str.getBytes();
        int inputLength = inputArray.length;
        // 最大加密字节数,超出最大字节数需要分组加密
        int MAX_ENCRYPT_BLOCK = 117;
        // 标识
        int offSet = 0;
        byte[] resultBytes = {};
        byte[] cache = {};
        while (inputLength - offSet > 0) {
            if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
                offSet += MAX_ENCRYPT_BLOCK;
            } else {
                cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
                offSet = inputLength;
            }
            resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
            System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
        }
        return resultBytes;
    }

  私钥加密公钥解密:

/**
     * 使用公钥解密
     */
    @SneakyThrows
    public static String decryptByPublicKey(String data) {
        try {
            return new String(getMaxResultDecrypt(data, getPublicKey(Cipher.DECRYPT_MODE)));
        }catch (Exception e){
            throw new Exception("解密失败|"+e.getMessage());
        }
    }
    /**
     * 使用RSA私钥解密
     *
     * @param str 加密字符串
     */
    public static String decryptByPrivateKey(String str) {
        return new String(getMaxResultDecrypt(str, getPrivateKey(Cipher.DECRYPT_MODE)));
    }

    /**
     * 使用RSA私钥加密
     * @param data       加密数据
     */
    @SneakyThrows
    public static String encryptByPrivateKey(String data) {
        try {
            return Base64.encodeBase64String(getMaxResultEncrypt(data, getPrivateKey(Cipher.ENCRYPT_MODE)));
        } catch (Exception e) {
            throw new Exception("加密失败|"+e.getMessage());
        }
    }
    /**
     * 当长度过长的时候,需要分割后加密 117个字节
     */
    @SneakyThrows
    private static byte[] getMaxResultEncrypt(String str, Cipher cipher){
        try {
            byte[] inputArray = str.getBytes(StandardCharsets.UTF_8.name());
            int inputLength = inputArray.length;
            // 最大加密字节数,超出最大字节数需要分组加密
            int maxEncryptBlock = 117;
            // 标识
            int offSet = 0;
            byte[] resultBytes = {};
            byte[] cache;
            while (inputLength - offSet > 0) {
                if (inputLength - offSet > maxEncryptBlock) {
                    cache = cipher.doFinal(inputArray, offSet, maxEncryptBlock);
                    offSet += maxEncryptBlock;
                } else {
                    cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
                    offSet = inputLength;
                }
                resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
                System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
            }
            return resultBytes;
        }catch (Exception e){
            e.printStackTrace();
            throw new Exception("加密处理失败,"+e.getMessage());
        }
    }

    /**
     * 当长度过长的时候,需要分割后解密 128个字节
     */
    @SneakyThrows
    private static byte[] getMaxResultDecrypt(String str, Cipher cipher) {
        try {
            byte[] inputArray = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8.name()));
            int inputLength = inputArray.length;
            // 最大解密字节数,超出最大字节数需要分组加密
            int maxEncryptBlock = 128;
            int offSet = 0;
            byte[] resultBytes = {};
            byte[] cache;
            while (inputLength - offSet > 0) {
                if (inputLength - offSet > maxEncryptBlock) {
                    cache = cipher.doFinal(inputArray, offSet, maxEncryptBlock);
                    offSet += maxEncryptBlock;
                } else {
                    cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
                    offSet = inputLength;
                }
                resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
                System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
            }
            return resultBytes;
        }catch (Exception e){
            e.printStackTrace();
            throw new Exception("解密数据处理异常,"+e.getMessage());
        }
    }
    /**
     * 根据加解密类型处理公钥
     *
     */
    @SneakyThrows
    public static Cipher getPublicKey(int mode) {
        try {
            String publicKey = formatString(PK);
            byte[] decoded = Base64.decodeBase64(publicKey);
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decoded);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PublicKey key = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(mode, key);
            return cipher;
        } catch (Exception e) {
            throw new Exception("转换公钥异常====>>" + e.getMessage());
        }
    }

    /**
     * 根据加解密类型处理私钥
     */
    @SneakyThrows
    public static Cipher getPrivateKey(int mode) {
        try {
            //mode 加解密模式 ENCRYPT_MODE = 1  DECRYPT_MODE = 2
            String privateKey = formatString(SK);
            byte[] decoded = Base64.decodeBase64(privateKey);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decoded);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey key = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(mode, key);
            return cipher;
        } catch (Exception e) {
            throw new Exception("转换私钥异常====>>" + e.getMessage());
        }
    }
    public static String formatString(String source) {
        if (source == null) {
            return null;
        }
        return source.replace("\\r", "").replace("\\n", "").trim().replace(" ","");
    }

  

posted on 2022-07-27 17:04  追枫狼  阅读(3465)  评论(0编辑  收藏  举报