【问题标题】:getting an AS400 java application called from RPGLE to trust a .PFX certificate获取从 RPGLE 调用的 AS400 java 应用程序以信任 .PFX 证书
【发布时间】:2018-06-30 05:43:39
【问题描述】:

我整天都在做这件事,我只是在猜测该怎么做。似乎知道此功能如何工作的人假设其他人都知道他们在说什么。他们会说诸如使用实用程序 ABC 生成 DEF 之类的话,但假设您知道 ABC 是什么、如何使用它以及完成后如何处理 DEF。让我先说我是一名 AS400 RPG 编码员,但可以用 Java 做一些事情。我想已经够危险了。从技术上讲,我仍然不太了解信任库或密钥库是什么。

基本上,我开发了一个简单的 AS400 java 应用程序,它基本上只是调用一些 HTTP 方法来向外部方发送交易。此应用程序直接从 RPGLE 程序调用。这一直运行良好,但现在他们决定使用 HTTPS。客户向我发送了一个 .PFX 文件,其中包含他们使用 AS400 上称为数字证书管理器的实用程序创建密钥时的一些内容。我找到了足够的信息来收集我必须在 IFS 的根应用程序目录中有一个 SSL 属性文件,并且工作正在查看该属性文件,它似乎具有正确的参数。我遇到的困难是如何让证书信任应用程序。我不确定您是否需要 .PFX 文件存在于应用程序的 IFS 根目录中,或者您是否必须创建信任库/密钥库,或者您是否需要除了 SSL 属性文件之外的任何东西?我发现所有问题的答案都是肯定的,这取决于你问的是谁。一些答案会引导你走上详尽的道路,以达到某一点,结果却什么也没有发生。这更像是一种发泄。我几乎得出结论,这东西是不可能的。 :)

对于它的价值,下面是我用于仅使用 HTTP 连接到服务的代码。我一直在寻找一个简单的逐步过程来解释在 AS400 上成功发生 HTTPS 握手所需的内容。我没有足够的信息来了解我是否需要从客户那里获得更多信息,或者我是否有足够的信息来独立完成。

HttpClient m_HttpClient = null; 
PostMethod m_PostMthd = null;
SimpleHttpConnectionManager m_simpleHttpConMnger = new 
SimpleHttpConnectionManager();
int timeoutInMilliseconds = 10000;
m_PostMthd = new PostMethod(urlEndpoint);
m_HttpClient = new HttpClient(m_simpleHttpConMnger);
HttpConnectionManagerParams lhttpConMnger = 
m_simpleHttpConMnger.getParams();
lhttpConMnger.setConnectionTimeout(timeoutInMilliseconds);
lhttpConMnger.setSoTimeout(timeoutInMilliseconds);

m_PostMthd.setRequestHeader("SOAPAction",SOAPAction);
m_PostMthd.setRequestHeader("Content-Type","text/xml; charset=UTF-8");  


m_PostMthd.setRequestEntity(new StringRequestEntity(inputMsg));

int l_status = m_HttpClient.executeMethod(m_PostMthd);
System.out.println("EXECUTION STATUS : " + l_status+"\n");

InputStream is = m_PostMthd.getResponseBodyAsStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuilder response = new StringBuilder();
while ((line = rd.readLine()) != null)
    {
    response.append(line);
    response.append('\r');
    }

    rd.close();
    return response.toString();

