我正在编写一个程序,该程序需要使用https Post将数据发送到webapi。我提供了一个.pem文件,提供商说我将需要该文件才能连接到api。现在,我被困在对此证书文件提出正确的发布请求。有人可以帮忙吗?
下面是到目前为止我得到的,它确实可以运行,但是遇到了
java.security.cert.CertificateException:在sun.security.util.HostnameChecker.matchIP上不存在使用者替代名称
我已经搜索了此异常。有人说我应该在代码中使用域名而不是IP地址。但是,我提供的api仅以IP形式提供。我还要检查.pem文件中的CN。它也是ip形式而不是域形式。
public void httpPost(String json) throws Exception {
System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2,SSLv3");
InputStream stream = getClass().getClassLoader().getResourceAsStream("test.pem");
File targetFile = new File("test_cert.pem");
try {
FileUtils.copyInputStreamToFile(stream, targetFile);
}
catch (IOException e) {
e.printStackTrace();
}
try {
//String key;
System.out.println("SSL");
SSLSocketFactory sf = getSocketFactoryPEM(targetFile);
URL url = new URL("https://xxxxxxx");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Content-Length", String.valueOf(json.getBytes().length));
conn.setSSLSocketFactory(sf);
conn.getOutputStream().write(json.getBytes());
conn.getOutputStream().flush();
conn.getInputStream().close();
System.out.println("Send message.");
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
System.out.println("Got response.");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
protected static SSLSocketFactory getSocketFactoryPEM(File file) throws Exception {
byte[] certAndKey = FileUtils.readFileToByteArray(file);
byte[] certBytes = parseDERFromPEM(certAndKey, "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----");
X509Certificate cert = generateCertificateFromDER(certBytes);
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(null);
keystore.setCertificateEntry("cert-alias", cert);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keystore, "123456".toCharArray());
KeyManager[] km = kmf.getKeyManagers();
SSLContext context = SSLContext.getInstance("TLS");
context.init(km, null, null);
return context.getSocketFactory();
}
protected static byte[] parseDERFromPEM(byte[] pem, String beginDelimiter, String endDelimiter) {
String data = new String(pem);
String[] tokens = data.split(beginDelimiter);
tokens = tokens[1].split(endDelimiter);
return DatatypeConverter.parseBase64Binary(tokens[0]);
}
protected static X509Certificate generateCertificateFromDER(byte[] certBytes) throws CertificateException {
CertificateFactory factory = CertificateFactory.getInstance("X.509");
return (X509Certificate)factory.generateCertificate(new ByteArrayInputStream(certBytes));
}