首页 > 编程语言 >JAVA实现RSA加密、解密、加签、验签

JAVA实现RSA加密、解密、加签、验签

时间:2024-01-19 19:23:02浏览次数:40  
标签:return String RSA param str 验签 JAVA byte data

1、工具类RSAUtils.java

import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.io.ByteArrayOutputStream;
import javax.crypto.Cipher;
import java.security.*;
import java.util.*;


public class RSAUtils {

    /**
     * 加密算法RSA
     */
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 签名算法
     */
    public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";

    /**
     * 获取公钥的key
     */
    private static final String PUBLIC_KEY_STR = "PublicKeyStr";

    /**
     * 获取私钥的key
     */
    private static final String PRIVATE_KEY_STR = "PrivateKeyStr";

    /**
     * RSA最大加密明文大小(字节数)
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /**
     * RSA最大解密密文大小(字节数)
     */
    private static final int MAX_DECRYPT_BLOCK = 128;



    /**
     * @description: 生成公钥私钥
     * @date: 2024/1/17 14:47
     * @param
     * @return java.util.Map<java.lang.String,java.lang.String>
     */
    public static Map<String, String> initKeyPair() throws Exception {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        kpg.initialize(1024);
        KeyPair keyPair = kpg.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        String publicKeyStr = encryptBASE64(publicKey.getEncoded());
        String privateKeyStr = encryptBASE64(privateKey.getEncoded());

        Map<String, String> keyMap = new HashMap<>();
        keyMap.put(PUBLIC_KEY_STR, publicKeyStr);
        keyMap.put(PRIVATE_KEY_STR, privateKeyStr);
        return keyMap;
    }


    /**
     * @description:  公钥加密
     * @date: 2024/1/17 14:49
     * @param str 待加密字符串
     * @param key 公钥
     * @return java.lang.String
     */
    public static String encryptByPublicKey(String str, String key) throws Exception {
        byte[] data = str.getBytes();
        PublicKey publicKey = strToPublicKey(key);
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        byte[] bytes = dataSegment(data, cipher, MAX_ENCRYPT_BLOCK);
        return encryptBASE64(bytes);
    }


    /**
     * @description:  私钥解密
     * @date: 2024/1/17 14:52
     * @param str 待解密字符串
     * @param key 私钥
     * @return java.lang.String
     */
    public static String decryptByPrivateKey(String str, String key) throws Exception {
        byte[] data = decryptBASE64(str);
        PrivateKey privateKey = strToPrivateKey(key);
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        byte[] bytes = dataSegment(data, cipher, MAX_DECRYPT_BLOCK);
        return new String(bytes);
    }


    /**
     * @description:  私钥加密
     * @date: 2024/1/17 14:58
     * @param str 待加密字符串
     * @param key 私钥
     * @return java.lang.String
     */
    public static String encryptByPrivateKey(String str, String key) throws Exception {
        byte[] data = str.getBytes();
        PrivateKey privateKey = strToPrivateKey(key);
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);

