标签:x509 rod timeout hang inter manager tab cond Owner
问题1:什么叫做客户端证书认证?
答案:通过客户端证书(服务端分发的私人证书或者是通过第三方认证的证书)+账号密码进行身份认证的行为。
问题2:为什么有客户端证书这么个东西?
答案:如何加强服务器的用户身份验证系统?一个方法是通过服务端证书认证,就是通过https进行访问。另一个方法是客户端证书认证。通过暴力破解的方式任然可以获取到用户密码,尽管有强密码策略,仅仅只是依靠密码还是不太保险,这个时候就需要客户端证书认证。用户通过服务端颁发的证书+密码,可以极大的加强安全性。
问题3:怎么使用客户端证书认证?
答案:如下文
客户端证书认证
1.首先准备一个证书(本例以私人证书为例,证书生成方式具体请度娘),记录下证书最后的加密密码。
2.服务器配置相应的客户端证书认证设置(本例不涉及服务端配置)
3.配置java类库信任个人证书
1 package sz.shuwen.utils; 2 /* 3 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * - Neither the name of Sun Microsystems nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 /** 33 * Originally from: 34 * http://blogs.sun.com/andreas/resource/InstallCert.java 35 * Use: 36 * java InstallCert hostname 37 * Example: 38 *% java InstallCert ecc.fedora.redhat.com 39 */ 40 41 import javax.net.ssl.*; 42 import java.io.*; 43 import java.security.KeyStore; 44 import java.security.MessageDigest; 45 import java.security.cert.CertificateException; 46 import java.security.cert.X509Certificate; 47 48 /** 49 * Class used to add the server‘s certificate to the KeyStore 50 * with your trusted certificates. 51 */ 52 public class InstallCert { 53 54 /*public static void main(String[] args) throws Exception { 55 handle("XXX.com",443,"changeit"); 56 }*/ 57 58 public static void handle(String host,int port,String passphraseStr) throws Exception{ 59 char[] passphrase=passphraseStr.toCharArray(); 60 /*if ((args.length == 1) || (args.length == 2)) { 61 String[] c = args[0].split(":"); 62 host = c[0]; 63 port = (c.length == 1) ? 443 : Integer.parseInt(c[1]); 64 String p = (args.length == 1) ? "changeit" : args[1]; 65 passphrase = p.toCharArray(); 66 } else { 67 System.out.println("Usage: java InstallCert <host>[:port] [passphrase]"); 68 return; 69 }*/ 70 71 File file = new File("cacerts"); 72 if (file.isFile() == false) { 73 char SEP = File.separatorChar; 74 File dir = new File(System.getProperty("java.home") + SEP 75 + "lib" + SEP + "security"); 76 file = new File(dir, "jssecacerts"); 77 if (file.isFile() == false) { 78 file = new File(dir, "cacerts"); 79 } 80 } 81 System.out.println("Loading KeyStore " + file + "..."); 82 InputStream in = new FileInputStream(file); 83 KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 84 ks.load(in, passphrase); 85 in.close(); 86 87 SSLContext context = SSLContext.getInstance("TLS"); 88 TrustManagerFactory tmf = 89 TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 90 tmf.init(ks); 91 X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; 92 SavingTrustManager tm = new SavingTrustManager(defaultTrustManager); 93 context.init(null, new TrustManager[]{tm}, null); 94 SSLSocketFactory factory = context.getSocketFactory(); 95 96 System.out.println("Opening connection to " + host + ":" + port + "..."); 97 SSLSocket socket = (SSLSocket) factory.createSocket(host, port); 98 socket.setSoTimeout(10000); 99 try { 100 System.out.println("Starting SSL handshake..."); 101 socket.startHandshake(); 102 socket.close(); 103 System.out.println(); 104 System.out.println("No errors, certificate is already trusted"); 105 } catch (SSLException e) { 106 System.out.println(); 107 e.printStackTrace(System.out); 108 } 109 110 X509Certificate[] chain = tm.chain; 111 if (chain == null) { 112 System.out.println("Could not obtain server certificate chain"); 113 return; 114 } 115 116 BufferedReader reader = 117 new BufferedReader(new InputStreamReader(System.in)); 118 119 System.out.println(); 120 System.out.println("Server sent " + chain.length + " certificate(s):"); 121 System.out.println(); 122 MessageDigest sha1 = MessageDigest.getInstance("SHA1"); 123 MessageDigest md5 = MessageDigest.getInstance("MD5"); 124 for (int i = 0; i < chain.length; i++) { 125 X509Certificate cert = chain[i]; 126 System.out.println 127 (" " + (i + 1) + " Subject " + cert.getSubjectDN()); 128 System.out.println(" Issuer " + cert.getIssuerDN()); 129 sha1.update(cert.getEncoded()); 130 System.out.println(" sha1 " + toHexString(sha1.digest())); 131 md5.update(cert.getEncoded()); 132 System.out.println(" md5 " + toHexString(md5.digest())); 133 System.out.println(); 134 } 135 //注释 136 /*System.out.println("Enter certificate to add to trusted keystore or ‘q‘ to quit: [1]"); 137 String line = reader.readLine().trim();*/ 138 String line="1"; 139 int k; 140 try { 141 k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1; 142 } catch (NumberFormatException e) { 143 System.out.println("KeyStore not changed"); 144 return; 145 } 146 147 X509Certificate cert = chain[k]; 148 String alias = host + "-" + (k + 1); 149 ks.setCertificateEntry(alias, cert); 150 151 OutputStream out = new FileOutputStream("jssecacerts"); 152 ks.store(out, passphrase); 153 out.close(); 154 155 System.out.println(); 156 System.out.println(cert); 157 System.out.println(); 158 System.out.println 159 ("Added certificate to keystore ‘jssecacerts‘ using alias ‘" 160 + alias + "‘"); 161 } 162 163 164 private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); 165 166 private static String toHexString(byte[] bytes) { 167 StringBuilder sb = new StringBuilder(bytes.length * 3); 168 for (int b : bytes) { 169 b &= 0xff; 170 sb.append(HEXDIGITS[b >> 4]); 171 sb.append(HEXDIGITS[b & 15]); 172 sb.append(‘ ‘); 173 } 174 return sb.toString(); 175 } 176 177 private static class SavingTrustManager implements X509TrustManager { 178 179 private final X509TrustManager tm; 180 private X509Certificate[] chain; 181 182 SavingTrustManager(X509TrustManager tm) { 183 this.tm = tm; 184 } 185 186 public X509Certificate[] getAcceptedIssuers() { 187 188 /** 189 * This change has been done due to the following resolution advised for Java 1.7+ 190 http://infposs.blogspot.kr/2013/06/installcert-and-java-7.html 191 **/ 192 193 return new X509Certificate[0]; 194 //throw new UnsupportedOperationException(); 195 } 196 197 public void checkClientTrusted(X509Certificate[] chain, String authType) 198 throws CertificateException { 199 throw new UnsupportedOperationException(); 200 } 201 202 public void checkServerTrusted(X509Certificate[] chain, String authType) 203 throws CertificateException { 204 this.chain = chain; 205 tm.checkServerTrusted(chain, authType); 206 } 207 } 208 }
该类是在github上找的(感谢大佬),我注释的两处便是修改的地方,可也以取上面的链接看看大佬的代码,我把原方法通过main启动改为通过接口调用传参了。
4.调用
本例介绍两种调用方式:
a.通过postman调用
关闭公有证书校验,因为本例是个人证书,若是公有证书可以开启。
添加域名证书配置,作用是访问该域名才会携带配置的相应证书
CRT FILE:证书文件(含公钥)
KEY FILE:私钥文件
PFX FILE: 后缀为p12的加密证书文件
Passphrase:加密证书的密码,就是生成加密证书的那个密码
这四个参数如何填写,依据生成的证书实际情况来即可,下图是我的配置:
打开postman控制台查看调用结果
b.通过java代码调用
1 /** 2 * 发送 SSL POST 请求(HTTPS),JSON形式 3 * @param apiUrl API接口URL 4 * @param json JSON对象 5 * @return 6 */ 7 public static String doPostSSL(String apiUrl, Object json) { 8 CloseableHttpResponse response = null; 9 String httpStr = ""; 10 try { 11 response=doPostSSLRequest(apiUrl,json); 12 if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 13 httpStr = EntityUtils.toString(response.getEntity(), "UTF-8"); 14 } 15 } catch (Exception e) { 16 e.printStackTrace(); 17 } finally { 18 if (response != null) { 19 try { 20 EntityUtils.consume(response.getEntity()); 21 } catch (IOException e) { 22 e.printStackTrace(); 23 } 24 } 25 } 26 return httpStr; 27 } 28 29 /** 30 *@Author: pengshihao 31 *@Description:带证书 32 *@Date: 2019/7/4 33 */ 34 public static CloseableHttpResponse doPostSSLRequest(String apiUrl, Object json) throws Exception{ 35 //注意PKCS12证书 36 KeyStore keyStore = KeyStore.getInstance("PKCS12"); 37 //指向你的证书的绝对路径,带着证书去访问 38 FileInputStream instream = new FileInputStream(new File(Constant.SSL_CERT_PATH)); 39 //证书的密码,创建证书时的密码 40 keyStore.load(instream, Constant.SSL_CERT_PASSWORD.toCharArray()); 41 SSLContext sslContext = new SSLContextBuilder().loadKeyMaterial(keyStore,Constant.SSL_CERT_PASSWORD.toCharArray()).build(); 42 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, 43 new String[] { "TLSv1" },null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); 44 45 CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); 46 47 HttpPost httpPost = new HttpPost(apiUrl); 48 httpPost.addHeader("Accept", "*/*"); 49 httpPost.setHeader("Connection","Keep-Alive"); 50 httpPost.setHeader("Content-Type","application/json;charset=utf-8"); 51 httpPost.setHeader("Host",Constant.DATA_BASE_HOST); 52 httpPost.addHeader("Cache-Control", "max-age=0"); 53 httpPost.setEntity(new StringEntity(json.toString(),"UTF-8"));//解决中文乱码问题 54 55 return httpClient.execute(httpPost); 56 }
以上就是具体的实操。
标签:x509 rod timeout hang inter manager tab cond Owner
原文地址:https://www.cnblogs.com/potatoChicken/p/11147307.html