如何在 Java 中解密 PEM 格式的密码保护私钥
发布时间 - 2026-01-22 00:00:00 点击率:次本文详解如何正确解析并解密 aws 导出的、以 pem 封装的密码加密私钥(begin encrypted private key),避免因直接使用 base64 原文导致的 der 解析异常(如 `ioexception: extra data given to dervalue constructor`)。
在使用 AWS ACM 导出证书时,私钥默认以 PEM 格式导出,并采用 PKCS#8 加密标准(即 -----BEGIN ENCRYPTED PRIVATE KEY----- 开头),其内容为 Base64 编码的 DER 结构。关键错误在于:直接对原始 PEM 字符串调用 getBytes() 并传入 EncryptedPrivateKeyInfo 构造器——这会将 PEM 头尾和换行符一并作为 DER 输入,导致 ASN.1 解析失败(报错 extra data given to DerValue constructor)。
正确做法是先剥离 PEM 封装,提取纯 DER 字节内容

org.bouncycastle bcprov-jdk15on1.70 org.bouncycastle bcpkix-jdk15on1.70
以下是完整、健壮的解密方法实现:
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.pkcs.*;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.io.*;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.KeySpec;
public PrivateKey readPrivateKey(String privateKeyPem, String passphrase) throws Exception {
// 1. 使用 PemReader 提取 PEM 内容(自动跳过头尾与换行)
try (PemReader pemReader = new PemReader(new StringReader(privateKeyPem))) {
PemObject pemObject = pemReader.readPemObject();
if (pemObject == null || !"ENCRYPTED PRIVATE KEY".equals(pemObject.getType())) {
throw new IllegalArgumentException("Invalid PEM type: expected 'ENCRYPTED PRIVATE KEY'");
}
// 2. 获取原始 DER 字节(已解码 Base64)
byte[] derBytes = pemObject.getContent();
// 3. 构建 EncryptedPrivateKeyInfo(此时输入为纯净 DER)
EncryptedPrivateKeyInfo encryptedInfo = new EncryptedPrivateKeyInfo(derBytes);
// 4. 初始化解密 Cipher
String algName = encryptedInfo.getAlgName();
Cipher cipher = Cipher.getInstance(algName);
PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algName);
cipher.init(Cipher.DECRYPT_MODE,
keyFactory.generateSecret(keySpec),
encryptedInfo.getAlgParameters());
// 5. 解密并生成 PrivateKey
KeySpec pkcs8KeySpec = encryptedInfo.getKeySpec(cipher);
KeyFactory kf = KeyFactory.getInstance("RSA"); // 若为 EC 私钥,改为 "EC"
return kf.generatePrivate(pkcs8KeySpec);
}
}⚠️ 注意事项:
- 密钥类型适配:若导出的是 ECC 证书(如 secp256r1),需将 KeyFactory.getInstance("RSA") 替换为 KeyFactory.getInstance("EC");Bouncy Castle 也支持 "ECDSA" 别名。
- 密码编码:确保 passphrase 与 AWS 导出时输入的密码完全一致(区分大小写、空格、特殊字符)。
- 异常处理:生产环境应捕获具体异常(如 InvalidKeySpecException, BadPaddingException)并提供有意义的错误提示,而非静默吞掉异常。
-
Bouncy Castle 注册(可选但推荐):若使用较新 JDK,建议显式注册 BC 提供者:
Security.addProvider(new BouncyCastleProvider());
该方案通过标准 PEM 解析流程,严格遵循 PKCS#8 加密私钥规范,彻底规避了原始代码中因 PEM/DER 混淆引发的 ASN.1 解析错误,适用于所有符合 RFC 7468 的加密私钥导入场景。
# java
# 编码
# 字节
# ssl
# crypto
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】
Laravel如何生成和使用数据填充?(Seeder和Factory示例)
如何在IIS7中新建站点?详细步骤解析
Laravel如何保护应用免受CSRF攻击?(原理和示例)
今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】
教你用AI将一段旋律扩展成一首完整的曲子
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
如何快速登录WAP自助建站平台?
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
Python文件流缓冲机制_IO性能解析【教程】
音乐网站服务器如何优化API响应速度?
iOS发送验证码倒计时应用
如何为不同团队 ID 动态生成多个独立按钮
JavaScript如何实现类型判断_typeof和instanceof有什么区别
如何用PHP快速搭建高效网站?分步指南
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
微信小程序 HTTPS报错整理常见问题及解决方案
高防服务器租用如何选择配置与防御等级?
HTML 中动态设置元素 name 属性的正确语法详解
昵图网官方站入口 昵图网素材图库官网入口
如何在IIS管理器中快速创建并配置网站?
Android中AutoCompleteTextView自动提示
javascript基于原型链的继承及call和apply函数用法分析
奇安信“盘古石”团队突破 iOS 26.1 提权
使用C语言编写圣诞表白程序
Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】
详解Huffman编码算法之Java实现
制作旅游网站html,怎样注册旅游网站?
百度浏览器网页无法复制文字怎么办 百度浏览器复制修复
Python高阶函数应用_函数作为参数说明【指导】
网站建设要注意的标准 促进网站用户好感度!
Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程
Win11怎么设置默认图片查看器_Windows11照片应用关联设置
如何在万网开始建站?分步指南解析
Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)
Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势
太平洋网站制作公司,网络用语太平洋是什么意思?
Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】
Laravel distinct去重查询_Laravel Eloquent去重方法
Laravel怎么判断请求类型_Laravel Request isMethod用法
千库网官网入口推荐 千库网设计创意平台入口
如何在景安云服务器上绑定域名并配置虚拟主机?
Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
无锡营销型网站制作公司,无锡网选车牌流程?
高端智能建站公司优选:品牌定制与SEO优化一站式服务
Android实现代码画虚线边框背景效果
如何在IIS中新建站点并配置端口与物理路径?
深圳网站制作平台,深圳市做网站好的公司有哪些?

