首页 > 编程语言 >Java RSA 加解密工具类,直接用

Java RSA 加解密工具类,直接用

时间:2024-02-24 16:23:29浏览次数:22  
标签:Java String java int 加解密 RSA static import byte

import org.junit.Test;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;

/**
 * @author EvanY
 * @since 2021/11/30
 */
public class RSAUtils {

    private static final String RSA = "RSA";
    private static final String RSA_ECB_PKCS1 = "RSA/ECB/PKCS1Padding";
    private static final String SHA1withDSA = "SHA1withDSA";
    private static final String SHA1withRSA = "SHA1withRSA";
    private static final String SHA256withRSA = "SHA256withRSA";
    private static final int BYTE_BIT_LENGTH = 8;
    private static final int PKCS1_PADDING_LENGTH = 11;

    String privateKeyStr = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAI++rMw5U/7DFooAlSZ9V2l89l44KfjClCFFFxzfLGvhVDTduP9FI8gQyOOvNekipcw1E01XbV6/JhGoKuwHVFfmCFeZWTBBJhMdIb4qh2cNOgfR5yEIxrn0928VnA+RwLg/LEtXuo0pkSs/SQ4Ey62QTGanWP0B5bRWkhxGIHTvAgMBAAECgYBWXxkPYYcR9oFNjMoSJZBnhzm2JYM6wRgm4Y/gvky/ydZCKdQmNpIofcVn4fi/zBzZli6x8015d9vVEjowNrs7YmmiAWK6BeF50Jo9a/6b42DCmYnJd4hLSzmXtlNI6nwvJ72vzCSOqji5Bzrg6Gj5MFHmeHyLZtqUhtu8nmpD8QJBAPx4NJjgLNwdCHZ1avKcmRFAHdnkc2DDYIWyi2SqI7wX/+pk6ExwT/wOC5a/8bl+hJcwLQNTXTVybOENV4sZfmcCQQCRwUFIdY8BLzDm6joLmaXXVTGPwlNc49IsSMcCd3YyAQtB6giIZeUpxYrBQlwrnd17f68ny7BNSSnlgHs0QDA5AkEAl1+DOb3/Z6JItq3EB974r60fuMsOmo/KSZ85kIuqjVZebK0/0sTsUBYjwKkpR6yh1vxdoMbU9fy7Z1xWhuIsNQJBAIdsElbbexnzmbECsRm0EUUnz5utRr0Io28n01e0XOoK1EXSx0jLu4b7FneHS5Hu5Cjpsnj8JHs6XiXxIQekF+kCQQD0u19/Pv2aZ4q2MBAwI2X5sElSfUEr3WNRFgKzxvejjgtxcAgK/UJCqBkcab/bDE5tHL64hljCo+kdZS0829C3";
    String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPvqzMOVP+wxaKAJUmfVdpfPZeOCn4wpQhRRcc3yxr4VQ03bj/RSPIEMjjrzXpIqXMNRNNV21evyYRqCrsB1RX5ghXmVkwQSYTHSG+KodnDToH0echCMa59PdvFZwPkcC4PyxLV7qNKZErP0kOBMutkExmp1j9AeW0VpIcRiB07wIDAQAB";

    public static String encodeToString(byte[] unEncoded) {
        return new String(encode(unEncoded), StandardCharsets.UTF_8);
    }

    public static byte[] encode(byte[] unEncoded) {
        return Base64.getEncoder().encode(unEncoded);
    }

    public static byte[] decodeFromString(String encoded) {
        return Base64.getDecoder().decode(encoded.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 根据公钥字符串生成公钥对象
     */
    public static PublicKey getPublicKey(String publicKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] keyByte = decodeFromString(publicKeyStr);
        return KeyFactory.getInstance(RSA).generatePublic(new X509EncodedKeySpec(keyByte));
    }

    /**
     * 根据私钥字符串生成私钥对象
     */
    public static PrivateKey getPrivateKey(String privateKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] keyByte = decodeFromString(privateKeyStr);
        return KeyFactory.getInstance(RSA).generatePrivate(new PKCS8EncodedKeySpec(keyByte));
    }

    /**
     * 用公钥加密字符串
     */
    public static String encrypt(String algorithm, String publicKeyStr, String unencryptedStr) throws Exception {
        return encrypt(algorithm, publicKeyStr, null, StandardCharsets.UTF_8, unencryptedStr);
    }

