以编程方式将 PEM 证书导入 Java KeyStore

2024-05-10

我有一个由两个文件(.crt 和 .key)组成的客户端证书,我希望将其导入到 java KeyStore 中,然后在 SSLContext 中使用,以通过 Apache 的 HTTPClient 发送 HTTP 请求。但是,我似乎找不到一种以编程方式执行此操作的方法,我发现的大多数其他问题要么指向外部工具,要么不适合我的情况。

我的证书使用典型的“BEGIN CERTIFICATE”进行编码,后跟 Base64 编码字符串,密钥采用“BEGIN RSA PRIVATE KEY”,然后是另一个 Base64 编码字符串。

这是我到目前为止得到的:

private static SSLContext createSSLContext(File certFile, File keyFile) throws IOException {
    try {
        PEMParser pemParser = new PEMParser(new FileReader(keyFile));
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(new BouncyCastleProvider());
        Object object = pemParser.readObject();
        KeyPair kp = converter.getKeyPair((PEMKeyPair) object);
        PrivateKey privateKey = kp.getPrivate();

        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        FileInputStream stream = new FileInputStream(certFile);
        X509Certificate cert = (X509Certificate) certFactory.generateCertificate(stream);

        KeyStore store = KeyStore.getInstance("JKS");
        store.load(null);
        store.setCertificateEntry("certificate", cert);
        store.setKeyEntry("private-key", privateKey, "changeit".toCharArray(), new Certificate[] { cert });

        SSLContext sslContext = SSLContexts.custom()
                .loadKeyMaterial(store, "changeit".toCharArray())
                .build();
        return sslContext;
    } catch (IOException | NoSuchAlgorithmException | CertificateException | KeyStoreException | KeyManagementException | UnrecoverableKeyException e) {
        throw new IOException(e);
    }
}

堆栈跟踪:

java.io.IOException:java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:无效的密钥格式 在 me.failedshack.ssltest.SSLTest.createSSLContext(SSLTest.java:80) 在 me.failedshack.ssltest.SSLTest.main(SSLTest.java:31)

引起原因:java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:无效的密钥格式 在 java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:216) 在 java.base/java.security.KeyFactory.generatePrivate(KeyFactory.java:390) 在 me.failedshack.ssltest.SSLTest.createSSLContext(SSLTest.java:62) ... 1 更多

引起原因:java.security.InvalidKeyException:密钥格式无效 在 java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:330) 在 java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:355) 在 java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.(RSAPrivateCrtKeyImpl.java:91) 在 java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75) 在 java.base/sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:315) 在 java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:212) ... 3 更多

遗憾的是,当我从文件生成私钥时,我不断收到 InvalidKeyException 异常。


类型的 PEM 文件RSA PRIVATE KEY是 base64 不是二进制,更重要的是采用 PKCS1 格式而不是 PKCS8,因此不能作为PKCS8EncodedKeySpec.

您的选择是:

  • 将 PKCS1 PEM 格式转换为 PKCS8(未加密)PEM 格式;读取该内容并删除标头和尾部行,将 Base64 解码为二进制并将其放入PKCS8EncodedKeySpec-- 但你说你不需要外部工具,而且将私钥 PLUS 证书(或链)转换为 PKCS12 (DER) 也同样容易alreadyJava 密钥库并避免该问题

  • 将 PKCS1 PEM 格式转换为 PKCS8(未加密)DER 格式,您可以将其作为二进制读取并放入PKCS8EncodedKeySpec——同上

  • 如果 PKCS1 PEM 未加密,请按照上述方式将其读取并解码为 PKCS1 DER,然后手动构建 PKCS8(未加密)编码,并使用该编码

  • 如果 PKCS1 PEM 已加密(您可以检测到它,因为除了 base64 之外,它的主体还包含两个 822 样式的标题行),您必须复制 OpenSSL 的“旧版”密钥文件解密,再加上构建 PKCS8(未加密)编码

  • 如果你可以专门使用 BouncyCastlebcpkix,可以直接读取解析allOpenSSL 用于私钥的 PEM 变体,包括解密加密的私钥;但是,如果您尚未使用它,则需要安装和/或部署一个额外的 jar

