SSL通信,到底有多难?

发布于 2024-07-15 01:50:23 字数 891 浏览 6 评论 0 原文

我的 PC 上运行着一个 Java 主应用程序,它可以将 XML 数据发送到servlet 并接收返回的 XML 数据。 http://iamt.wisconsin.gov/IAM-WiEntUser/WiEntUserService?xml=< /a>

我可以使用 https://iamt.wisconsin.gov/IAM-WiEntUser /WiEntUserService?xml= 来自 IE 和 Firefox,因为它们允许我加载私有证书。

我想在 Java 主应用程序中使用 https,因为某些数据是敏感的。 我收到带有 MSG=未知证书的 IOException。 好的,这是有道理的,Java 不知道私有证书。

我希望这就像告诉 Java 信任 FireFox 证书一样简单。 System.setProperty("javax.net.ssl.trustStore", “C:/文档和设置/kendajm/应用程序数据/Mozilla/Firefox/Profiles/6f8ggdi7.default/cert8.db”); 但这会给出带有 MSG=Invalid keystore 格式的 IOException 。

SSL通信,到底有多难? 我花了整整八个小时试图找出如何做到这一点。 似乎这很容易,以至于没有记录或非常困难,没有人有一个很好的例子。

帮助。

I have a Java main application running on my PC that can send XML data to a servelet and recieve XML data back.
http://iamt.wisconsin.gov/IAM-WiEntUser/WiEntUserService?xml=

I can use https://iamt.wisconsin.gov/IAM-WiEntUser/WiEntUserService?xml= from IE and Firefox because I they allowed me to load the private certificate.

I want to use https from the Java main application because some of the data is sensitive. I get an IOException with MSG=unkown certificate. Ok, That makes sense, Java does not know about the private certificate.

I was hoping that it would be as simple as telling Java to trust the FireFox certificates.
System.setProperty("javax.net.ssl.trustStore",
"C:/Documents and Settings/kendajm/Application Data/Mozilla/Firefox/Profiles/6f8ggdi7.default/cert8.db" );
But that gives an IOException with MSG=Invalid keystore format.

SSL communication, how hard can it be? I spent a good eight hours trying to track down how to do this. It seems that is so easy that it is not documented or very difficult and no one has a good example.

Help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

倒数 2024-07-22 01:50:23

默认情况下,Mozilla cert8.db 密钥存储格式不可读(尽管可以“插入”可以解析它的提供程序。)最简单的方法是将证书导入到默认支持的密钥存储中。

首先,您需要一份证书副本。

在 Firefox 中,访问相关页面。 单击窗口右下角状态栏上的“锁定”图标。 在出现的对话框中,单击“查看证书”按钮。 将出现一个新对话框; 选择其“详细信息”选项卡。 单击窗口底部的“导出”按钮将证书保存到文件中(使用 DER 或 PEM 格式)。

现在,您需要将证书转换为 Java 使用的密钥存储格式。

使用 JDK 的 keytool 实用程序:

keytool -import -keystore mykeystore.jks -alias iamt -file iamt.wisconsin.gov

当提示输入密码时,选择一个新密码,稍后可用于验证密钥库中的证书未被篡改。 接下来,keytool会提示您是否信任新证书——输入yes! 您应该有一个名为“mykeystore.jks”(或您选择的任何名称)的新 Java 密钥存储文件。

现在,运行您的程序,将新的密钥存储文件指定为“javax.net.ssl.trustStore”属性的值。


顺便说一句,我注意到您正在从服务返回 Java Beans XMLEncoder 输出。 这种“长期持久性”格式是 JDK 中被忽视的瑰宝,但解析不受信任的内容并不安全。 使用此语法,可以在 JVM 中调用任何方法来进行解析。 它有点像不受信任的 JSON 的“eval”。 因此,如果我正在实现一个客户端服务,如果没有大量额外的工作将解析“沙箱”为不受信任的代码,我可能不愿意解析该服务的结果。 我假设该服务解析请求中的相同格式,这对于服务器来说同样是危险的。


