java 建立双向认证 https连接

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 建立双向认证 https连接相关的知识,希望对你有一定的参考价值。

在做一个银行支付的接口,服务器需要SSL双向认证,目前手上有根证、客户证书pfx等,如何建立连接并且向其POST数据呢??
求大神!!

参考技术A 绝对好用的。直用的这个,GOOD LUCK FOR YOU

public static String httpRequest(String requestUrl, String requestMethod, String outputStr)
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = new MyX509TrustManager() ;
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();

URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);

httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);

if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();

// 当有数据需要提交时
if (null != outputStr)
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();


// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String str = null;
while ((str = bufferedReader.readLine()) != null)
buffer.append(str);

bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
System.out.println("返回的数据:"+buffer.toString());
// jsonObject = JSONObject.fromObject(buffer.toString());
catch (ConnectException ce)
log.error("Weixin server connection timed out.");
catch (Exception e)
log.error("https request error:", e);

return buffer.toString();
追问

需要用证书?否则会拒绝访问的。。。

追答

再搞个代理类,就OK了。

参考技术B 证书验证 注册在服务器或者jre中就可以了吧 这样没有证书 直接不能访问

使用 jdk自带ssl包 进行 https通讯双向认证

package com.iraid.test;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

/**
 * 使用 jdk自带ssl包 进行 https通讯双向认证。
 * @author wangfeihu
 *
 */
public class HttpsTest {
	public static void main(String[] args) throws Exception {
		testHttpsWithCert();
	}

	/**
	 * post 请求,带双证书验证
	 */
	public static void testHttpsWithCert() {
		// 授信证书库
		String trustStore = "D:\\workspaces\\test\\https-native\\src\\cacerts.jks";
		String trustStorePass = "changeit";

		// 私钥证书
		String keyStore = "D:\\workspaces\\test\\https-native\\src\\www.demo.com.p12";
		String keyStorePass = "052537159932766";

		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";

		try {
			TrustManager[] tms = getTrustManagers(trustStore, trustStorePass);

			KeyManager[] kms = getKeyManagers(keyStore, keyStorePass);

			SSLContext sslContext = SSLContext.getInstance("SSL");
			sslContext.init(kms, tms, new java.security.SecureRandom());

			SSLSocketFactory ssf = sslContext.getSocketFactory();

			// 服务链接
			URL url = new URL(
					"https://www.demo.com/rest/UidApiService/authCardWithoutOTP");
			// 请求参数
			String params = "{\"merchantCode\": \"www.demo.com\","
					+ "\"sessionId\": \"10000011\","
					+ "\"userName\": \"jack\","
					+ "\"idNumber\": \"432652515\","
					+ "\"cardNo\": \"561231321\"," + "\"phoneNo\": \"\"}";

			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(ssf);

			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0");
			
			// content-type 按具体需要进行设置
			conn.setRequestProperty("content-type", "application/json");
			
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);

			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(params);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(
					new InputStreamReader(conn.getInputStream()));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
			System.out.println(result);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				in.close();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 加载信任证书库
	 * 
	 * @param trustStore
	 * @param trustStorePass
	 * @return
	 * @throws IOException
	 */
	private static TrustManager[] getTrustManagers(String trustStore,
			String trustStorePass) throws IOException {
		try {
			String alg = TrustManagerFactory.getDefaultAlgorithm();
			TrustManagerFactory factory = TrustManagerFactory.getInstance(alg);
			InputStream fp = new FileInputStream(trustStore);
			KeyStore ks = KeyStore.getInstance("JKS");
			ks.load(fp, trustStorePass.toCharArray());
			fp.close();
			factory.init(ks);
			TrustManager[] tms = factory.getTrustManagers();
			System.out.println(tms);
			return tms;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 加载私钥证书
	 * 
	 * @param keyStore
	 * @param keyStorePass
	 * @return
	 * @throws IOException
	 */
	private static KeyManager[] getKeyManagers(String keyStore,
			String keyStorePass) throws IOException {
		try {
			String alg = KeyManagerFactory.getDefaultAlgorithm();
			KeyManagerFactory factory = KeyManagerFactory.getInstance(alg);
			InputStream fp = new FileInputStream(keyStore);
			KeyStore ks = KeyStore.getInstance("PKCS12");
			ks.load(fp, keyStorePass.toCharArray());
			fp.close();
			factory.init(ks, keyStorePass.toCharArray());
			KeyManager[] keyms = factory.getKeyManagers();
			System.out.println(keyms);
			return keyms;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
		}
		return null;
	}

}


本文出自 “流浪的脚步” 博客,请务必保留此出处http://now51jq.blog.51cto.com/3474143/1789539

以上是关于java 建立双向认证 https连接的主要内容,如果未能解决你的问题,请参考以下文章

网络https单向认证和双向认证

如何使用Java访问双向认证的Https资源

计算机网络

干货 | 图解 https 单向认证和双向认证!

使用 jdk自带ssl包 进行 https通讯双向认证

TOMCAT配置HTTPS双向认证,为啥始终无法访问