首页 > 其他分享 >使用rsa对明文加密与解密

使用rsa对明文加密与解密

时间:2023-10-24 13:11:43浏览次数:27  
标签:Exception return String plaintext 解密 rsa byte 明文 throws

公钥加密,私钥解密

/**
     * 加密
     *
     * @param plaintext    明文
     * @param publicKeyStr 公钥字符
     * @return
     * @throws Exception
     */
    public static String rsaEncrypt(String plaintext, String publicKeyStr) throws Exception {
        // 将公钥字符串和私钥字符串转换为 PublicKey 对象
        PublicKey publicKey = getPublicKey(publicKeyStr);
        // 使用公钥加密明文
        byte[] encryptedBytes = encrypt(plaintext.getBytes(StandardCharsets.UTF_8), publicKey);
        System.out.println("加密文本: " + base64Encode(encryptedBytes));
        return base64Encode(encryptedBytes);
    }

    /**
     * 加密
     *
     * @param encryptedText 加密密文
     * @param privateKeyStr 私钥字符
     * @return
     * @throws Exception
     */
    public static String rsaDecrypt(String encryptedText, String privateKeyStr) throws Exception {
        // 将公钥字符串和私钥字符串转换为 PrivateKey 对象
        PrivateKey privateKey = getPrivateKey(privateKeyStr);
        // 使用私钥解密密文
        byte[] decryptedBytes = decrypt(base64Decode(encryptedText), privateKey);
        System.out.println("解密文本: " + new String(decryptedBytes, StandardCharsets.UTF_8));
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    /**
     * 将公钥字符串转换为 PublicKey 对象
     *
     * @param publicKeyStr
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKey(String publicKeyStr) throws Exception {
        byte[] keyBytes = base64Decode(publicKeyStr);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
    }

    /**
     * 将私钥字符串转换为 PrivateKey 对象
     *
     * @param privateKeyStr
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String privateKeyStr) throws Exception {
        // 添加 Bouncy Castle 作为安全提供程序
        Security.addProvider(new BouncyCastleProvider());
        byte[] keyBytes = base64Decode(privateKeyStr);
        //pkcs1格式 转 pkcs8格式
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(spec);
    }

    /**
     * 使用公钥加密
     *
     * @param plaintext
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(byte[] plaintext, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(plaintext);
    }

    /**
     * 使用私钥解密
     *
     * @param ciphertext
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] ciphertext, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(ciphertext);
    }

    /**
     * Base64 编码
     *
     * @param data
     * @return
     */
    public static String base64Encode(byte[] data) {
        return Base64.getEncoder().encodeToString(data);
    }

    /**
     * Base64 解码
     *
     * @param data
     * @return
     */
    public static byte[] base64Decode(String data) {
        return Base64.getDecoder().decode(data);
    }

 

测试

public static void main(String[] args) throws Exception {
        // 明文
        String plaintext = "123456";
        // 使用公钥加密明文
        String s = rsaEncrypt(plaintext, publicKeyStr);
        System.out.println("加密文本: " + s);
        System.out.println("解密文本: " + rsaDecrypt(s, privateKeyStr));

        String sign = sign(plaintext);
        System.out.println("签名结果:" + sign);

        boolean verify = verify(plaintext, sign);
        System.out.println("验证签名结果:" + verify);
    }

 

秘钥格式

PKCS1的文件头格式    -----BEGIN RSA PRIVATE KEY-----
PKCS8的文件头格式    -----BEGIN PRIVATE KEY-----

 

签名

/**
     * 签名
     *
     * @param plaintext 需要签名的明文
     * @return 返回签名信息
     * @throws Exception
     */
    public static String sign(String plaintext) throws Exception {
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

        // 创建Signature对象并初始化为签名模式
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);

        // 要签名的数据
        byte[] dataToSign = plaintext.getBytes(StandardCharsets.UTF_8);

        // 更新数据并签名
        signature.update(dataToSign);
        byte[] signatureBytes = signature.sign();

        // 将签名结果以Base64编码的形式输出
        String signatureBase64 = Base64.getEncoder().encodeToString(signatureBytes);
        System.out.println("RSA签名结果:" + signatureBase64);
        return signatureBase64;
    }

 

验证签名

/**
     * 验证签名
     *
     * @param plaintext 明文
     * @param decodeSrc 签名结果的Base64编码
     * @return 返回签名结果
     * @throws Exception
     */
    public static boolean verify(String plaintext, String decodeSrc) throws Exception {
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);

        // 创建Signature对象并初始化为验签模式
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(publicKey);

        // 原始数据和签名数据
        byte[] originalData = plaintext.getBytes(StandardCharsets.UTF_8);
        byte[] signatureBytes = Base64.getDecoder().decode(decodeSrc);

        // 更新数据并验证签名
        signature.update(originalData);
        boolean isValid = signature.verify(signatureBytes);

        if (isValid) {
            System.out.println("RSA签名验证成功");
        } else {
            System.out.println("RSA签名验证失败");
        }
        return isValid;
    }

 

