要对接外部系统,对方提供了一个p12(PFX)证书,提供一个解密这个证书的密码。
方法一:httpClient支持直接用p12证书和密码的方式请求ssl(PKCS12)
httpClient支持直接用p12证书和密码的方式请求ssl,示例如下:
public static String post(JSONObject json, String url, Map<String, String> headerMap,String p12Path, String password) throws Exception{
HttpClientBuilder builder = HttpClientBuilder.create();
SSLContext sslContext = getSSlContext(p12Path, password);
builder.setSSLContext(sslContext);
CloseableHttpClient httpclient = builder.build();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringEntity s = new StringEntity(json.toString(),"utf-8");
// s.setContentEncoding("UTF-8");
/*发送json数据需要设置contentType*/
s.setContentType("application/json");
post.setEntity(s);
post.setHeader("Content-Type","application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry:headerEntries){
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber= new StringBuilder();
String line = null;
while((line = br.readLine())!=null){
strber.append(line+'\n');
}
result = strber.toString();
if(response.getStatusLine().getStatusCode()!=HttpStatus.SC_OK){
if(StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if(null != br) br.close();
if(null != in) in.close();
if(null != response) response.close();
if(null != httpclient) httpclient.close();
}
return result;
}
private static SSLContext getSSlContext(String p12Path, String password) {
SSLContext sslContext = null;
try {
KeyStore kstore = KeyStore.getInstance("PKCS12");
kstore.load(new FileInputStream(p12Path), password.toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance("sunx509");
keyFactory.init(kstore, password.toCharArray());
sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyFactory.getKeyManagers(), null, (SecureRandom) null);
} catch (Exception e) {
e.printStackTrace();
}
return sslContext;
}
这种方法输入的是p12文件地址,一般不会直接这样用,用文件的形式管理证书秘钥不太安全,一般是会转成crt证书之后,存到vault里。
方法二:httpClient也支持用crt证书和privateKey的请求(JKS)
先把p12(PFX)证书转成PEM
openssl pkcs12 -in xxx.pfx -nodes -out server.pem
pem继续提取私钥:
openssl rsa -in server.pem -out server.key
pem提取验证证书:
openssl x509 -in server.pem -out server.crt
如此我们就得到了一个X509协议的crt证书
-----BEGIN CERTIFICATE-----
xxxxx
-----END CERTIFICATE-----
和一个pkcs1的私钥key
-----BEGIN RSA PRIVATE KEY-----
xxxxx
-----END RSA PRIVATE KEY-----
如此就可以用下面代码来实现:
public static String post(String json, String url, Map<String, String> headerMap,String crt, String privateKey) throws Exception{
HttpClientBuilder builder = HttpClientBuilder.create();
SSLConnectionSocketFactory sslf = getSSlContextByCrtAndKey(crt, privateKey);
// builder.setSSLContext(sslContext);
builder.setSSLSocketFactory(sslf);
CloseableHttpClient httpclient = builder.build();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringEntity s = new StringEntity(json,"utf-8");
// s.setContentEncoding("UTF-8");
/*发送json数据需要设置contentType*/
s.setContentType("application/json");
post.setEntity(s);
post.setHeader("Content-Type","application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry:headerEntries){
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber= new StringBuilder();
String line = null;
while((line = br.readLine())!=null){
strber.append(line+'\n');
}
result = strber.toString();
if(response.getStatusLine().getStatusCode()!=HttpStatus.SC_OK){
if(StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if(null != br) br.close();
if(null != in) in.close();
if(null != response) response.close();
if(null != httpclient) httpclient.close();
}
return result;
}
private static SSLConnectionSocketFactory getSSlContextByCrtAndKey(String crt, String privateKey) {
SSLConnectionSocketFactory sslsf = null;
try {
String crtContent = crt.split("-----BEGIN CERTIFICATE-----\n")[1].split("\n-----END CERTIFICATE-----")[0];
CertificateFactory factory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(crtContent)));
RSAPrivateKey key = (RSAPrivateKey)parseKey(privateKey, null);
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(null);
keystore.setCertificateEntry("cert-alias", cert);
//生成证书的密码,修改为自己的
keystore.setKeyEntry("key-alias", key, "123456".toCharArray(),new Certificate[] {cert});
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keystore, "123456".toCharArray());
//根据你的jdk版本决定是TLS、TLSv1.1、TLSv1.2
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(kmf.getKeyManagers(), null, null);
sslsf = new SSLConnectionSocketFactory(context);
} catch (Exception e) {
e.printStackTrace();
}
return sslsf;
}
这个私钥是pkcs1的,java里一般使用pkcs8的,pkcs8一般是这样的形式:
-----BEGIN PRIVATE KEY-----
xxxxx
-----END PRIVATE KEY-----
pkcs1转pkcs8可以用下面的代码来转换(先去掉一头一尾比如:-----BEGIN RSA PRIVATE KEY----- 、-----END RSA PRIVATE KEY-----、 -----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----,只拿中间的部分):
//format PKCS#1 to PKCS#8
public static String formatPkcs1ToPkcs8(String privateKey) throws Exception {
String result = null;
if (StringUtils.isNotBlank(privateKey))
{
//将BASE64编码的私钥字符串进行解码
byte[] encodeByte = Base64.decodeBase64(privateKey);
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag); //PKCSObjectIdentifiers.pkcs8ShroudedKeyBag
// ASN1Object asn1Object = ASN1Object.fromByteArray(encodeByte);
ASN1Object asn1Object = ASN1ObjectIdentifier.fromByteArray(encodeByte);
PrivateKeyInfo privKeyInfo = new PrivateKeyInfo(algorithmIdentifier, asn1Object);
byte[] pkcs8Bytes = privKeyInfo.getEncoded();
// String type = "PRIVATE KEY";
// result = format2PemString(type, pkcs8Bytes); // 格式化为pem多行格式输出
return Base64.encodeBase64String(pkcs8Bytes); // 直接一行字符串输出
}
return result;
}
上面的post方法中并没有用这个方法去转换pkcs8,而是用的下面的pasekey方法转的,这个方法可以直接传入pem形式的私钥。
/**
* Parses a Key instance from a PEM representation.
* <p>
* When the provided key is encrypted, the provided pass phrase is applied.
*
* @param pemString a PEM representation of a private key (cannot be null or empty)
* @param passPhrase optional pass phrase (must be present if the private key is encrypted).
* @return a Key instance (never null)
*/
public static Key parseKey(String pemString, String passPhrase) throws IOException {
if (passPhrase == null) {
passPhrase = "";
}
try (StringReader reader = new StringReader(pemString); //
PEMParser pemParser = new PEMParser(reader)) {
final Object object = pemParser.readObject();
final JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
final KeyPair kp;
if (object instanceof PEMEncryptedKeyPair) {
// Encrypted key - we will use provided password
final PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(passPhrase.toCharArray());
kp = converter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(decProv));
} else if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
// Encrypted key - we will use provided password
try {
final PKCS8EncryptedPrivateKeyInfo encryptedInfo = (PKCS8EncryptedPrivateKeyInfo) object;
final InputDecryptorProvider provider = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(passPhrase.toCharArray());
final PrivateKeyInfo privateKeyInfo = encryptedInfo.decryptPrivateKeyInfo(provider);
return converter.getPrivateKey(privateKeyInfo);
} catch (PKCSException | OperatorCreationException e) {
throw new IOException("Unable to decrypt private key.", e);
}
} else if (object instanceof PrivateKeyInfo) {
return converter.getPrivateKey((PrivateKeyInfo) object);
} else if (object instanceof SubjectPublicKeyInfo) {
return converter.getPublicKey((SubjectPublicKeyInfo) object);
} else {
// Unencrypted key - no password needed
kp = converter.getKeyPair((PEMKeyPair) object);
}
return kp.getPrivate();
}
}
用这个方法前要初始化下面这个:
static {
java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
====2022-12-19补充更新====
也可以直接设置信任所有证书的方式请求通ssl
信任所有的站点
HttpClientBuilder builder = HttpClientBuilder.create();
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslf = new SSLConnectionSocketFactory(sslContext,
NoopHostnameVerifier.INSTANCE);
builder.setSSLSocketFactory(sslf);
CloseableHttpClient httpclient = builder.build();
下面记录一个application/octet-stream发送文件请求例子:
package com.ly.mp.ota.apimanage.controller;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import com.ly.mp.ota.apimanage.utils.HttpRequestUtil;
import ly.mp.project.common.util.HmacSHA256Util;
public class Test {
public static void main(String[] args) throws Exception {
String appId = "eb22c0efa9da472db59430c7d0b8cqwe";
String appSecret = "db70c735ded44902a5d3fc29822dert";
String contentType = "application/octet-stream";
String url = "https://xxx/putfile";
String filePath = "D://upload/TEST0408S003.tar.gz";
File file = new File(filePath);
String date = String.valueOf(System.currentTimeMillis());
String encoding = "UTF-8";
String length = String.valueOf(file.length());
String md5Hash = "";
String stringToSign = encoding + "\n" + length + "\n" + md5Hash + "\n" + contentType + "\n" + date + "\n" + appId;
String hmacSHA = HmacSHA256Util.hmacSHA256(appSecret, stringToSign);
Map<String, String> headerMap = new HashMap<>();
headerMap.put("Authorization", appId + ":" + hmacSHA);
headerMap.put("x-version", "2022-06-27");
// headerMap.put("Content-Length", length);
headerMap.put("Content-Type", contentType);
headerMap.put("Content-Encoding", encoding);
headerMap.put("Date", date);
headerMap.put("x-content-disposition", "attachment; filename=\"" + file.getName() + "\"");
Integer code = HttpRequestUtil.octetStreamPut(filePath, url, headerMap);
System.out.println(code);
}
}
补充一下完整的HttpRequestUtil:
package com.ly.mp.ota.apimanage.utils;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentProducer;
import org.apache.http.entity.EntityTemplate;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMDecryptorProvider;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
import org.bouncycastle.operator.InputDecryptorProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
import org.bouncycastle.pkcs.PKCSException;
import com.alibaba.fastjson.JSONObject;
import ly.mp.project.common.util.LogUtils;
/**
* @ClassName:HttpRequestUtil
* @Description: Http请求
*/
public class HttpRequestUtil {
private String defaultContentEncoding;
static {
java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
public HttpRequestUtil() {
this.defaultContentEncoding = Charset.defaultCharset().name();
}
/**
* 默认的响应字符集
*/
public String getDefaultContentEncoding() {
return this.defaultContentEncoding;
}
/**
* 设置默认的响应字符集
*/
public void setDefaultContentEncoding(String defaultContentEncoding) {
this.defaultContentEncoding = defaultContentEncoding;
}
public static String post(JSONObject json, String url) throws Exception {
CloseableHttpClient httpclient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringEntity s = new StringEntity(json.toString(), "utf-8");
s.setContentEncoding("UTF-8");
/*发送json数据需要设置contentType*/
s.setContentType("application/json");
post.setEntity(s);
post.setHeader("Content-Type", "application/json;charset=utf-8");
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line + '\n');
}
result = strber.toString();
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
if (StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
// System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if (null != br) br.close();
if (null != br) in.close();
if (null != response) response.close();
if (null != httpclient) httpclient.close();
}
return result;
}
public static String post(JSONObject json, String url, Map<String, String> headerMap) throws Exception {
HttpClientBuilder builder = HttpClientBuilder.create();
CloseableHttpClient httpclient = builder.build();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringEntity s = new StringEntity(json.toString(), "utf-8");
s.setContentEncoding("UTF-8");
/*发送json数据需要设置contentType*/
s.setContentType("application/json");
post.setEntity(s);
post.setHeader("Content-Type", "application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line + '\n');
}
result = strber.toString();
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
if (StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if(br != null) br.close();
if(in != null) in.close();
if(response != null) response.close();
if(httpclient != null) httpclient.close();
}
return result;
}
public static String post(JSONObject json, String url, Map<String, String> headerMap, String p12Path, String password) throws Exception {
HttpClientBuilder builder = HttpClientBuilder.create();
SSLContext sslContext = getSSlContext(p12Path, password);
builder.setSSLContext(sslContext);
CloseableHttpClient httpclient = builder.build();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringEntity s = new StringEntity(json.toString(), "utf-8");
// s.setContentEncoding("UTF-8");
/*发送json数据需要设置contentType*/
s.setContentType("application/json");
post.setEntity(s);
post.setHeader("Content-Type", "application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line + '\n');
}
result = strber.toString();
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
if (StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if (null != br) br.close();
if (null != in) in.close();
if (null != response) response.close();
if (null != httpclient) httpclient.close();
}
return result;
}
public static String post(String json, String url, Map<String, String> headerMap, String crt, String privateKey) throws Exception {
HttpClientBuilder builder = HttpClientBuilder.create();
SSLConnectionSocketFactory sslf = getSSlContextByCrtAndKey(crt, privateKey);
// builder.setSSLContext(sslContext);
builder.setSSLSocketFactory(sslf);
CloseableHttpClient httpclient = builder.build();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringEntity s = new StringEntity(json, "utf-8");
// s.setContentEncoding("UTF-8");
/*发送json数据需要设置contentType*/
s.setContentType("application/json");
post.setEntity(s);
post.setHeader("Content-Type", "application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line + '\n');
}
result = strber.toString();
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
if (StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if (null != br) br.close();
if (null != in) in.close();
if (null != response) response.close();
if (null != httpclient) httpclient.close();
}
return result;
}
public static String vespaPost(String json, String url, Map<String, String> headerMap, String crt, String privateKey) {
HttpClientBuilder builder = HttpClientBuilder.create();
SSLConnectionSocketFactory sslf = getSSlContextByCrtAndKey(crt, privateKey);
// builder.setSSLContext(sslContext);
builder.setSSLSocketFactory(sslf);
CloseableHttpClient httpclient = builder.build();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringEntity s = new StringEntity(json, "utf-8");
// s.setContentEncoding("UTF-8");
/*发送json数据需要设置contentType*/
s.setContentType("application/json");
post.setEntity(s);
post.setHeader("Content-Type", "application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line).append('\n');
}
result = strber.toString();
// if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
// if (StringUtils.isBlank(result)) result = "服务器异常";
// throw new Exception(result);
// }
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
LogUtils.error("调用接口出错:{}",e);
} finally {
try {
if (null != br) {
br.close();
}
if (null != in) {
in.close();
}
if (null != response) {
response.close();
}
if (null != httpclient) {
httpclient.close();
}
}catch (Exception e){
LogUtils.error("调用接口出错:{}",e);
}
}
return result;
}
public static String vespaPut(String json, String url, Map<String, String> headerMap, String crt, String privateKey) {
HttpClientBuilder builder = HttpClientBuilder.create();
SSLConnectionSocketFactory sslf = getSSlContextByCrtAndKey(crt, privateKey);
// builder.setSSLContext(sslContext);
builder.setSSLSocketFactory(sslf);
CloseableHttpClient httpclient = builder.build();
HttpPut post = new HttpPut(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringEntity s = new StringEntity(json, "utf-8");
// s.setContentEncoding("UTF-8");
/*发送json数据需要设置contentType*/
s.setContentType("application/json");
post.setEntity(s);
post.setHeader("Content-Type", "application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line).append('\n');
}
result = strber.toString();
// if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
// if (StringUtils.isBlank(result)) result = "服务器异常";
// throw new Exception(result);
// }
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
LogUtils.error("调用接口出错:{}",e);
} finally {
try {
if (null != br) {
br.close();
}
if (null != in) {
in.close();
}
if (null != response) {
response.close();
}
if (null != httpclient) {
httpclient.close();
}
}catch (Exception e){
LogUtils.error("调用接口出错:{}",e);
}
}
return result;
}
public static SSLConnectionSocketFactory getSSlContextByCrtAndKey(String crt, String privateKey) {
SSLConnectionSocketFactory sslsf = null;
try {
String crtContent = crt.split("-----BEGIN CERTIFICATE-----\n")[1].split("\n-----END CERTIFICATE-----")[0];
CertificateFactory factory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(crtContent)));
RSAPrivateKey key = (RSAPrivateKey) parseKey(privateKey, null);
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(null);
keystore.setCertificateEntry("cert-alias", cert);
//生成证书的密码,修改为自己的
keystore.setKeyEntry("key-alias", key, "123456".toCharArray(), new Certificate[]{cert});
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keystore, "123456".toCharArray());
//根据你的jdk版本决定是TLS、TLSv1.1、TLSv1.2
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(kmf.getKeyManagers(), null, null);
sslsf = new SSLConnectionSocketFactory(context);
} catch (Exception e) {
LogUtils.error("getSSlContextByCrtAndKey 异常:{}",e);
}
return sslsf;
}
public static byte[] formatPkcs1ToPkcs8(String privateKey) throws Exception {
if (StringUtils.isNotBlank(privateKey)) {
//将BASE64编码的私钥字符串进行解码
byte[] encodeByte = org.apache.commons.codec.binary.Base64.decodeBase64(privateKey);
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag); //PKCSObjectIdentifiers.pkcs8ShroudedKeyBag
// ASN1Object asn1Object = ASN1Object.fromByteArray(encodeByte);
ASN1Object asn1Object = ASN1ObjectIdentifier.fromByteArray(encodeByte);
PrivateKeyInfo privKeyInfo = new PrivateKeyInfo(algorithmIdentifier, asn1Object);
byte[] pkcs8Bytes = privKeyInfo.getEncoded();
// String type = "PRIVATE KEY";
// result = format2PemString(type, pkcs8Bytes); // 格式化为pem多行格式输出
return Base64.encodeBase64(pkcs8Bytes); // 直接一行字符串输出
}
return null;
}
/**
* Parses a Key instance from a PEM representation.
* <p>
* When the provided key is encrypted, the provided pass phrase is applied.
*
* @param pemString a PEM representation of a private key (cannot be null or empty)
* @param passPhrase optional pass phrase (must be present if the private key is encrypted).
* @return a Key instance (never null)
*/
public static Key parseKey(String pemString, String passPhrase) throws IOException {
if (passPhrase == null) {
passPhrase = "";
}
try (StringReader reader = new StringReader(pemString); //
PEMParser pemParser = new PEMParser(reader)) {
final Object object = pemParser.readObject();
final JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
final KeyPair kp;
if (object instanceof PEMEncryptedKeyPair) {
// Encrypted key - we will use provided password
final PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(passPhrase.toCharArray());
kp = converter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(decProv));
} else if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
// Encrypted key - we will use provided password
try {
final PKCS8EncryptedPrivateKeyInfo encryptedInfo = (PKCS8EncryptedPrivateKeyInfo) object;
final InputDecryptorProvider provider = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(passPhrase.toCharArray());
final PrivateKeyInfo privateKeyInfo = encryptedInfo.decryptPrivateKeyInfo(provider);
return converter.getPrivateKey(privateKeyInfo);
} catch (PKCSException | OperatorCreationException e) {
throw new IOException("Unable to decrypt private key.", e);
}
} else if (object instanceof PrivateKeyInfo) {
return converter.getPrivateKey((PrivateKeyInfo) object);
} else if (object instanceof SubjectPublicKeyInfo) {
return converter.getPublicKey((SubjectPublicKeyInfo) object);
} else {
// Unencrypted key - no password needed
kp = converter.getKeyPair((PEMKeyPair) object);
}
return kp.getPrivate();
}
}
private static SSLContext getSSlContext(String p12Path, String password) {
SSLContext sslContext = null;
try {
KeyStore kstore = KeyStore.getInstance("PKCS12");
kstore.load(new FileInputStream(p12Path), password.toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance("sunx509");
keyFactory.init(kstore, password.toCharArray());
sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyFactory.getKeyManagers(), null, (SecureRandom) null);
} catch (Exception e) {
e.printStackTrace();
}
return sslContext;
}
private static SSLConnectionSocketFactory getSSlContext1(String p12Path, String password) {
SSLContext sslContext = null;
SSLConnectionSocketFactory sslsf = null;
try {
KeyStore kstore = KeyStore.getInstance("PKCS12");
kstore.load(new FileInputStream(p12Path), password.toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance("sunx509");
keyFactory.init(kstore, password.toCharArray());
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(kstore, password.toCharArray())
.build();
// Allow TLSv1 protocol only
sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[]{"TLSv1"},
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
// sslContext = SSLContext.getInstance("TLSv1.2");
// sslContext.init(keyFactory.getKeyManagers(), null, (SecureRandom) null);
} catch (Exception e) {
e.printStackTrace();
}
return sslsf;
}
/**
* ContentType.URLENCODED.getHeader()
*
* @param map
* @param url
* @param headerMap
* @param contentType
* @return
* @throws Exception
*/
public static String post(Map<String, String> map, String url, Map<String, String> headerMap, String contentType) throws Exception {
CloseableHttpClient httpclient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
List<NameValuePair> nameValuePairs = getNameValuePairList(map);
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nameValuePairs, "UTF-8");
/*发送json数据需要设置contentType*/
urlEncodedFormEntity.setContentType(contentType);
post.setEntity(urlEncodedFormEntity);
post.setHeader("Content-Type", contentType);
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line + '\n');
}
result = strber.toString();
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
if (StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if(br != null) br.close();
if(in != null) in.close();
if(response != null) response.close();
if(httpclient != null) httpclient.close();
}
return result;
}
private static List<NameValuePair> getNameValuePairList(Map<String, String> map) {
List<NameValuePair> list = new ArrayList<>();
for (String key : map.keySet()) {
list.add(new BasicNameValuePair(key, map.get(key)));
}
return list;
}
public static String post(String params, String url, Map<String, String> headerMap) throws Exception {
CloseableHttpClient httpclient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringEntity s = new StringEntity(params.toString(), "utf-8");
s.setContentEncoding("UTF-8");
/*发送json数据需要设置contentType*/
s.setContentType("application/json");
post.setEntity(s);
post.setHeader("Content-Type", "application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line + '\n');
}
result = strber.toString();
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
if (StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if(br != null) br.close();
if(in != null) in.close();
if(response != null) response.close();
if(httpclient != null) httpclient.close();
}
return result;
}
public static String put(JSONObject json, String url, Map<String, String> headerMap) throws Exception {
CloseableHttpClient httpclient = HttpClientBuilder.create().build();
HttpPut post = new HttpPut(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringEntity s = new StringEntity(json.toString(), "utf-8");
s.setContentEncoding("UTF-8");
/*发送json数据需要设置contentType*/
s.setContentType("application/json");
post.setEntity(s);
post.setHeader("Content-Type", "application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line + '\n');
}
result = strber.toString();
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
if (StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if(br != null) br.close();
if(in != null) in.close();
if(response != null) response.close();
if(httpclient != null) httpclient.close();
}
return result;
}
public static String delete(String url, Map<String, String> headerMap) throws Exception {
CloseableHttpClient httpclient = HttpClientBuilder.create().build();
HttpDelete post = new HttpDelete(url);
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
post.setHeader("Content-Type", "application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line + '\n');
}
result = strber.toString();
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
if (StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
//System.out.println("返回数据="+result);
} catch (Exception e) {
//System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if(br != null) br.close();
if(in != null) in.close();
if(response != null) response.close();
if(httpclient != null) httpclient.close();
}
return result;
}
public static String get(JSONObject paramsObj, String url, Map<String, String> headerMap) throws Exception {
CloseableHttpClient httpclient = HttpClientBuilder.create().build();
CloseableHttpResponse response = null;
InputStream in = null;
BufferedReader br = null;
String result = "";
try {
StringBuffer param = new StringBuffer();
int i = 0;
Set<Entry<String, Object>> entries = paramsObj.entrySet();
for (Entry<String, Object> entry : entries) {
if (i == 0)
param.append("?");
else
param.append("&");
param.append(entry.getKey()).append("=").append(entry.getValue());
i++;
}
url += param;
HttpGet post = new HttpGet(url);
// post.setHeader("Content-Type","application/json;charset=utf-8");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
post.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
response = httpclient.execute(post);
in = response.getEntity().getContent();
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder strber = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
strber.append(line + '\n');
}
result = strber.toString();
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
if (StringUtils.isBlank(result)) result = "服务器异常";
throw new Exception(result);
}
//System.out.println("返回数据="+result);
} catch (Exception e) {
// System.err.println("调用接口出错::::::::::::"+e.getMessage());
throw new Exception(e.getMessage());
} finally {
if(br != null) br.close();
if(in != null) in.close();
if(response != null) response.close();
if(httpclient != null) httpclient.close();
}
return result;
}
public static Integer octetStreamPut(String filePath, String url, Map<String, String> headerMap) throws Exception {
HttpClientBuilder builder = HttpClientBuilder.create();
// SSLContext sslContext = getSSlContext(p12Path, password);
// builder.setSSLContext(sslContext);
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
return true;
}
}).build();
builder.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext,
NoopHostnameVerifier.INSTANCE));
CloseableHttpClient httpclient = builder.build();
HttpPut put = new HttpPut(url);
CloseableHttpResponse response = null;
try {
ContentProducer myContentProducer = new ContentProducer() {
@Override
public void writeTo(OutputStream out) throws IOException
{
FileInputStream in = null;
try {
in = new FileInputStream(new File(filePath));
int byteread = 0;
byte[] buffer = new byte[1024];
while ((byteread = in.read(buffer)) != -1) {
out.write(buffer, 0, byteread);
}
} catch (Exception e) {
throw e;
} finally {
if(in != null) in.close();
}
}
};
put.setHeader("Content-Type", "application/octet-stream");
Set<Entry<String, String>> headerEntries = headerMap.entrySet();
for (Entry<String, String> headerEntry : headerEntries) {
put.setHeader(headerEntry.getKey(), headerEntry.getValue());
}
put.setEntity(new EntityTemplate(myContentProducer));
response = httpclient.execute(put);
LogUtils.info("response.code==={}", response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
LogUtils.info("服务器传输异常:{}", response);
throw new Exception(String.valueOf(response.getStatusLine().getStatusCode()));
}
return response.getStatusLine().getStatusCode();
} catch (Exception e) {
throw e;
} finally {
if(response != null) response.close();
if(httpclient != null) httpclient.close();
}
}
}
HmacSHA256Util:
package ly.mp.project.common.util;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class HmacSHA256Util {
/**
* HmacSHA256算法,返回的结果始终是32位
* @param key 加密的键,可以是任何数据
* @param content 待加密的内容
* @return 加密后的内容
* @throws Exception
*/
public static byte[] hmacSHA256(byte[] key,byte[] content) throws Exception {
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
hmacSha256.init(new SecretKeySpec(key, 0, key.length, "HmacSHA256"));
byte[] hmacSha256Bytes = hmacSha256.doFinal(content);
return hmacSha256Bytes;
}
/**
* 将加密后的字节数组转换成字符串
*
* @param b 字节数组
* @return 字符串
*/
public static String byteArrayToHexString(byte[] b) {
StringBuilder hs = new StringBuilder();
String stmp;
for (int n = 0; b!=null && n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1)
hs.append('0');
hs.append(stmp);
}
return hs.toString().toLowerCase();
}
/**
* sha256_HMAC加密
* @param message 消息
* @param secret 秘钥
* @return 加密后字符串
*/
public static String hmacSHA256(String secret, String message) throws Exception {
String hash = "";
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
hmacSha256.init(secret_key);
byte[] bytes = hmacSha256.doFinal(message.getBytes());
hash = byteArrayToHexString(bytes);
return hash;
}
public static void main(String[] args) {
String appSecret = "b06c75b58d1701ff470119a4114f8b45";
String appId = "10000001";
String timestamp = "1529853639000";
// HMAC-SHA256(appSecret,appId + timestamp+去除节点间的空格及换行符的请求体)
String message = appId + timestamp + "<req><orderId>91303183862452</orderId><notifyUrl></notifyUrl><refundTime>2013-03-22 16:25:26</refundTime><refundFee>24.5</refundFee><refundNo>14252414245</refundNo></req>";
System.out.println("加密前 =========>"+message);
String str = "";
try{
str = HmacSHA256Util.hmacSHA256(appSecret,message);
System.out.println("加密后 =========>"+str);
}catch (Exception e){
System.out.println("Error HmacSHA256 ===========>" + e.getMessage());
}
}
}
网友评论