您的位置:首页 > 理论基础 > 计算机网络

网络编程六:https请求(双向验证)

2016-12-23 11:47 393 查看
以微信支付退款api为例,写https的请求(微信支付v3的退款和撤销订单api都需要双向验证,刚好满足这个文章的需求)

步骤:

1、获取ca证书

2、生成jks版本的证书,并且,把格式为pem的ca证书导入

3、为SSLContext添加jks证书和cert证书

4、把需要传的数据填入PrintWriter里面

5、然后根据url发起请求

6、接收服务器返回回来的数据

HttpsPost.java(没有用任何第三方的jar)

import java.io.*;
import java.net.URL;
import java.security.*;
import javax.net.ssl.*;

public class HttpsPost {
public static void main(String[] args) throws Exception {

String path = "F:\\WORK\\workspace\\WebContent\\WEB-INF\\classes\\com\\demo\\certificate\\";
String caName = path+"rootca.pem";
String certName = path+"apiclient_cert.p12";
String caPass = "";
String certPass = "apiclient_cert";

String urlstr =  "https://apihk.mch.weixin.qq.com/secapi/pay/reverse";

String datas = "<xml><appid>wx2421b1c4370ec43b</appid><mch_id>10000100</mch_id><nonce_str>0b9f35f484df17a732e537c37708d1d0</nonce_str><out_refund_no></out_refund_no><out_trade_no>1415757673</out_trade_no><refund_id></refund_id><transaction_id></transaction_id><sign>66FFB727015F450D167EF38CCC549521</sign></xml>";

httprequestwithcacert(path,caName,caPass,certName,certPass,urlstr,datas);
}

private static final String JKS_CA_FILENAME = "server.jks";

private static final String JKS_CA_ALIAS = "server";

private static final String JKS_CA_PASSWORD = "";

/**
* post 请求,带双证书验证
*/
public static void httprequestwithcacert(String path, String caName, String caPass, String certName, String certPass, String urlstr, String datas) throws Exception{
//IOException,CertificateException, KeyStoreException, NoSuchAlgorithmException,UnrecoverableKeyException, KeyManagementException

String capath = path + caName; //ca证书路径加名字
String certpath = path + certName; //cert证书路径加名字
String jkspath = path + JKS_CA_FILENAME; //ca转
4000
jks后的文件路径加名字
File caFile = new File(capath);
//把pem格式的ca导入到jks
jksmaker(jkspath,caFile);

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

try {
//这里加载的证书需要是jks格式的
TrustManager[] tms = getTrustManagers(jkspath, caPass);

KeyManager[] kms = getKeyManagers(certpath, certPass);

SSLContext sslContext = SSLContext.getInstance("SSL");
// 如果服务器不要求私钥证书,kms 可以不填
sslContext.init(kms, tms, new java.security.SecureRandom());

SSLSocketFactory ssf = sslContext.getSocketFactory();

// 服务链接
URL url = new URL(urlstr);

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(datas);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
conn.getInputStream(), "UTF-8"));
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;
}

/**
* CA证书生成/导入jks
*
* @param jkspath
* @param caFile
*/
public static void jksmaker(String jkspath,File caFile) throws Exception{
File jksCAFile = new File(jkspath);
if (!jksCAFile.isFile()) {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream in = new FileInputStream(caFile);
Certificate certificate = cf.generateCertificate(in);
in.close();
X509Certificate cert = (X509Certificate) certificate;
FileOutputStream out = new FileOutputStream(jksCAFile);
// store jks file
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
ks.setCertificateEntry(JKS_CA_ALIAS, cert);
// store keystore
ks.store(out, (JKS_CA_PASSWORD==null?null:JKS_CA_PASSWORD.toCharArray()));
out.close();
}
}

}


就这样了,可以当做模板用,赞
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: