JAVA 解密被密码保护的pem私钥文件

这篇具有很好参考价值的文章主要介绍了JAVA 解密被密码保护的pem私钥文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0、说明:只能读取PKCS8格式的加密私钥

JAVA 解密被密码保护的pem私钥文件

1、解密使用的依赖:

        <!-- RAS私钥解密相关 -->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.68</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>1.68</version>
        </dependency>
        <!-- 工具 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.22</version>
        </dependency>

JAVA版本:1.8.0_261

SpringBoot版本:2.6.4

2、代码:

读取PKCS8格式的秘钥


    private static final String PRIVATE_KEY_FILE = "prikey.pem";

    /**
     * 读取带密码保护的私钥文件
     * @param passwd 保护密码
     * @return 私钥的byte数组,可以通过Base64编码转为字符串
     */
    public static byte[] readPrivateKeyFromPem(String passwd) throws Exception {
        File file = ResourceUtils.getFile("classpath:".concat(PRIVATE_KEY_FILE));
        String encrypted = FileUtil.readString(file, StandardCharsets.UTF_8);
        // 读取带密码保护的私钥:https://cloud.tencent.com/developer/article/2186682?from=15425
        PrivateKeyInfo pki;
        try (PEMParser pemParser = new PEMParser(new StringReader(encrypted))) {
            Object o = pemParser.readObject();
            PKCS8EncryptedPrivateKeyInfo epki = (PKCS8EncryptedPrivateKeyInfo) o;
            // 手动添加BC的安全模式:https://blog.csdn.net/Roy_70/article/details/70842322
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            JcePKCSPBEInputDecryptorProviderBuilder builder =
                    new JcePKCSPBEInputDecryptorProviderBuilder().setProvider("BC");
            InputDecryptorProvider idp = builder.build(passwd.toCharArray());
            pki = epki.decryptPrivateKeyInfo(idp);
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
            return converter.getPrivateKey(pki).getEncoded();
        }
     }

秘钥文件放置在模块的resource目录下,也可以自行更改文件读取方式

3、另外附上自己写的完整的RSA分段加解密

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.operator.InputDecryptorProvider;
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;

import org.bouncycastle.pkcs.jcajce.JcePKCSPBEInputDecryptorProviderBuilder;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Arrays;

public class RsaBigDataUtil {

    private static final String PUBLIC_KEY_FILE = "pubkey.pem";
    private static final String PRIVATE_KEY_FILE = "prikey.pem";

    /**
     * 私钥分段解密
     *
     * @param privateKey 私钥
     * @param context    密文
     * @param len        公钥长度
     * @return 解密后的明文比特流
     */
    public static byte[] decrypt(byte[] privateKey, byte[] context, int len) {
        RSA rsa = new RSA(privateKey, null);
        ByteBuffer srcByteBuffer = ByteBuffer.wrap(context);
        int splitCount = (int) Math.ceil((double) context.length / (double) (len * 2));        // 向上取整得分段数
        ByteBuffer resByteBuffer = ByteBuffer.allocate(splitCount * len);
        int splitIndex = 1;
        int length = 0;
        while (splitIndex <= splitCount) {
            // 当本次被解密数据的最后一位长度扩张后会超过缓冲区长度的时候减小数据容器的长度
            byte[] temp_mi = new byte[srcByteBuffer.limit() < splitIndex * len * 2 ? len : len * 2];
            srcByteBuffer.get(temp_mi, 0, temp_mi.length);
            byte[] temp_min = rsa.decrypt(temp_mi, KeyType.PrivateKey);
            resByteBuffer.put(temp_min, 0, temp_min.length);
            length += temp_min.length;
            splitIndex++;
        }
        return Arrays.copyOfRange(resByteBuffer.array(), 0, length);
    }