    public static String encrypt(String algorithm, String publicKeyStr, AlgorithmParameterSpec param, Charset charset, String unencryptedStr) throws Exception {
        PublicKey publicKey = getPublicKey(publicKeyStr);
        Cipher cipher = initCipher(algorithm, Cipher.ENCRYPT_MODE, publicKey, param);
        byte[] bytes = unencryptedStr.getBytes(charset);
        //单次加密最大长度
        int maxEncryptByteLength = ((RSAKey) publicKey).getModulus().bitLength() / BYTE_BIT_LENGTH;
        int excludePaddingMaxLength = maxEncryptByteLength - PKCS1_PADDING_LENGTH;
        int encryptCount = bytes.length / excludePaddingMaxLength;
        //可能有剩余字符串,不足一次加密长度,
        int outSize = maxEncryptByteLength * (encryptCount + 1);
        byte[] encryptedBytes = getBytes(cipher, bytes, excludePaddingMaxLength, outSize);
        return encodeToString(encryptedBytes);
    }

    private static byte[] getBytes(Cipher cipher, byte[] bytes, int step, int outSize) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream(outSize);
        int offset = 0;
        byte[] outBytes;
        while (offset + step <= bytes.length) {
            outBytes = cipher.doFinal(bytes, offset, step);
            out.write(outBytes);
            offset += step;
        }
        if (offset < bytes.length) {
            outBytes = cipher.doFinal(bytes, offset, bytes.length - offset);
            out.write(outBytes);
        }
        return out.toByteArray();
    }

    /**
     * 用私钥解密字符串
     */
    public static String decrypt(String algorithm, String privateKeyStr, String encryptedStr) throws Exception {
        return decrypt(algorithm, privateKeyStr, null, StandardCharsets.UTF_8, encryptedStr);
    }

    public static String decrypt(String algorithm, String privateKeyStr, AlgorithmParameterSpec param, Charset charset, String encryptedStr) throws Exception {
        PrivateKey privateKey = getPrivateKey(privateKeyStr);
        Cipher cipher = initCipher(algorithm, Cipher.DECRYPT_MODE, privateKey, param);
        byte[] bytes = decodeFromString(encryptedStr);
        //单次解密最大长度
        int maxDecryptByteLength = ((RSAKey) privateKey).getModulus().bitLength() / BYTE_BIT_LENGTH;
        int excludePaddingMaxLength = maxDecryptByteLength - PKCS1_PADDING_LENGTH;
        int decryptCount = bytes.length / maxDecryptByteLength;
        int outSize = decryptCount * excludePaddingMaxLength;
        byte[] decryptedBytes = getBytes(cipher, bytes, maxDecryptByteLength, outSize);
        return new String(decryptedBytes, charset);
    }

    /**
     * 初始化密码
     */
    public static Cipher initCipher(String algorithm, int cipherMode, Key key, AlgorithmParameterSpec param)
            throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException {
        Cipher cipher = Cipher.getInstance(algorithm);
        if (param == null) {
            cipher.init(cipherMode, key);
        } else {
            cipher.init(cipherMode, key, param);
        }
        return cipher;
    }

    //签名
    public static String sign(String algorithm, String privateKeyStr, Charset charset, String encryptedStr) throws Exception {
        PrivateKey privateKey = getPrivateKey(privateKeyStr);
        Signature signature = Signature.getInstance(algorithm);
        signature.initSign(privateKey);
        signature.update(encryptedStr.getBytes(charset));
        byte[] signByte = signature.sign();
        return encodeToString(signByte);
    }

    public static boolean verifySign(String algorithm, String publicKeyStr, Charset charset, String encryptedStr, String signStr) throws Exception {
        PublicKey publicKey = getPublicKey(publicKeyStr);
        Signature signature = Signature.getInstance(algorithm);
        signature.initVerify(publicKey);
        signature.update(encryptedStr.getBytes(charset));
        byte[] signByte = decodeFromString(signStr);
        return signature.verify(signByte);
    }

    public static String[] generateKeys(String algorithm, int keySize) throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        keyPairGenerator.initialize(keySize);
        KeyPair keyPair = keyPairGenerator.genKeyPair();
        byte[] privateKeyByte = keyPair.getPrivate().getEncoded();
        byte[] publicKeyByte = keyPair.getPublic().getEncoded();
        return new String[]{new String(encode(privateKeyByte)), new String(encode(publicKeyByte))};
    }

    @Test
    public void test() throws NoSuchAlgorithmException {
        String[] keys = generateKeys(RSA, 512);
        System.out.println(keys[0]);
        System.out.println(keys[1]);
    }

    @Test
    public void testEncrypt() throws Exception {
        String[] keys = generateKeys(RSA, 1024);
        System.out.println("PrivateKeyStr:" + keys[0]);
        System.out.println("PublicKeyStr:" + keys[1]);

        String unencryptedStr = "{\"serialNo\":\"中国China

标签:Java,String,java,int,加解密,RSA,static,import,byte
From: https://www.cnblogs.com/yy299/p/18031198

相关文章

  • Java_6 函数
    title:(在线学习平台)link:(https://www.acwing.com/)cover:(https://cdn.acwing.com/media/activity/surface/log.png)1函数基础一个典型的函数定义包括以下部分:修饰符、返回类型、函数名字、由0个或多个形参组成的列表以及函数体。1.1编写函数我们来编写一个求阶乘的......
  • 【论文随笔】会话推荐系统综述(A Survey on Conversational Recommender Systems)
    前言今天读的论文为一篇于2021年5月发表在《ACM计算机调查》(ACMComputingSurveys)的论文,文章提供了对话式推荐系统(CRS)的全面综述,探讨了CRS的定义、概念架构、交互方式、知识元素、计算任务以及评估方法。文章还讨论了CRS在不同应用环境中的实现,如智能家居助手和聊天机器人,并指......
  • java异常
    java异常异常分类Throwable是所有异常子类的超类exception子类:编译器异常,进行编译,java程序出现问题error子类:错误,必须修改源代码产生过程JVM判断异常,并产生包含异常信息的对象,如果异常产生的方法没有try--catch方法,如果没有则把异常对象返回main方法main方法也判......
  • Java锁的思想和区别
    乐观锁VS悲观锁乐观锁和悲观锁是两种处理并发访问的不同策略,用于确保多个操作不会同时修改同一资源而导致数据不一致的问题。它们的区别在于处理并发时的思想和实现方式:乐观锁:思想:认为在大多数情况下,读操作远远多于写操作,因此假设在绝大多数情况下并发冲突是不会发生的,直到出......
  • Javascript/DOM:如何删除 DOM 对象的所有事件侦听器
    Javascript/DOM:如何删除DOM对象的所有事件侦听器一、重写重写EventTarget添加监听事件方法addEventListenerif(EventTarget.prototype.original_addEventListener==null){EventTarget.prototype.original_addEventListener=EventTarget.prototype.addEventList......
  • Java语法之HelloWorld!
    HelloWorld入门随便新建一个文件夹(coed),存放代码新建一个Java文件文件后缀名为.JavaHello.java编写代码publicclassHello{ publicstaticvoidmain(String[]args){ System.out.print("Hello,World!"); }}编译javacjava文件,会生成一个class文件运......
  • 什么是Java中的SPI机制
    SPI,全称ServiceProviderInterface,是Java中提供的一种服务发现机制它允许应用程序动态地加载和使用第三方提供的服务实现,而无需在代码中引用这些实现类。JavaSPI是基于接口编程思想的具体体现,通过将服务接口和其实现分离,从而具备更好的可扩展性和可维护性如何定义一个Java......
  • Java事件侦听器学习记录
    前言我们监听事件之前要有事件源source,创建事件源(Event),发布事件(publishEvent),然后才能到监听事件。事件驱动机制是观察者模式(称发布订阅)具体实现,事件对象(Event)相当于被观察对象(Subject),事件监听(EventListener)相当于观察者(Observer)1、包结构(个人): 2、创建事件源(Event)......
  • java面向对象之封装-抽象-继承-组合-多态五种概念一网打尽
    说明曾经在学习java面向对象时,你是否会为面向对象的封装-继承-抽象-多态-组合等各种概念搞得稀里糊涂,乃至反复阅读,背诵其相关概念,结果一段时间过后又还给了时间。。。这种经历简直令人发指,让人无法忍受,难道就没有哪个地方能把它一次说清楚,老百姓看了以后纷纷醍醐灌顶,不再重蹈覆......
  • java中 break和continue区别
    breakcontinue◆break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环不执行循环中剩余的语句。(break语句也在switch语句中使用)◆continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句接着进行下一次是否执行循环的判......