注意:

PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

这个是构造一个对象,并没有转换pkcs8 格式的操作

在执行转换前加上这行就可以了

Security.addProvider(new BouncyCastleProvider());

 

如果秘钥放在yml文件中需要注意以\换行

 

标签:Exception,return,String,plaintext,解密,rsa,byte,明文,throws
From: https://www.cnblogs.com/ckfeng/p/17784574.html

相关文章

  • The 2nd Universal Cup. Stage 6: Warsaw L.Spectacle (思维)
    大致题意:  给定n个玩家,每个玩家有一个战力值,安排x(1<=x<=n/2(向下取整))场游戏,每场游戏安排x对玩家对战,对于每一场游戏每个玩家只能参加一次对战,要求对于每x场玩家对战的两个玩家rating差的最大值尽可能小。  例如给定6个玩家战力值为10131420100105,当x=1的时......
  • 探索CPU的黑盒子:解密指令执行的秘密
    引言在我们之前的章节中,我们着重讲解了CPU内部的处理过程,以及与之密切相关的数据总线知识。在这个基础上,我们今天将继续深入探讨CPU执行指令的相关知识,这对于我们理解计算机的工作原理至关重要。CPU是一系列寄存器的集合体我们以使用的IntelCPU为例,其中包含数百亿个晶体管......
  • JS加密/解密之闭包的运用
    深入探讨JavaScript闭包的演变与应用摘要:本文将深入探讨JavaScript闭包的概念、特性以及其在实际开发中的应用。我们将从闭包的起源开始,探讨它在JavaScript编程中的重要性,并通过实例展示闭包在不同场景下的灵活应用。引言JavaScript作为一种高度灵活的编程语言,一直以其独特的特性......
  • JS加密/解密那些必须知道的事儿
    一直以来,字符串的编码问题对于新手程序员来说,或者平常不太涉猎这方面的程序员来说,是犹如灵异学一样的存在。经常会遇到莫名其妙的编码问题,导致的各种的无法理解的错误。 今天,本问就来介绍一下作者所知晓的一切的字符编码知识。0x1.初识ASCII 说起字符串编码,不得不说到现代计算机的......
  • 一篇文章解密如何轻松实现移动应用的电子和手绘PDF签名功能!
    对PDF文件签名是移动设备上越来越普遍的使用需求,本文将描述自动生成/“手绘”签名与如何使用DevExpressOfficeFileAPI组件来实现在.NETMAUI应用程序中快速合并签名/签名支持之间的区别。DevExpressOfficeFileAPI是一个专为C#,VB.NET和ASP.NET等开发人员提供的非可视化......
  • The 2nd Universal Cup. Stage 5: Northern J Sets May Be Good
    题解我们考虑计算\(\sum_{S\subseteq\{1,2,3,\cdots,n\}}(-1)^{cnt(S)}\),这里\(cnt(S)\)表示\(S\)集合的导出子图的边数。我们记\(x_i=[i\inS]\)。我们考虑删掉\(n\)号点。注意到如果\(x_i\)的取值会影响\(cnt(s)\)的奇偶性,则正负相消,贡献为\(0\)。所以我们需......
  • 常用JS加密/解密类型以及案例
    简介这里给大家汇总常用不常用的JS加密案例,免得大家用的时候到处去找例子。正题对称加密:替代字符表示法:使用Base64或类似的编码对数据进行简单的转换,不过这并不是真正的加密,而只是一种表示形式的转换。<!DOCTYPEhtml><html><body><h2>Base64编码示例</h2><p>原始文本:Hello......
  • app直播源码,android AES加密解密实现
     app直播源码,androidAES加密解密实现importandroid.util.Base64;importandroid.util.Log; importjava.security.Key; importjavax.crypto.Cipher;importjavax.crypto.SecretKeyFactory;importjavax.crypto.spec.DESedeKeySpec;importjavax.crypto.spec.IvParameterSpe......
  • c# RSA相关 加密 签名 PEM - XML互相转换
    安装nugetPortable.BouncyCastleusingOrg.BouncyCastle.Asn1.Pkcs;usingOrg.BouncyCastle.Asn1.X509;usingOrg.BouncyCastle.Crypto;usingOrg.BouncyCastle.Crypto.Parameters;usingOrg.BouncyCastle.Math;usingOrg.BouncyCastle.Pkcs;usingOrg.BouncyCastle.Se......
  • Erlang 使用rsa不对称密钥进行签名和验签
    背景:合作方要求使用rsa(sha256)不对称密钥进行签名和验签erlang版本:OTP20.3使用工具生成rsa密钥对(自行百度)获得一个公钥和私钥公钥内容如:-----BEGINPUBLICKEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApiwI+2ZT0eWUiLQ1p6JVKv70ae...-----ENDPUBLICKEY-----......