    /**
     * 公钥分段加密
     *
     * @param publicKey 公钥
     * @param context   明文
     * @param len       公钥长度
     * @return 加密后的密文比特数组
     */
    public static byte[] encrypt(byte[] publicKey, byte[] context, int len) {
        RSA rsa = new RSA(null, publicKey);
        ByteBuffer srcByteBuffer = ByteBuffer.wrap(context);
        int splitCount = (int) Math.ceil((double) context.length / (double) len);
        // 由于加密后密文会膨胀,但最大大小是切片数*两倍的块大小
        ByteBuffer resByteBuffer = ByteBuffer.allocate(splitCount * len * 2);
        int splitIndex = 1;
        int length = 0;
        while (splitIndex <= splitCount) {
            byte[] temp_min = new byte[splitCount == splitIndex ? (context.length - (splitCount - 1) * len) : len];
            srcByteBuffer.get(temp_min, 0, temp_min.length);
            byte[] temp_mi = rsa.encrypt(temp_min, KeyType.PublicKey);
            resByteBuffer.put(temp_mi, 0, temp_mi.length);
            length += temp_mi.length;
            splitIndex++;
        }
        return Arrays.copyOfRange(resByteBuffer.array(), 0, length);
    }

    /**
     * 读取公钥文件
     * @return 公钥的byte数组,可以通过Base64编码转为字符串
     * */
    public static byte[] readPublicKeyFromPem() throws Exception {
        File file = ResourceUtils.getFile("classpath:".concat(PUBLIC_KEY_FILE));
        String encrypted = FileUtil.readString(file, StandardCharsets.UTF_8);
        encrypted = encrypted.replace("-----BEGIN PUBLIC KEY-----","");
        encrypted = encrypted.replace("-----END PUBLIC KEY-----","");
        return Base64Decoder.decode(encrypted);
    }

    /**
     * 读取带密码保护的私钥文件
     * @param passwd 保护密码
     * @return 私钥的byte数组,可以通过Base64编码转为字符串
     */
    public static byte[] readPrivateKeyFromPem(String passwd) throws Exception {
        File file = ResourceUtils.getFile("classpath:".concat(PRIVATE_KEY_FILE));
        String encrypted = FileUtil.readString(file, StandardCharsets.UTF_8);
        // 读取带密码保护的私钥:https://cloud.tencent.com/developer/article/2186682?from=15425
        PrivateKeyInfo pki;
        try (PEMParser pemParser = new PEMParser(new StringReader(encrypted))) {
            Object o = pemParser.readObject();
            PKCS8EncryptedPrivateKeyInfo epki = (PKCS8EncryptedPrivateKeyInfo) o;
            // 手动添加BC的安全模式:https://blog.csdn.net/Roy_70/article/details/70842322
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            JcePKCSPBEInputDecryptorProviderBuilder builder =
                    new JcePKCSPBEInputDecryptorProviderBuilder().setProvider("BC");
            InputDecryptorProvider idp = builder.build(passwd.toCharArray());
            pki = epki.decryptPrivateKeyInfo(idp);
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
            return converter.getPrivateKey(pki).getEncoded();
        }
    }
}

代码只实现了基础功能,还有很多不足,欢迎各位大佬指正

4、附上一个基础的使用案例

    void encrypt() throws Exception {
        String content = "114514";
        System.out.println("原文:"+content);
        byte[] mi = RsaBigDataUtil.encrypt(RsaBigDataUtil.readPublicKeyFromPem(), content.getBytes(StandardCharsets.UTF_8), 256);
        String base64 = Base64Encoder.encode(mi);
        System.out.println("加密:"+base64);
        byte[] min = RsaBigDataUtil.decrypt(RsaBigDataUtil.readPrivateKeyFromPem("yourPasswd"),mi,256);
        System.out.println("解密:"+new String(min, StandardCharsets.UTF_8));
    }

测试用的密钥对可以在RSA加密/解密 - 在线工具 (try8.cn)在线生成

JAVA 解密被密码保护的pem私钥文件

下载好的秘钥放置在项目的resource目录下(或者自己重写文件读取方法)

JAVA 解密被密码保护的pem私钥文件

记得将代码中的文件名替换为自己的 

JAVA 解密被密码保护的pem私钥文件文章来源地址https://www.toymoban.com/news/detail-459948.html