查看以下一个或多个骗局:
加载证书到KeyStore (JAVA) https://stackoverflow.com/questions/50514553/load-certificate-to-keystore-java(Q使用BouncyCastle构建PKCS8)
Java:将 DKIM 私钥从 RSA 转换为 JavaMail 的 DER https://stackoverflow.com/questions/23709898/java-convert-dkim-private-key-from-rsa-to-der-for-javamail(我的答案“手动”构造 PKCS8)
如何从文件加载 RSA 私钥 https://stackoverflow.com/questions/3243018/how-to-load-rsa-private-key-from-file(使用 BouncyCastle 阅读)
JAVA读取PKCS1格式的RSA私钥 https://stackoverflow.com/questions/41934846/read-rsa-private-key-of-format-pkcs1-in-java(使用 BouncyCastle 阅读)
从 RSA .pem 文件获取私钥 https://stackoverflow.com/questions/44681737/get-a-privatekey-from-a-rsa-pem-file(使用BC解密)
使用 Java 解密 OpenSSL PEM 编码的 RSA 私钥? https://stackoverflow.com/questions/35276820/decrypting-an-openssl-pem-encoded-rsa-private-key-with-java(手动解密)
maybe RSA 私钥的 PKCS#1 和 PKCS#8 格式 https://stackoverflow.com/questions/48958304/pkcs1-and-pkcs8-format-for-rsa-private-key(背景)
and “BEGIN RSA PRIVATE KEY”和“BEGIN PRIVATE KEY”之间的区别 https://stackoverflow.com/questions/20065304/differences-between-begin-rsa-private-key-and-begin-private-key(背景)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以编程方式将 PEM 证书导入 Java KeyStore 的相关文章

  • 如何创建一个显示 Spinners 的 x 和 y 值的表格?

    我想创建一个位于图表右侧的表格 其中显示 2 列 x 和 y 值已输入到xSpin and ySpin旋转器 我已经画了一张我想要桌子放置的位置的图 我尝试过在网格窗格布局中使用文本框来创建表格并将值直接输入到文本框网格中 但是我无法将它们
  • 是什么决定了从 lambda 创建哪个函数式接口?

    请考虑这个例子 import java util function Consumer public class Example public static void main String args Example example new
  • 正则表达式拆分数字和字母组,不带空格

    如果我有一个像 11E12C108N 这样的字符串 它是字母组和数字组的串联 如何在中间没有分隔符空格字符的情况下分割它们 例如 我希望分割结果为 tokens 0 11 tokens 1 E tokens 2 12 tokens 3 C
  • 从 HTTP 登录到 HTTPS

    我的网站默认使用 HTTP 我确实有一个启用 HTTPS 的证书 但只有其上的某些区域强制建立安全连接 登录是通过 Ajax 处理的 我想开始使用 SSL 即使请求来自 HTTP 我尝试强制请求的地址具有 HTTPS 并且它完美地回复 然而
  • 运行具有外部依赖项的 Scala 脚本

    我在 Users joe scala lib 下有以下 jar commons codec 1 4 jar httpclient 4 1 1 jar httpcore 4 1 jar commons logging 1 1 1 jar ht
  • Cassandra java驱动程序协议版本和连接限制不匹配

    我使用的java驱动程序版本 2 1 4卡桑德拉版本 dsc cassandra 2 1 10cql 的输出给出以下内容 cqlsh 5 0 1 Cassandra 2 1 10 CQL spec 3 2 1 Native protocol
  • Java 文件上传速度非常慢

    我构建了一个小型服务 它从 Android 设备接收图像并将其保存到 Amazon S3 存储桶中 代码非常简单 但是速度非常慢 事情是这样的 public synchronized static Response postCommentP
  • 画透明圆,外面填充

    我有一个地图视图 我想在其上画一个圆圈以聚焦于给定区域 但我希望圆圈倒转 也就是说 圆的内部不是被填充 而是透明的 其他所有部分都被填充 请参阅这张图片了解我的意思 http i imgur com zxIMZ png 上半部分显示了我可以
  • hibernate锁等待超时超时;

    我正在使用 Hibernate 尝试模拟对数据库中同一行的 2 个并发更新 编辑 我将 em1 getTransaction commit 移至 em1 flush 之后我没有收到任何 StaleObjectException 两个事务已成
  • 在 Netbeans 8 上配置 JBoss EAP 的问题

    我已经下载了 JBoss EAP 7 并正在 Netbeans 8 上配置它 我已经到达向导 实例属性 其中要求从选择框中选择 域 当我打开选择框时 它是空的 没有什么可以选择的 因此 完成 按钮也处于非活动状态 这使得无法完成配置 我通过
  • Java 8 流 - 合并共享相同 ID 的对象集合

    我有一系列发票 class Invoice int month BigDecimal amount 我想合并这些发票 这样我每个月都会收到一张发票 金额是本月发票金额的总和 例如 invoice 1 month 1 amount 1000
  • 具有 java XSLT 扩展的数组

    我正在尝试使用 java 在 XSLT 扩展中使用数组 我收到以下错误 Caused by java lang ClassCastException org apache xpath objects XObject cannot be ca
  • 将 SignedHash 插入 PDF 中以进行外部签名过程 -workingSample

    遵循电子书第 4 3 3 节 PDF 文档的数字签名 https jira nuxeo com secure attachment 49931 digitalsignatures20130304 pdf 我正在尝试创建一个工作示例 其中 客
  • 编辑文件名在 JComboBox 中的显示方式,同时保持对文件的访问

    我对 Java 很陌生 对堆栈溢出也很陌生 我正在尝试利用 JMF API 创建一个用 Java 编码的简单媒体播放器 到目前为止 我已经能够设置一个简单的队列 播放列表来使用JComboBox called playListHolder
  • 有没有一种快速方法可以从 Jar/war 中删除文件,而无需提取 jar 并重新创建它?

    所以我需要从 jar war 文件中删除一个文件 我希望有类似 jar d myjar jar file I donot need txt 的内容 但现在我能看到从 Linux 命令行执行此操作的唯一方法 不使用 WinRAR Winzip
  • Struts 2 + Sitemesh 3 集成 - FreemarkerDecoratorServlet 中的 NPE

    我将 Struts 2 版本 2 3 14 3 与 Sitemesh 3 版本 3 0 alpha 2 一起使用 并且在某些情况下遇到 NullPointerException 首先 这是我的 web xml 中的 struts2 site
  • 如何在JSTL中调​​用java方法? [复制]

    这个问题在这里已经有答案了 这可能是重复的问题 我只想调用不是 getter 或 setter 方法的方法例如 xyz 类的 makeCall someObj stringvalue Java类 Class XYZ public Strin
  • Netty:阻止调用以获取连接的服务器通道?

    呼吁ServerBootstrap bind 返回一个Channel但这不是在Connected状态 因此不能用于写入客户端 Netty 文档中的所有示例都显示写入Channel从它的ChannelHandler的事件如channelCon
  • Trie 数据结构 - Java [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 是否有任何库或文档 链接提供了在 java 中实现 Trie 数据结构的更多信息 任何帮助都会很棒 Thanks 你可以阅读Java特里树
  • ServletContainer 类未找到异常

    我无法再编译我的球衣项目 并且出现以下异常 GRAVE Servlet Project API threw load exception java lang ClassNotFoundException com sun jersey spi

随机推荐

  • MVC3 中的 ModelState.IsValid 与 IValidatableObject

    所以根据Gu http weblogs asp net scottgu archive 2010 07 27 introducing asp net mvc 3 preview 1 aspx IValidatableObject Valid
  • 如何创建新的私人文本频道并向其中添加 2 个人?

    我正在创建一个不和谐的机器人 用户将向机器人发送消息并 机器人将创建一个新的私人文本通道 最好与机器人位于同一服务器上 机器人只会将消息传递用户和管理员添加到频道 我已经能够使用创建一个新频道这个问题 https stackoverflow
  • 日期减去 xslt 中的另一个日期

    希望有人能帮忙 我正在尝试比较 XML 文件中的 2 个日期并使用 XSLT 进行一些计算 例如 我有 2 个 XML 日期 2011 05 23 和 2011 04 29 我想在 XSLT 中进行计算 如下所示 2011 05 23 20
  • V8 如何管理它的堆?

    我知道V8的垃圾收集在工作时 会从GC的root开始追踪 这样无法到达的对象就会被标记然后被清除 我的问题是GC是如何遍历那些对象的 必须有一个数据结构来存储所有可达或不可达的对象 位图 链接表 顺便说一句 JVM 也做同样的事情吗 艾伦秀
  • 为什么单击拖动手柄不会夺走文本焦点?

    我有一个带有一些文本的 divhttp jsfiddle net MuCeD 2 http jsfiddle net MuCeD 2 如果我双击 div 中的 sample 一词 它就会突出显示 如果我然后单击页面上的其他任何位置 文本就会
  • Python 在 anaconda 中找不到 h2o 包

    当我尝试导入 h2o 时 我被告知该包不存在 当我尝试安装它时 它告诉我它已经存在 我尝试将其从计算机中删除并重新安装 但没有成功 此时我能想到的只是一些环境变量 C Users Lanier Anaconda2 C Users Lanie
  • JPanel透明背景和显示元素[重复]

    这个问题在这里已经有答案了 我插入一个背景图e 变成 aJPanel但一些界面元素消失了 以下 Java Swing 元素不会出现 标签标题 标签 usuario 标签 密码 按钮加速器 你能否使图像透明或元素不透明 setOpaque f
  • 修复 JSLint“意外的‘this’。”错误?

    我试图让以下代码成为符合 jslint 标准 http jslint com 但我陷入以下两个错误 本来应该看到一个声明 结果却看到了一个块 and 意想不到的 这个 我应该对我的代码进行哪些更改才能使 JSLint 满意 var pvAc
  • 修复了当 CSS 过滤器应用于 Microsoft Edge 中的同一元素时不起作用的位置

    我正在 Edge 20 10240 16384 0 上测试这个 我有一个位置固定的元素 并且应用了 CSS 过滤器 这在除 Microsoft Edge 之外的所有浏览器中都非常有效 其中元素的位置不保持固定 此问题与 CSS3 过滤器直接
  • 如何使用 wampserver 在本地系统上将 URL 从“localhost”更改为其他内容?

    在 Windows 计算机上 有一个系统在本地 wampserver 上运行 但当应用程序在 localhost 上运行时 URL 却另有说明 虽然我希望基于目录结构的 URL 是这样的 http localhost pro include
  • MAC 上的 QT/C++ - 未设置应用程序图标

    我正在努力解决的奇怪问题 在与我的 pro QT 项目文件相同的文件夹中 我有一个 Resources myIcon png 我试图将其设置为我构建的应用程序的图标 在 OSX 上运行 我阅读了文档 它建议在 pro 文件中添加 ICON
  • Java Swing:清除JList而不触发监听器

    我的情况如下 我有一个 JList 只要在列表中进行选择 它就会触发搜索 使用 ListSelectionListener 我正在尝试使用以下命令重置列表上的选择list clearSelection 这样做的问题是使用clearSelec
  • 如何处理 ReST 中的两个破折号

    我正在使用 Sphinx 来记录用 Python 编写的命令行实用程序 我希望能够记录命令行选项 例如 region像这样 region
  • D3.js分组条形图

    I am making a bar chart using D3 js like this source statcan gc ca http www statcan gc ca pub 12 593 x 2007001 figures f
  • 如何在 firebase 中监视子子添加事件

    有没有办法用 firebase 监视 grandchild added 事件 我已经使用node js javascript 库为child added 设置了一个观察者 但是当添加子项的子项时它不会触发 我正在设置会员状态信息 并想知道用
  • 超时 jQuery 效果

    我试图让一个元素淡入 然后在 5000 毫秒内再次淡出 我知道我可以做类似的事情 setTimeout function notice fadeOut 5000 但这只会控制淡出 我会在回调中添加上述内容吗 Update 从 jQuery
  • 目前最好的 Javascript 模板引擎是什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 遏制gem安装:捆绑安装失败,但正常gem安装有效[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions solve
  • 如何使用修改后的索引来旋转 pandas 数据框?

    我有一个以下形式的时间序列数据框 rng pd date range 1 1 2013 periods 1000 freq 10min ts pd Series np random randn len rng index rng ts ts
  • 以编程方式将 PEM 证书导入 Java KeyStore

    我有一个由两个文件 crt 和 key 组成的客户端证书 我希望将其导入到 java KeyStore 中 然后在 SSLContext 中使用 以通过 Apache 的 HTTPClient 发送 HTTP 请求 但是 我似乎找不到一种以