        byte[] bytes = dataSegment(data, cipher, MAX_ENCRYPT_BLOCK);
        return encryptBASE64(bytes);
    }


    /**
     * @description:  公钥解密
     * @date: 2024/1/17 15:23
     * @param str 待解密字符串
     * @param key 公钥
     * @return java.lang.String
     */
    public static String decryptByPublicKey(String str, String key) throws Exception {
        byte[] data = decryptBASE64(str);
        PublicKey publicKey = strToPublicKey(key);
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, publicKey);

        byte[] bytes = dataSegment(data, cipher, MAX_DECRYPT_BLOCK);
        return new String(bytes);
    }


    /**
     * @description:  使用私钥对数据进行数字签名
     * @date: 2024/1/17 15:36
     * @param str 待加签字符串
     * @param privateKey 私钥
     * @return java.lang.String
     */
    public static String sign(String str, String privateKey) throws Exception {
        byte[] data = str.getBytes();
        PrivateKey priKey = strToPrivateKey(privateKey);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(priKey);
        signature.update(data);
        byte[] bytes = signature.sign();
        return encryptBASE64(bytes);
    }


    /**
     * @description: 使用公钥对数据验证签名
     * @date: 2024/1/17 15:46
     * @param str 待验签字符串(即要加签的内容)
     * @param publicKey 公钥
     * @param sign 数据签名
     * @return boolean
     */
    public static boolean verify(String str, String publicKey, String sign) throws Exception {
        byte[] data = str.getBytes();
        byte[] signBytes = decryptBASE64(sign);
        PublicKey pubKey = strToPublicKey(publicKey);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(pubKey);
        signature.update(data);
        return signature.verify(signBytes);
    }

    /**
     * @description: 对数据进行分段加密或解密
     * @date: 2024/1/17 16:11
     * @param data
     * @param cipher
     * @param maxBlock
     * @return byte[]
     */
    private static byte[] dataSegment(byte[] data, Cipher cipher, int maxBlock) throws Exception{
        byte[] toByteArray;
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        int i = 0;
        byte[] cache;
        // 对数据分段加密解密
        while (inputLen - offSet > 0) {
            int var = inputLen - offSet > maxBlock ? maxBlock : inputLen - offSet;
            cache = cipher.doFinal(data, offSet, var);
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * maxBlock;
        }
        toByteArray = out.toByteArray();
        out.close();
        return toByteArray;
    }


    /**
     * @description: 获取私钥
     * @date: 2024/1/17 14:57
     * @param str 私钥字符串
     * @return java.security.PrivateKey
     */
    private static PrivateKey strToPrivateKey(String str) throws Exception {
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(decryptBASE64(str));
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        return privateKey;
    }

    /**
     * @description: 获取公钥
     * @date: 2024/1/17 14:57
     * @param str 公钥字符串
     * @return java.security.PrivateKey
     */
    private static PublicKey strToPublicKey(String str) throws Exception {
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(decryptBASE64(str));
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
        return publicKey;
    }


    /**
     * @description:  字节数组转字符串
     * @date: 2024/1/17 14:59
     * @param bytes 字节数组
     * @return java.lang.String
     */
    private static String encryptBASE64(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }


    /**
     * @description: 字符串转字节数组
     * @date: 2024/1/17 15:00
     * @param str 字符串
     * @return byte[]
     */
    private static byte[] decryptBASE64(String str) {
        return Base64.getDecoder().decode(str);
    }


    public static void main(String[] args) throws Exception {
        // 获取公钥私钥
        Map<String, String> keyMap = initKeyPair();
        String publicKey = keyMap.get(PUBLIC_KEY_STR);
        String privateKey = keyMap.get(PRIVATE_KEY_STR);
        System.out.println("公钥: " + publicKey);
        System.out.println("私钥: " + privateKey);

        String data = "123456";
        System.out.println("源数据: " + data);

        // 公钥加密私钥解密
        String encryptData = encryptByPublicKey(data, publicKey);
        String decryptData = decryptByPrivateKey(encryptData, privateKey);
        System.out.println("公钥加密结果: " + encryptData);
        System.out.println("私钥解密结果: " + decryptData);
        System.out.println();

        // 私钥加密公钥解密
        String encryptData2 = encryptByPrivateKey(data, privateKey);
        String decryptData2 = decryptByPublicKey(encryptData2, publicKey);
        System.out.println("私钥加密结果: " + encryptData2);
        System.out.println("公钥解密结果: " + decryptData2);
        System.out.println();

        // 私钥加签公钥验签
        String data2 = "abc123369";
        String sign = sign(data2, privateKey);
        boolean flag = verify(data2, publicKey, sign);
        System.out.println("私钥加签结果: " + sign);
        System.out.println("公钥验签结果: " + flag);
    }

}

 

2、测试结果

 

