gpt4 book ai didi

使用自签名证书的 Java Rest Client

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:33:29 24 4
gpt4 key购买 nike

您好,我正在尝试编写一个访问我们的云服务器(Rest Web 服务)的小型 Rest 客户端。该连接由 SSL 客户端证书保护,如果我理解正确的话,该证书未由任何证书颁发机构签署,并且存在问题。

我知道该证书工作正常,因为我可以在其他编程语言(例如 C#、PHP 等)中使用它,还因为我正在使用 Postman 测试 API,但是我无法真正理解如何在 Java 中执行此操作.

我试过使用P12证书文件,我也有.key和.crt文件,但还是没有任何改变。我使用 keytool.exe 创建的 .JKS 文件,我认为它是正确的(据我所知)。

这是我正在使用的代码:

String keyPassphrase = certPwd;

KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream("C:\\Test\\Certificate\\idscertificate.jks"), keyPassphrase.toCharArray());

SSLContext sslContext = SSLContexts.custom()
.loadKeyMaterial(keyStore, certPwd.toCharArray())
.build();

HttpClient httpClient = HttpClients.custom().setSslcontext(sslContext).build();

HttpResponse response = httpClient.execute(new HttpGet(
"https://url_that_I_am_using_to_call_my_rest_web_service"));

但是每次我启动这个我都会得到一个错误:

“无法找到请求目标的有效认证路径”。

据我所知,这是因为我没有要指定的证书颁发机构,对吗?谁能帮我解决这个问题?

谢谢大家的帮助

托马索

/**********************这就是我将 P12 导入 keystore 的方式。我尝试了不同的方法,我最后尝试的是:

首先创建了 JKS:keytool -genkey -alias myName -keystore c:\Test\Certificate\mykeystoreName.jks

然后“清理:keytool -delete -alias myName -keystore c:\Test\Certificate\myKeystoreName.jks

然后导入 P12 文件: key 工具 -v -importkeystore -srckeystore c:\Test\Certificate\idscertificate.p12 -srcstoretype PKCS12 -destkeystore c:\Test\Certificate\myKeystoreName.jks -deststoretype JKS

获得的结果:别名 idsclientcertificate 的条目已成功导入。导入命令完成:1 个条目成功导入,0 个条目失败或取消

如果我检查 keystore 的内容,我会找到我导入的证书。尽管如此,我仍然遇到同样的错误。

感谢您的帮助。

/******************************2月8日更新*************** ****

好吧,我什么都试过了,但真的什么都试过了,现在慢慢放弃了……情况如下:

到目前为止使用以下代码:

SSLContextBuilder sslContext = new SSLContextBuilder();
sslContext.loadKeyMaterial(readKeyStore(), userPwd.toCharArray());
//sslContext.loadTrustMaterial(readKeyStore(), new TrustSelfSignedStrategy());

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext.build());

CloseableHttpClient client = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
HttpGet httpGet = new HttpGet("https://myhost.com/myrest/status");
httpGet.addHeader("Accept", "application/json;charset=UTF8");
httpGet.addHeader("Cookie", "sessionids=INeedThis");
String encoded = Base64.getEncoder().encodeToString((userName+":"+userPwd).getBytes(StandardCharsets.UTF_8));
httpGet.addHeader("Authorization", "Basic "+encoded);
httpGet.addHeader("Cache-Control", "no-cache");

HttpResponse response = client.execute(httpGet);

不幸的是仍然没有工作。我尝试了以下操作:- 在默认的 java cacerts 中包含我的证书,- 将别名指定为我的主机名,- 创建一个新的 jks,- 加载 p12 文件,仍然没有,同样的错误。我收到的错误消息是:

javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径

如果我不使用证书,我会收到另一个错误,指出证书丢失,因此证书已加载(我也在我的 IDE 中看到它)。

如果我使用来自另一个平台(c# 或使用浏览器)的完全相同的证书文件,我会得到正确的响应和对象(因此证书/密码有效)

有什么方法可以停止证书路径的验证?

最佳答案

首先感谢大家的帮助。我终于按照以下步骤让它工作:1 - 我使用命令确定了我的根 CA 证书:

openssl s_client -showcerts -connect my.root.url.com:443

然后我使用 Portecle.exe ( https://sourceforge.net/projects/portecle/ ) 导入此证书,但您也可以使用普通的 keytool 命令将其导入我的默认 Java keystore (jre/lib/security/cacerts)--> 确保将根 URL 指定为别名(例如,如果您要连接到 google API,则为 *.google.com)。这似乎很重要。

然后我使用了下面的代码:首先创建ServerSocketFactory:

private static SSLSocketFactory getSocketFactory() 
{
try
{
SSLContext context = SSLContext.getInstance("TLS");

// Create a key manager factory for our personal PKCS12 key file
KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance("SunX509");
KeyStore keyStore = KeyStore.getInstance("PKCS12");
char[] keyStorePassword = pk12Password.toCharArray(); // --> This is the Password for my P12 Client Certificate
keyStore.load(new FileInputStream(pk12filePath), keyStorePassword); // --> This is the path to my P12 Client Certificate
keyMgrFactory.init(keyStore, keyStorePassword);

// Create a trust manager factory for the trust store that contains certificate chains we need to trust
// our remote server (I have used the default jre/lib/security/cacerts path and password)
TrustManagerFactory trustStrFactory = TrustManagerFactory.getInstance("SunX509");
KeyStore trustStore = KeyStore.getInstance("JKS");
char[] trustStorePassword = jksTrustStorePassword.toCharArray(); // --> This is the Default password for the Java KEystore ("changeit")
trustStore.load(new FileInputStream(trustStorePath), trustStorePassword);
trustStrFactory.init(trustStore);

// Make our current SSL context use our customized factories
context.init(keyMgrFactory.getKeyManagers(),
trustStrFactory.getTrustManagers(), null);

return context.getSocketFactory();
}
catch (Exception e)
{
System.err.println("Failed to create a server socket factory...");
e.printStackTrace();
return null;
}
}

然后我使用以下方法创建了连接:

public static void launchApi() 
{
try
{
// Uncomment this if your server cert is not signed by a trusted CA
HostnameVerifier hv = new HostnameVerifier()
{
public boolean verify(String urlHostname, SSLSession session)
{
return true;
}};

HttpsURLConnection.setDefaultHostnameVerifier(hv);


URL url = new URL("https://myRootUrl.com/to/launch/api");

HttpsURLConnection.setDefaultSSLSocketFactory(getSocketFactory());
HttpsURLConnection urlConn = (HttpsURLConnection)url.openConnection();

String encoded = Base64.getEncoder().encodeToString((userName+":"+userPwd).getBytes(StandardCharsets.UTF_8)); //Acc User Credentials if needed to log in
urlConn.setRequestProperty ("Authorization", "Basic "+encoded);
urlConn.setRequestMethod("GET"); // Specify all needed Request Properties:
urlConn.setRequestProperty("Accept", "application/json;charset=UTF8");
urlConn.setRequestProperty("Cache-Control", "no-cache");

urlConn.connect();

/* Dump what we have found */
BufferedReader in =
new BufferedReader(
new InputStreamReader(urlConn.getInputStream()));
String inputLine = null;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}

这对我有用。谢谢大家,也感谢: this article that guided me on the right direction

再见

关于使用自签名证书的 Java Rest Client,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48610798/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com