如何在 java 中使用本地 HTTPS URL?

发布于 2024-07-11 04:34:58 字数 325 浏览 6 评论 0原文

使用 Java URL 类,我可以连接到外部 HTTPS 服务器(例如我们的生产站点),但使用本地 URL 时会出现以下异常。

"SunCertPathBuilderException: unable to find valid certification path to requested target".

如何获得有效的认证路径?

编辑:我没有使用此 URL 直接创建连接,而是将 URL 传递给 itext PDFReader,然后该 URL 出现连接问题。

Using the Java URL class, I can connect to an external HTTPS server (such as our production site), but using a local URL I get following exception.

"SunCertPathBuilderException: unable to find valid certification path to requested target".

How do I get a valid certification path?

EDIT: I'm not using this URL to directly create a connection, I am passing the URL to an itext PDFReader, which is then having the connection issue.

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

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

发布评论

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

评论(5

骄傲 2024-07-18 04:34:58

您可能需要设置 主机名验证器。 在连接之前,您需要将其添加到连接对象中。

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
  public boolean verify(String hostname, SSLSession session) {
    // check hostname/session
    return true;
  }
});
conn.connect();
// read/write...

如果您需要的话,肯定有一些实现。 您可能还想查看 HttpClient 项目。

You probably need to setup a HostnameVerifier. Before connecting, you need add it to the connection object

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
  public boolean verify(String hostname, SSLSession session) {
    // check hostname/session
    return true;
  }
});
conn.connect();
// read/write...

There certainly are some implementations out there, if you need one. You might want to look at HttpClient project too.

愛上了 2024-07-18 04:34:58

另一件需要注意的事情是您正在使用的 TrustManager。 该错误消息表明服务器提供的证书未由受信任的根签名。 由于您无法直接控制创建的 SSL 套接字,因此我认为最好的选择是 初始化拥有 SSLContext使用服务器证书链的根 CA 进行设置。 然后将此上下文设置为 默认

这是假设您使用的是 Java 6。Java 5 中的 API 受到更多限制。您可以获得默认的 SSLSocketFactory,但没有标准的方法来设置它。

Another thing to look at is the TrustManager you are using. The error message suggests that the certificate presented by the server is not signed by a trusted root. Since you don't have direct control over the SSL socket that is created, I think your best bet is to initialize your own SSLContext with a TrustManager that's been setup with the root CA of the server's certificate chain. Then set this context as the default.

This is assuming you are using Java 6. The API is more limited in Java 5. You can get a default SSLSocketFactory, but there's no standard way to set it.

枯寂 2024-07-18 04:34:58

它抱怨的问题是,当您创建 SSL 连接时,服务器必须向客户端提供有效的证书。 您可以用 Java 编写适当的端点(我认为 HTTPServerSocket 可以做到),但需要一些技巧来设置它。 使用正确处理 SSL 的任何东西(Apache、lighttp 等)设置本地 Web 服务器可能更容易,并使用 openssl 工具创建自签名证书。

Updated

这是 Java 年鉴中的一个示例。 http://www.exampledepot.com/egs/javax.net。 ssl/Server.html

SSL 服务器套接字需要将其发送给客户端进行身份验证的证书。 证书必须包含在密钥库中,其位置必须明确指定(没有默认值)。 下面的示例描述了如何创建和指定要使用的 SSL 服务器套接字的密钥库。

try {
    int port = 443;
    ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
    ServerSocket ssocket = ssocketFactory.createServerSocket(port);

    // Listen for connections
    Socket socket = ssocket.accept();

    // Create streams to securely send and receive data to the client
    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();

    // Read from in and write to out...

    // Close the socket
    in.close();
    out.close();
} catch(IOException e) {
}

使用 javax.net.ssl.keyStore 系统属性指定证书的密钥库:

> java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 MyServer

The problem it's complaining about is that when you create an SSL connection, the server must present a valid certificate to the client. You can write an appropriate endpoint in Java (HTTPServerSocket will do it I think) but it would require some hacking about to set it up. It's probably easier to set up a local web server with anything that handles SSL correctly --- Apache, lighttp, whatever --- and create a self-signed cert using the openssl tools.

Updated

Here's an example from the Java Almanac. http://www.exampledepot.com/egs/javax.net.ssl/Server.html

An SSL server socket requires certificates that it will send to clients for authentication. The certificates must be contained in a keystore whose location must be explicitly specified (there is no default). Following the example we describe how to create and specify a keystore for the SSL server socket to use.

try {
    int port = 443;
    ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
    ServerSocket ssocket = ssocketFactory.createServerSocket(port);

    // Listen for connections
    Socket socket = ssocket.accept();

    // Create streams to securely send and receive data to the client
    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();

    // Read from in and write to out...

    // Close the socket
    in.close();
    out.close();
} catch(IOException e) {
}

Specify the keystore of certificates using the javax.net.ssl.keyStore system property:

> java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 MyServer
最单纯的乌龟 2024-07-18 04:34:58

它还可以帮助您将本地主机服务器正在使用的证书(我假设它是自签名的)添加到 JVM 的 密钥库使用“keytool “实用程序。 这应该具有告诉 JVM“您可以信任此证书”的效果。

It may also help you to add the certificate that the localhost server is using (I assume it's self-signed) to the JVM's keystore, using the "keytool" utility. This should have the effect of telling the JVM "you can trust this certificate".

谁许谁一生繁华 2024-07-18 04:34:58

我最终运行了一个静态方法(仅在开发人员上),该方法安装了一个非常信任的 TrustManager (接受所有内容),并且还添加了一个始终返回 true 的 hostnameVerifier (感谢 sblundy)。

I have ended up running a static method (only on dev) that installs a very trusting TrustManager (accepts everything), and also added a hostnameVerifier that always returns true (thanks sblundy).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文