【问题标题】:Cannot create instance of org.bouncycastle.jcajce.provider.digest.GOST3411$Mappings : java.lang.SecurityException无法创建 org.bouncycastle.jcajce.provider.digest.GOST3411$Mappings 的实例:java.lang.SecurityException
【发布时间】:2018-05-14 09:48:23
【问题描述】:

我正在编写一个程序,它有一个这样的静态块:

static
{
Security.addProvider(new BouncyCastleProvider());
}

在这里我得到一个例外:

Exception in thread "Launcher: JavaAgent" java.lang.InternalError: cannot create instance of org.bouncycastle.jcajce.provider.digest.GOST3411$Mappings : java.lang.SecurityException
    at org.bouncycastle.jce.provider.BouncyCastleProvider.loadAlgorithms(Unknown Source)
    at org.bouncycastle.jce.provider.BouncyCastleProvider.setup(Unknown Source)
    at org.bouncycastle.jce.provider.BouncyCastleProvider.access$000(Unknown Source)
    at org.bouncycastle.jce.provider.BouncyCastleProvider$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(AccessController.java:594)
    at org.bouncycastle.jce.provider.BouncyCastleProvider.<init>(Unknown Source)
    at JavaAgent.<clinit>(JavaAgent.java:46)
    at java.lang.J9VMInternals.newInstanceImpl(Native Method)
    at java.lang.Class.newInstance(Class.java:1899)
    at lotus.domino.AgentInfo.newInstance(Unknown Source)
    at lotus.domino.AgentLauncher.run(Unknown Source)
    at lotus.domino.NotesThread.run(Unknown Source)

我尝试了很多,包括在 java.security 文件中添加:"security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider"

我也尝试了 "permission java.security.SecurityPermission "putProviderProperty.BC";" 到 java.policy 文件。

但似乎没有什么能解决这个问题!我已将此添加到我 PC 上所有 JVM 的所有文件中。问题是我使用 IBM Domino/Notes 软件。可以在那里工作吗?我就是找不到问题..

