我在Java程序的每次其他调用中都得到了这个异常:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我在OpenSuSE Linux机器上运行Java 1.5.0_15。我从VeriSign网站下载了根证书,并使用keytool导入它们。
代码没有什么异常 - 只需发送几个参数并读取响应。代码在这篇文章的末尾。
看起来我没有安装所需的证书,但我真的不明白为什么我在每次调用时都会看到这个问题!?
我使用了-Djavax.net.debug = ssl并且具有工作调用和失败调用的输出。前几百行输出是相同的,然后我从失败的调用中获得此输出:
***
main, SEND TLSv1 ALERT: fatal, description = certificate_unknown
main, WRITE: TLSv1 Alert, length = 2
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
...
%% No cached client session
*** ClientHello, TLSv1
由于-Djavax.net.debug = ssl属性而生成的完整输出太多,无法包含在此帖子中。
这是我正在使用的测试程序:
<imports go here>
public class HttpPoster
{
public static final String s_target = "https://<url goes here>";
private static final String s_parameters = "a=100&b=200";
public void runTest()
{
HttpURLConnection connection = createHttpConnection(s_target);
String response = null;
int statusCode = -1;
String responseMessage = null;
try
{
response = sendRequest(connection, s_parameters);
statusCode = connection.getResponseCode();
responseMessage = connection.getResponseMessage();
System.out.println("Response = " +response);
System.out.println("Status Code = " +statusCode);
System.out.println("Response Message = " +responseMessage);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (connection != null)
{
connection.disconnect();
connection = null;
}
}
}
private String sendRequest(HttpURLConnection connection, String parameters)
{
StringBuffer buffer = new StringBuffer();
try
{
// Calling getOutputStream() does an implicit connect()
OutputStreamWriter outputWriter = new OutputStreamWriter(connection.getOutputStream());
outputWriter.write(parameters);
outputWriter.flush();
// Get the response
String line = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while((line = bufferedReader.readLine()) != null)
{
buffer.append(line);
}
if (outputWriter != null) {
outputWriter.close();
}
if (bufferedReader != null) {
bufferedReader.close();
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
return buffer.toString();
}
private HttpURLConnection createHttpConnection(String url)
{
HttpURLConnection connection = null;
try
{
connection = (HttpURLConnection)(new URL(url)).openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestMethod("POST");
connection.setReadTimeout(15000);
setHostNameVerifier(connection);
}
catch (MalformedURLException murlException)
{
murlException.printStackTrace();
}
catch (IOException ioException)
{
ioException.printStackTrace();
}
return connection;
}
private void setHostNameVerifier(HttpURLConnection c)
{
HostnameVerifier hv = null;
if (c instanceof HttpsURLConnection)
{
hv = new HostnameVerifier()
{
public boolean verify(String urlHostName, SSLSession session)
{
// Ignore the domain mismatch
return true;
}
};
((HttpsURLConnection)c).setHostnameVerifier(hv);
}
}
public static void main(String[] args)
{
new HttpPoster().runTest();
}
}
谢谢,
保