【问题讨论】:

    标签: java ssl ibm-midrange


    【解决方案1】:

    我认为这里有两个不同的问题:如何在 Java 中使用 PFX 文件,以及我应该如何处理它。第一个相当直截了当,第二个可能需要一些额外的信息,但我会尽我所能回答。

    在 Java 中处理 PFX

    PFX 是一种容器文件格式,可以包含大量与 SSL/TLS 和加密相关的不同类型的数据。 Java 有自己的容器格式,称为 JKS KeyStore。从广义上讲,这些是保存相同类型数据的等效方法,您只需从一个导出到另一个。预先执行此操作比在运行时尝试执行此操作更容易。引用this answer

    keytool -importkeystore \
            -srckeystore mypfxfile.pfx -srcstoretype pkcs12 \
            -destkeystore clientcert.jks -deststoretype JKS
    

    Keytool 包含在 JDK 中。它会一路询问一些密码。您可以使用keytool -list -keystore file.jks 命令来显示 JKS 文件。

    我该怎么处理这些东西?

    这取决于情况,这里你的问题有点含糊。在所有情况下,目的都是身份验证:客户端需要验证它正在与正确的服务器通信,并且可选地,服务器需要验证它正在与正确的客户端通信。这涉及到三位信息和大量数学运算。

    • 私钥公钥(连同一些数学运算,通常是 RSA 算法)用于创建锁和钥匙系统。您将私钥留给自己,并与需要它的任何人共享公钥。这些在身份验证中的使用方式是,私钥用于在数学上提出可以用公钥验证的声明。数学如此,几乎不可能伪造这种说法。因此,如果数学检查出来,您可以确定与您交谈的人持有私钥。简而言之,这就是数字签名。
    • 证书嵌入了一个公钥并向其中添加了一堆信息(密钥基本上只是一个巨大的质数,所以它本身并没有多大用处)。添加的信息包括密钥持有者的身份,以及保证证书有效性的颁发者的身份,所有这些都用数字签名密封。

    根据应用程序,您收到的 PFX 文件可能仅包含证书,也可能包含证书和相应的私钥(或两者都包含)。

    keytool -list 的输出将显示任意数量的trustedCertEntry 记录,这些是没有可用私钥的证书,它可能包括一个privateKeyEntry,这是一个记录存在私钥。记下任何私钥条目的alias

    客户端验证服务器

    创建 HTTPS 连接后,服务器会向客户端提供证书,以及服务器持有与嵌入在证书中的公钥相对应的私钥的证明。客户端必须决定是信任服务器的身份,还是中止连接。它通过数学方式检查服务器提供的证书与称为信任库的预共享、受信任证书列表(cacerts 是一个常见的文件系统名称)。

    您的操作系统和网络浏览器都带有默认的信任库;此机制位于浏览器中的挂锁图标后面。

    在您的情况下,您连接的端点很可能使用默认信任存储中不存在的证书,因此您必须提供自己的 [信任存储]。

    假设 Java 在 AS/400 上的工作方式与 Java 在 Windows 和 Linux 上的工作方式相同,您可以(引用 this answer)传递一个名为 javax.net.ssl.trustStore 的 Java 系统属性,该属性包含指向包含受信任的 JKS 密钥库的文件系统路径签名者的证书。

    另一种方法是将 JKS 文件命名为 jssecacerts 并将其放在您的 jre/lib/security 目录中,但请记住,它现在会影响使用该 JVM 安装运行的 所有 java 进程只是你正在为之做这项工作的那个人。

    服务器验证客户端

    在网络上用的不多,但是 HTTPS 可以选择做双向证书验证。这意味着在客户端以上述方式对服务器进行身份验证后,服务器现在对客户端进行身份验证。这是完全相同的过程,但方向相反。

    这在专有 SOAP 服务中更为常见,所以这里可能就是这种情况。你的问题并没有让我很清楚。

    这意味着您的应用程序必须向服务器提供证书,并且它必须拥有与嵌入在证书中的公钥相对应的私钥。可悲的是,我自己从来没有在 Java 中这样做过,所以我不知道你必须传递的确切命令。您需要寻找一种方法来告诉您的联系这些事情:

    • 使用什么 JKS 密钥库文件(+其密码)
    • 要使用该 JKS 中的哪个密钥别名(+其密码)

    【讨论】:

    • If 默认上下文,Sun/Oracle/OpenJDK JSSE 使用 javax.net.ssl.keyStore 作为密钥库,ibm.com/support/knowledgecenter/en/SSYKE2_7.1.0/… 表示 IBMJSSE2 也这样做。我 99.9% 确定 IBM(如 Suncle)支持 PKCS12 作为密钥库类型,因此您实际上不需要转换,只需将 storetype 指定为 PKCS12。
    • 我们的 IBM 管理员也达成了同样的共识。他认为我们可以在选项中更改 ssl 属性文件以使用 PKCS12。但是,我已经这样做了,结果相同。我的工作是设置 IFS_HOME、SSLPROPS 和 TRUSTSTORE 的 JVM 参数。目前 TRUSTSTORE 等于 /home/folder1/certificate.pfx 并且我已将客户端发送给我的 Pfx 文件复制到该文件夹​​。这足够了吗,还是我还需要一些java代码?还是我离基地太远了?
    • 另外,当我将属性 java.net.ssl.truststore 设置为 certificate.pfx 时,我在日志中收到错误“未实现未连接的套接字”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多