标签:return,String,RSA,param,str,验签,JAVA,byte,data
From: https://www.cnblogs.com/guliang/p/17975428

相关文章

  • [Java SE/JDK] Map之重定义key对象的hash值
    0序言项目上有个场景:数据源连接池需要对key对象的hash值重写,保证通过相同的关键属性(datasourceName)值去重不同的对象。publicabstractclassAbstractDatabaseConnectorKeyedObjectPool<KextendsDataSource,VextendsAbstractConnector>1重写Map的key对象的hash值......
  • Java - 排序
      冒泡排序升序排列importjava.util.Arrays;publicclassArrayDemo07{publicstaticvoidmain(String[]args){int[]a={1,4,5,3,14,12,51};int[]sort=sort(a);System.out.println(Arrays.toString(sort));}public......
  • Java爬虫在网络数据抓取方面有什么优势和不足
    Java爬虫是一种常用的网络数据抓取工具,它能够自动化地从网页中提取和解析数据。本文将介绍Java爬虫在网络数据抓取方面的优势和不足。一、Java爬虫的优势1.多线程支持:Java语言天生支持多线程,可以使用多线程技术提高爬虫的并发能力,加快数据抓取速度。2.丰富的第三方库:Java拥有丰富的......
  • java线程的基本操作
    1.线程名称的设置和获取在Thread类中可以通过构造器Thread(...)初始化设置线程名称,也可以通过setName(...)实例方法去设置线程名称,取得线程名称可以通过getName()方法完成。关于线程名称有以下几个要点:线程名称一般在启动线程前设置,但也允许为运行的线程设置名称......
  • Java开发之Java8 新特性--流式数据处理学习
    一.流式处理简介在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式处理可以在一行中实现。比如我们希望对一个包含整数的集合中筛选出所有的偶数,并将其封装成为一个新的List返回,那么在java8之前,我们需......
  • Java实现基于GDAL将单波段影像转为三波段影像-唯一值渲染
    在处理遥感影像的渲染时,经常需要处理单波段影像。单波段影像没有任何颜色,只有一个波段的值。渲染时只能采用色带拉伸、离散颜色、唯一值渲染这几种方式。直接将单波段影像转成三波段的影像,并将三个波段转为颜色对应的rgb值,这样可以加速渲染、切片的过程。这里我有一张单波段影像,需......
  • qt和java的socket连接
    事先说明qt为客户端(发出请求)java为服务端(处理请求)关于qt的客户端来说我们大体上要完成三个需求,即请求连接,发送,接收请求连接如果想使用qt写socket程序,首先需要在.pro文件中添加QT+=network;(非常非常重要)接收然后我们就可以在代码中使用QT的网络库了,socket涉及到的函数库......
  • RSA加密算法实现
    一、实验目的深度理解RSA算法的工作原理,查阅欧几里得扩展算法计算模运算的逆元,并编程序实现。学会生成不同大小的素数,体会模指数运算的困难性和模指数运算的快速算法。二、实验器材pycharm+python3.11三、实验内容1.实验要求:自己配置python环境,编写RSA算法实现程序,运行RSA程......
  • java线程核心原理
    1.线程的调度与时间片1.1java线程与操作系统现代操作系统(如Windows、Linux、Solaris)提供了强大的线程管理能力,Java不需要再进行自己独立的线程管理和调度,而是将线程调度工作委托给操作系统的调度进程去完成。在某些系统(比如Solaris操作系统)上,JVM甚至将每个Java线程一对一......
  • 深入理解JavaScript堆栈、事件循环、执行上下文、作用域以及闭包
    合集-JavaScript进阶系列(5) 1.JavaScriptthis绑定详解01-092.JavaScriptapply、call、bind函数详解01-093.JavaScriptforEach方法跳出循环01-024.深入理解JavaScript堆栈、事件循环、执行上下文和作用域以及闭包01-105.JavaScript到底应不应该加分号?JavaScript自......