【问题讨论】:

    标签: java lotus-notes bouncycastle lotus-domino securityexception


    【解决方案1】:

    所以我也遇到了这个错误,我能够找到解决它的方法,尽管它不是可扩展的方法。但是,如果您担心它仅适用于您的机器,那么此解决方案将适合您。

    为了让阅读此答案的其他人清楚,我们都在这里的原因是 IBM Notes (IBM Lotus Notes) 实际上运行在 Java 之上,特别是 Java 1.6(实际上是在 IBM J9 VM 上)。尽管 Notes 的大部分自定义代码都可以用 LotusScript(类似 VisualBasic 的变体)编写,但 Notes 允许您使用 Java 本身进行开发。这提供了极大的灵活性,但如果您的代码需要通过 HTTPS 进行任何通信并且您正在与之通信的服务器实现 TLS 1.2(2018 年此答案的现代标准),Java 1.6 does not natively support TLS 1.2 .那么有什么好办法呢? 3rd 方库,例如 Bouncy Castle。这把我们带到了这里。

    错误

    错误/堆栈跟踪是 exact 我得到的相同错误。它没有提供很多有意义的信息。所以我所做的是玩弄并稍微修改了 Bouncy Castle 源代码(特别是 BouncyCastleProvider.java)。它使用反射来实例化每个摘要/密码/等,我只是手动实例化每个类。您会看到它在 loadAlgorithms 方法中失败了。 loadAlgorithms 方法实例化一个类列表,然后在类上调用.configure() 方法,传入thisBouncyCastleProvider 类的一个实例。当我手动执行时,我重现了相同的错误,但是更多细节:

    java.lang.ExceptionInInitializerError
            at java.lang.J9VMInternals.initialize(J9VMInternals.java:222)
            at JavaAgent.NotesMain(Unknown Source)
            at lotus.domino.AgentBase.runNotes(Unknown Source)
            at lotus.domino.NotesThread.run(Unknown Source)
    Caused by: java.lang.SecurityException
            at java.lang.SecurityManager.checkPermission(SecurityManager.java:582)
            at COM.ibm.JEmpower.applet.AppletSecurity.checkSecurityPermission(AppletSecurity.java:1332)
            at COM.ibm.JEmpower.applet.AppletSecurity.checkPermission(AppletSecurity.java:1613)
            at COM.ibm.JEmpower.applet.AppletSecurity.checkPermission(AppletSecurity.java:1464)
            at java.lang.SecurityManager.checkSecurityAccess(SecurityManager.java:1725)
            at java.security.Provider.put(Provider.java:243)
            at ExplicitBouncyCastleProvider.addAlgorithm(Unknown Source)
            at org.bouncycastle.jcajce.provider.digest.GOST3411$Mappings.configure(Unknown Source)
            at ExplicitBouncyCastleProvider.setup(Unknown Source)
            at ExplicitBouncyCastleProvider.access$0(Unknown Source)
            at ExplicitBouncyCastleProvider$1.run(Unknown Source)
            at java.security.AccessController.doPrivileged(AccessController.java:202)
            at ExplicitBouncyCastleProvider.<init>(Unknown Source)
            at TLSSocketConnectionFactory.<clinit>(Unknown Source)
            at java.lang.J9VMInternals.initializeImpl(Native Method)
            at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
            ... 6 more
    

    现在我们可以进入每个提供者,在本例中是 GOST3411.Mappings 类(因为它是 Bouncy Castle 加载的第一个),并看到它在调用 java.security.Provider.put() 时失败,因为该方法有SecurityManager 可以防止这种情况发生。换句话说,Notes 具有安全性,不仅允许 Java 代理修改 Java 的安全性设置。

    如何修改 Notes 的 Java 安全设置

    你的回答已经暗示了如何去做,但我还需要做一些其他的事情。

    1. 在运行我的客户端的机器上,修改 \jvm\lib\security\java.security 文件以添加到列表中: security.provider.8=org.bouncycastle.jce.provider.BouncyCastleProvider

      (我选择 8 是因为我认为 security.provider.n 只支持 n=1 到 9,而且我没有使用 Apache Harmony,它在我的列表中排名第 8)。

    2. 将 BouncyCastle JAR 放在 \jvm\lib\ext 目录中。就我而言,我使用 Bouncy Castle 1.59 for Java 1.5 及更高版本,因此我在此目录中放置了 bcprov-jdk15on-159.jar 的副本。

    3. \jvm\lib\security\trusted.libraries 文件中,添加您刚刚放在 ext 目录中的 JAR 的 base-64 编码 SHA-1 哈希。我使用FCIV 生成文件的SHA-1 哈希(十六进制),然后使用any old online hex to base64 converter tool 将该十六进制值转换为base64。如果您在其上方也添加评论将会很有帮助,因此它就像此文件中的所有其他条目一样。

      # bcprov-jdk15on-159.jar
      SHA1-Digest-Manifest: JQcgQkGrRQRWvbjowKj5huQYvZk=
      

    现在,当您在 Java 代码中调用 HttpsURLConnection con = (HttpsURLConnection) urlObj.openConnection(); 时,它会自动找到这个 TLS 1.2 的 Bouncy Castle 提供程序,意识到它信任它,并使用 TLS 1.2 通过 HTTPS 打开连接。这为我解决了同样的问题。

    免责声明 1:同样,这必须为客户完成,即所有需要这样做的客户都必须经过这个程序。

    免责声明 2:我是在安装了 IBM Domino Designer 的同一台机器上执行此操作的。 (我相信我经历的其中一个步骤是将 ext 目录中的这个 JAR 添加到 Domino 设计器中数据库的 Java 项目的构建路径中,但我认为这实际上没有必要)。


    现在说了这么多,对于必须使用此代码的所有 Notes 客户端,唯一现实的方法是修改您的 IBM Notes 安装程序并将其与客户端安装捆绑在一起,以供将来所有安装使用。

    相反,为了避免字面上所有这些,在您公司的安全 VPN 中,通过内部代理使用纯 HTTP 或 TLS 1.0(Java 1.6 确实支持)。换句话说,在您的公司内部网上设置一个 Web 中继来侦听纯 HTTP 请求(或者如果您真的想使用 HTTPS,您可以使用 TLS 1.0 保护它)并使用 TLS 1.2 将它们转发到目的地。这称为代理。这将完全存在于 Notes 之外,并且可以使用 Apache HTTPD 或您喜欢的任何编程语言(如 Java 或 C#)来完成。

    猜你喜欢
    • 1970-01-01
    • 2011-09-09
    • 2021-05-17
    • 2012-01-29
    • 2016-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多