当您询问有关错误消息的问题时,最好发布整个消息,包括堆栈跟踪(除非它实际上是 java.lang.StackOverflowError!)。 它可能对您来说毫无意义,但通常它包含人们立即发现问题所需的信息。

The Mozilla cert8.db key store format is not readable by default (though one could "plug in" a provider that can parse it.) It is easiest to import the certificate into a key store that is supported by default.

First, you need a copy of the certificate.

In Firefox, visit the page in question. Click the "lock" icon on the status bar in the lower right corner of the window. In the resulting dialog, click the "View Certificate" button. A new dialog will appear; select its "Details" tab. Click the "Export" button at the bottom of the window to save the certificate into a file (use DER or PEM format).

Now, you need to get the certificate into a key store format used by Java.

Use the JDK's keytool utility:

keytool -import -keystore mykeystore.jks -alias iamt -file iamt.wisconsin.gov

When prompted for a password, choose a new password that can be used to verify later that the certificates in the keystore have not been tampered with. Next, keytool will prompt you whether to trust the new certificate—enter yes! You should have a new Java key store file named "mykeystore.jks" (or whatever you choose).

Now, run your program, specifying your new key store file as the value of the "javax.net.ssl.trustStore" property.


By the way, I noticed that you are returning Java Beans XMLEncoder output from your service. This "Long Term Persistence" format is an overlooked gem of the JDK, but it is not safe to parse untrusted content. Using this syntax, any method can be invoked in the JVM doing the parsing. It's sort of like "eval" with untrusted JSON. So, if I were implementing a client service, I would not probably not be willing to parse the result from the service without a lot of extra work to "sandbox" the parsing as untrusted code. And I'm assuming the service parses the same format in requests, which is likewise dangerous for the server.


When you ask a question about an error message, it's a great idea to post the entire message, including the stack trace (unless it's actually a java.lang.StackOverflowError!). It might be meaningless to you, but often it has the information one needs to spot the problem in an instant.

盗梦空间 2024-07-22 01:50:23

一旦我使用 keytool 在 Java 中正确注册了自签名证书,我就能够使用它了。

请参阅本指南:http://java.sun。 com/j2se/1.4.2/docs/tooldocs/windows/keytool.html

本质上,您:
1. 创建自签名证书
2.导出到文件
3. 将其导入默认密钥库

但是,您尝试集成的政府网站可能会拒绝此类自签名证书。

I've been able to use a self-signed certificate once I registered it properly with Java using keytool.

See this guide: http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/keytool.html

Essentially, you:
1. Create a self signed certificate
2. Export it to a file
3. Import it into the default keystore

It is possible that the government website you are trying to integrate with will reject such a self-signed cert, however.

洛阳烟雨空心柳 2024-07-22 01:50:23

据我了解,问题在于Java不接受自签名证书。 如果我错了请纠正我!

您是否尝试过使用Commons-HttpClient? 这有更多选项,并且在此页面上有一个指南用于接受自签名证书。 另请参阅 此示例代码

编辑:有一个关于如何将证书导入Java的指南此处 - 显然,您需要在运行 Java 应用程序的每台计算机上执行此操作。 HttpClient 选项可能更灵活,具体取决于您的需要。

As I understand it, the problem is that Java will not accept a self-signed certificate. Correct me if I am wrong!

Have you tried using Commons-HttpClient? This has some more options, and on this page there is a guide for accepting self-signed certificates. Also see this sample code

Edit: there is a guide on how to import the certificate into Java here - obviously you will need to do this on each machine that the Java app runs on though. The HttpClient option may be more flexible, depending on what you need.

提笔书几行 2024-07-22 01:50:23
  1. 将证书从 IE 导出为 Base-64 编码的 X.509 (.CER)
  2. 对导出的证书运行 keytool。 提供 trustStore 文件和密码。 对信任问题回答“是”。
    keytool -import -v -trustcacerts -alias IamtCert -file C:\Work\IAM\Acceptance\IamAcceptanceCertificate.cer -keystore N:\WEB\DEG\Ca​​Cert.dat
  3. 添加两行代码。
    System.setProperty("javax.net.ssl.trustStore","N:\WEB\DEG\Ca​​Cert.dat");
    System.setProperty("javax.net.ssl.trustStorePassword","xxxxxx");

