没有 JCE 的 Java 中的 S/MIME

Posted

技术标签:

【中文标题】没有 JCE 的 Java 中的 S/MIME【英文标题】:S/MIME in Java without JCE 【发布时间】:2011-01-14 10:50:38 【问题描述】:

我正在尝试编写一个可以使用 S/MIME 签署电子邮件的小程序。

显然我想用只需要的东西制作一个小罐子。 显然,Java 的做法涉及到周围有一个巨大的神圣签名 Bouncy Castle JCE 罐子。

问题是:获得 S/MIME 的最简单方法是什么,而无需接触 JCE 并让它抱怨“身份验证”“提供者”?也许有一个不依赖于 JCE 的 S/MIME 实现?也许可以在不接触 JCE 的情况下使用 Bouncy Castle S/MIME 使用他们的轻量级 API?或许还有其他办法?

对我来说很明显,无论 Sun 是否批准,没有什么可以阻止纯 Java 开源加密算法的工作,所以这不是理论上的可能性问题,而是:哪种方式最不痛苦?

当然,我总是可以通过获取 Bouncy Castle 纯 Java JCE 实现、将其包重命名为 java.security1 并进行任何我想要的更改来尽早变得丑陋 - 但这种方式现在看起来太痛苦了。

更新我目前直接使用 Bouncy Castle 的问题:我尝试从密钥库加载密钥,这涉及使用 SecretKeyFactory,这反过来又拒绝了我的 Bouncy Castle 构建。

【问题讨论】:

【参考方案1】:

BC S/MIME 是在 CMS 包上编写的,因此问题真正转移到修改 CMS 包上,以便所有加密都使用轻量级类完成。

已经为 .NET 版本的 Bouncy Castle 做过类似的事情,或多或少成功。我们正在尝试(诚然这是一个缓慢的过程)重构 Java 版本,以便 CMS 的东西可以与 JCE 或轻量级一起使用。同样的问题也会影响 BC API 的其他部分,例如PKCS#12 密钥库内置在 JCE 提供程序中,OpenPGP 包被写入 JCE 等。这些的 .NET 端口也将它们重写为轻量级 API。

不过,您的问题可能比一般情况更简单。大概您只需要 CMSSignedDataGenerator 和支持类。您可能不需要 addSigner 或 generate 的所有无数变体。如果您只是预先决定您的摘要/签名算法,那么所有提供者的东西都可以很容易地用对特定轻量级实现的硬编码调用来替换。

也许您可以不使用密钥库,而是将单个私钥存储在 PKCS#8 文件(也许是 PEM 编码)中。证书也是如此。

【讨论】:

是的,我可以在不使用 JCE 的情况下轻松签署消息。真正的问题是读取 PKCS#12 密钥。我会在那里描述它。【参考方案2】:

在不使用 JCE 的情况下签署消息非常简单。 真正的问题是读取 PKCS#12 密钥。

我这样做了: * 将 JDKPKCS12KeyStore 类复制过来。 * 在其中的任何地方,将 Security.getInstance() 替换为 bcProvider.getService().newInstance() (返回 Spi-s) * 在那些 Spi-s(在 BC 来源)中,将所需的方法公开而不是受保护。

它看起来像一个 hack,但似乎确实有效。

【讨论】:

以上是关于没有 JCE 的 Java 中的 S/MIME的主要内容,如果未能解决你的问题,请参考以下文章

(java加密解密)如何实现JCE接口的各种算法??

启动时服务中的NoClassDefFoundError。 jce_policy-8.zip是安全的罪魁祸首吗?

Java - 使用 JavaMail 发送和接收 S/MIME 消息

jce_policy安装java密码扩展无限制权限策略文件安装

java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider解决方法

Java服务部署规范(内部使用)