到了这里,关于JAVA 解密被密码保护的pem私钥文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 密码管家:保护你的密码安全的最佳选择

    在现代社会中,我们每个人都面临着一个共同的问题:账号密码太多,记不住。同时,我们也担心密码泄露,导致个人信息的安全受到威胁。为了解决这些问题,我向大家推荐一款最专业安全的本地密码管理工具——密码管家。 密码管家是一款简单实用的专业密码管理软件,

    2024年02月09日
    浏览(32)
  • Excel表格密码保护解除

    表格受密码保护时,我们修改数据Excel弹出“您试图更改的单元格或图表受保护,因而是只读的。 若要修改受保护单元格或图表,请先使用‘撤消工作表保护’命令(在‘审阅’选项卡的‘更改’组中)来取消保护。 可能会提示输入密码。这时候我们可以用VBA宏代码破解法来破

    2024年02月06日
    浏览(26)
  • Excel去除表格密码保护

    表格受密码保护时,我们修改数据Excel弹出“您试图更改的单元格或图表受保护,因而是只读的。 若要修改受保护单元格或图表,请先使用‘撤消工作表保护’命令(在‘审阅’选项卡的‘更改’组中)来取消保护。 可能会提示输入密码。这时候我们可以用VBA宏代码破解法来破

    2024年02月16日
    浏览(67)
  • 私密相册管家-加密码保护私人相册照片安全

    App Store史上最安全、最强大、最卓越的私密相册App!再也不用担心私密照片视频被别人看见了!
私密相册为你提供多重密码保护机制、简单便捷的照片存储空间,完美地将你的私密照片远离一切恶意偷窥者的窥探!  【产品功能】
 √ 支持登陆密码:没有你的密码,任何

    2024年02月12日
    浏览(30)
  • 加固密码安全:保护您的个人信息

    一、引言 在数字化时代,密码安全是保护个人信息和数据的重要环节。然而,许多人在创建和管理密码时存在一些常见的安全漏洞,如使用弱密码、重复使用密码等。本文将详细介绍密码安全的重要性,并提供一些有效的方法和技巧,帮助您加固密码安全,保护个人信息不被

    2024年01月21日
    浏览(41)
  • 密码学的社会网络:如何保护社交网络的安全

    社交网络已经成为了现代人们生活中不可或缺的一部分,它们为我们提供了一种与家人、朋友和同事保持联系的方式。然而,这种联系也带来了一些挑战,因为社交网络上的数据经常被盗、篡改或泄露。因此,保护社交网络的安全至关重要。 在这篇文章中,我们将探讨密码学

    2024年02月20日
    浏览(51)
  • 如何在NodeJs中使用Bcrypt来保护用户密码

            不管你给你的程序进行了多少加密,黑客都可能有一万种办法黑进你的数据库。一个成熟的软件必须要有额外的加密系统。这样,即使数据库真的被攻破,我们也可以更好地保护我们的用户信息。这就是Bcrypt的作用,加盐salt和散列hash 注意:本文仅仅讲解Bcrypt的作用

    2024年02月09日
    浏览(36)
  • 读所罗门的密码笔记14_数据隐私保护

    1.2.6.1.            将数据隐私作为除了自己的公司和他对抓捕坏人的热情以外的又一追求目标 2.3.3.1.            随着认知机器进一步融入我们的生活,这种困境只会加剧,还会导致新的两难局面 2.3.3.2.            如果没有想清楚这些问题和其他代表性问题,

    2024年04月09日
    浏览(29)
  • 保护网络安全的新方法:密码技术创新与发展

           随着互联网的日益普及,我们的生活和工作越来越离不开网络。然而,随着互联网的发展,网络安全问题也逐渐变得越来越严重。在这样的背景下,密码技术和加密技术显得尤为重要。不同于传统的加密技术,现代的密码技术和加密技术已经投入大量的研究,旨在提

    2024年02月04日
    浏览(29)
  • 密码安全:保护你的数据不被入侵的重要性

    在数字时代,密码安全是保护个人和机构数据的关键。然而,不安全的密码可能导致严重的后果,包括个人隐私泄露、金融损失和声誉受损等。本文将探讨密码安全的重要性,揭示不安全密码的危害,列举一些因密码不安全而发生的真实事件,介绍安全的密码特征以及不安全

    2024年03月09日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包