一旦你知道该做什么就不难了。 其余代码保持不变。
(Servlet 有另一种方法来验证调用者的身份,但不涉及证书。)

    urlAddress += encodedXmlData;
    URL  url = null;
    HttpURLConnection connection = null;
    StringBuffer result = new StringBuffer();
    try {
        url = new URL( urlAddress );
        connection = (HttpURLConnection)url.openConnection();
    }
    catch( IOException ioe ) {
        System.out.println(classMethod+": IOException: URL Msg="+ioe.getMessage() );
        return(null);
    }           
    connection.setDoInput(true);    // Default value.
    connection.setDoOutput(true);   // Not the default value.
    connection.setUseCaches(false); // Not the default value.
    try {
        connection.setRequestMethod("POST");  // Large pay load.
    }
    catch( ProtocolException pe ){
        System.out.println(classMethod+": ProtocolException: URL Msg="+pe.getMessage() );
        return(null);
    }
    // If true, this URL is being examined in a context in which it makes
    // sense to allow user interactions such as popping up an 
    // authentication dialog.
    connection.setAllowUserInteraction(false);
    try {
        connection.connect();
        BufferedReader bufferedReader = new BufferedReader( new
                InputStreamReader( connection.getInputStream() ) );

        // Retrieve the response
        String inputLine = null;
        while ( (inputLine = bufferedReader.readLine() ) != null ) {
            if ( inputLine.indexOf("</void>") > -1 ) inputLine+='\n';
            result.append(inputLine);
        }
        bufferedReader.close();
        connection.disconnect();
    }
    catch( IOException ioe) {
        System.out.println(classMethod+": IOException: Read Msg="+ioe.getMessage() );
        return(null);
    }
  1. Export the certificate from IE as Base-64 encoded X.509 (.CER)
  2. Run keytool on the exported certificate. Provide trustStore file and password. Reply "yes" to trust question.
    keytool -import -v -trustcacerts -alias IamtCert -file C:\Work\IAM\Acceptance\IamAcceptanceCertificate.cer -keystore N:\WEB\DEG\CaCert.dat
  3. Add two lines of code.
    System.setProperty("javax.net.ssl.trustStore","N:\WEB\DEG\CaCert.dat");
    System.setProperty("javax.net.ssl.trustStorePassword","xxxxxx");

Not hard once you know what to do. Rest of the code remains the same.
(Servlet has another way to valid the caller that does not involve a certificate.)

    urlAddress += encodedXmlData;
    URL  url = null;
    HttpURLConnection connection = null;
    StringBuffer result = new StringBuffer();
    try {
        url = new URL( urlAddress );
        connection = (HttpURLConnection)url.openConnection();
    }
    catch( IOException ioe ) {
        System.out.println(classMethod+": IOException: URL Msg="+ioe.getMessage() );
        return(null);
    }           
    connection.setDoInput(true);    // Default value.
    connection.setDoOutput(true);   // Not the default value.
    connection.setUseCaches(false); // Not the default value.
    try {
        connection.setRequestMethod("POST");  // Large pay load.
    }
    catch( ProtocolException pe ){
        System.out.println(classMethod+": ProtocolException: URL Msg="+pe.getMessage() );
        return(null);
    }
    // If true, this URL is being examined in a context in which it makes
    // sense to allow user interactions such as popping up an 
    // authentication dialog.
    connection.setAllowUserInteraction(false);
    try {
        connection.connect();
        BufferedReader bufferedReader = new BufferedReader( new
                InputStreamReader( connection.getInputStream() ) );

        // Retrieve the response
        String inputLine = null;
        while ( (inputLine = bufferedReader.readLine() ) != null ) {
            if ( inputLine.indexOf("</void>") > -1 ) inputLine+='\n';
            result.append(inputLine);
        }
        bufferedReader.close();
        connection.disconnect();
    }
    catch( IOException ioe) {
        System.out.println(classMethod+": IOException: Read Msg="+ioe.getMessage() );
        return(null);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文