SSL练习代码 博客分类: secure javasecurity证书sslhttpsConnection
程序员文章站
2024-03-15 00:01:41
...
创建证书
上面创建了X509Certificate,并且把私钥和证书用字符串保存起来,这里用的是apache的commons-codec.jar里面的Base64。
建立SSLServerSocket
建立SSLClientSocket
自定义X509KeyManager
自定义X509TrustManager,这里checkServerTrusted验证服务端证书。
这里既验证了服务端,也验证了客户端,前提是客户端的证书已经传输过去。
package com.ssl; import com.security.X509CertificateInfo; import com.util.KeyUtility; import com.util.StringUtility; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.codec.binary.Base64; import sun.security.x509.AlgorithmId; import sun.security.x509.CertificateAlgorithmId; import sun.security.x509.CertificateIssuerName; import sun.security.x509.CertificateSerialNumber; import sun.security.x509.CertificateSubjectName; import sun.security.x509.CertificateValidity; import sun.security.x509.CertificateVersion; import sun.security.x509.CertificateX509Key; import sun.security.x509.X500Name; import sun.security.x509.X500Signer; import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertInfo; public class BuildCertificate { private String x509Certificate = "MIICRTCCAa6gAwIBAgIET8SU6DANBgkqhkiG9w0BAQQFADBnMRUwEwYDVQQKEwxPcmdhbml6YXRpb24xGTAXBgNVBAsTEE9yZ2FuaXphdGlvblVuaXQxETAPBgNVBAcTCExvY2FsaXR5MQ4wDAYDVQQIEwVzdGF0ZTEQMA4GA1UEAxMHY291bnRyeTAeFw0xMjA1MjkwOTIwNDBaFw0yMzEyMjIyMjE0MDBaMGcxFTATBgNVBAoTDE9yZ2FuaXphdGlvbjEZMBcGA1UECxMQT3JnYW5pemF0aW9uVW5pdDERMA8GA1UEBxMITG9jYWxpdHkxDjAMBgNVBAgTBXN0YXRlMRAwDgYDVQQDEwdjb3VudHJ5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUFhd0YhO9HFSEfQKDzKjN/EwKw7h4MxZaTvLqmhrSlkhN6p2rhHFePF0lWM4spVDTd285FYHrf3HOVl9Fm/5ChQeEqPNMBCkYgMDMEQhxKQ4Gpt/Nanf4awdoYYFwvP4Bj9kkMwLa9iAVstb4Y9idzTWVtjB8G5YT0CUeBi+y0wIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAHHySfSjsg8ogL/dPzF4eODkaYzBSIGHN03O5JEIRSzBpX5fXwPpJIuEX7g5NM8f4hv5wOgiAV8G7J9Bh1qGk6pv8QeYQBwSnEXyTDtekeTkWoyo8vP9VaJmQG9NhLQs4+3rnPtesIaMhLe3HTJ/+5bKKsg4SbC/cRlwWIQJ1Fob"; private String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJQWF3RiE70cVIR9AoPMqM38TArDuHgzFlpO8uqaGtKWSE3qnauEcV48XSVYziylUNN3bzkVget/cc5WX0Wb/kKFB4So80wEKRiAwMwRCHEpDgam381qd/hrB2hhgXC8/gGP2SQzAtr2IBWy1vhj2J3NNZW2MHwblhPQJR4GL7LTAgMBAAECgYBm/npvoqsR0zthLkTqgBRDt573uap6RyXbx58h1e6j2owNTQk+Oo5SuW8bQ4mZ+ZyehynfLPtAXFI97Uqz8kvCzuTPkOgD2Xt1f+vfD2y22VoBxh+Yp4U3dw/osDrK79WzD0fEdiW9mmtGzBSadYM8DmpBkR9pFYDVvCKgp3mf4QJBAM1PwrqefI9HFLBv0Xx3PS6H7rB/DG/GzQcaxGJRzx3B9GShYOmBw+CBsqt1wcpke0XlBF3OCQgsTBVeZE1F4cMCQQC4pYqCmx+GxPBj4m6LrBCLZiWe5pwybJDH+85k4Qpbt3AspTXphl73sJDZz9STgIQKw6RK80iPc4jU/GFAqkmxAkAQHjfiYLjUorbsFwsyI0ZJVeCWOJMoX0oPSbmrIlMJOgXOtKCgFFDlWilFrqv1EKhg11bdamRpINkkQFHNgzPzAkBXHMp/Gb5C79DV3vL2dEQN8DAZioTwiSW5I8RY9Y7UfHOwrHUF6n4Nb0C3cgTBXiVtiqWNMr/t5b0NdtBPGMfRAkEApxqnjmBZPWFjHHGWdqjYbru6WElVHvecNVLZRp0dScdqFArUg9V04hJPFP3Z/5sHo9d5v7nhzNeizbTkWGq6fQ=="; public KeyPair createKeyPair(int length) { KeyPair keyPair = null; try { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(length, new SecureRandom()); keyPair = keyPairGenerator.generateKeyPair(); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(X509CertificateInfo.class.getName()).log(Level.SEVERE, null, ex); } return keyPair; } public Certificate createCertificate(KeyPair keyPair, String name) { try { X500Name x500Name = new X500Name(name); Signature signature = Signature.getInstance("MD5WithRSA"); X500Signer signer = new X500Signer(signature, x500Name); X509CertInfo x509CertInfo = new X509CertInfo(); x509CertInfo.set(X509CertInfo.VERSION, new CertificateVersion(2)); x509CertInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber((int) (System.currentTimeMillis() / 1000L))); AlgorithmId algorithmId = signer.getAlgorithmId(); x509CertInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithmId)); x509CertInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName(x500Name)); x509CertInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic())); CertificateValidity interval = new CertificateValidity(new Date(), new Date(System.currentTimeMillis() + 365000000000L)); x509CertInfo.set(X509CertInfo.VALIDITY, interval); x509CertInfo.set(X509CertInfo.ISSUER, new CertificateIssuerName(signer.getSigner())); X509CertImpl x509CertImpl = new X509CertImpl(x509CertInfo); x509CertImpl.sign(keyPair.getPrivate(), "MD5WithRSA"); return x509CertImpl; } catch (InvalidKeyException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchProviderException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } catch (SignatureException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } catch (CertificateException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } return null; } public Certificate buildCert(String cert){ try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate certificate = (X509Certificate) cf.generateCertificate( new ByteArrayInputStream( Base64.decodeBase64(cert) ) ); return certificate; } catch (CertificateException ex) { Logger.getLogger(KeyUtility.class.getName()).log(Level.SEVERE, null, ex); } return null; } public PrivateKey buildKey(String key){ KeyFactory kf; try { kf = KeyFactory.getInstance("RSA"); PrivateKey privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(key))); return privateKey; } catch (InvalidKeySpecException ex) { Logger.getLogger(KeyUtility.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(KeyUtility.class.getName()).log(Level.SEVERE, null, ex); } return null; } public static void main(String args[]) { try { BuildCertificate buildCertificate = new BuildCertificate(); KeyPair keyPair = buildCertificate.createKeyPair(1024); X509Certificate x509Cert = (X509Certificate) buildCertificate.createCertificate(keyPair, "CN=country,ST=state,L=Locality,OU=OrganizationUnit,O=Organization"); byte[] bytes = x509Cert.getEncoded(); String cert = Base64.encodeBase64String(bytes); String privateKey = Base64.encodeBase64String(keyPair.getPrivate().getEncoded()); buildCertificate.setPrivateKey(privateKey); buildCertificate.setX509Certificate(cert); System.out.println(cert); System.out.println(privateKey); } catch (CertificateEncodingException ex) { Logger.getLogger(BuildCertificate.class.getName()).log(Level.SEVERE, null, ex); } } public String getPrivateKey() { return privateKey; } public String getX509Certificate() { return x509Certificate; } public void setPrivateKey(String privateKey) { this.privateKey = privateKey; } public void setX509Certificate(String x509Certificate) { this.x509Certificate = x509Certificate; } }
上面创建了X509Certificate,并且把私钥和证书用字符串保存起来,这里用的是apache的commons-codec.jar里面的Base64。
package com.ssl; import com.security.SSLKeyManager; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; public class SSLServer { public void sslServerSocket() { try { SSLContext sslc = SSLContext.getInstance("SSL"); BuildCertificate buildCertificate = new BuildCertificate(); String pk = buildCertificate.getPrivateKey(); String x509Cert = buildCertificate.getX509Certificate(); X509Certificate x509Certificate = (X509Certificate) buildCertificate.buildCert(x509Cert); System.out.println(x509Certificate); PrivateKey privateKey = buildCertificate.buildKey(pk); SSLKeyManager keyManager = new SSLKeyManager(privateKey, new X509Certificate[]{x509Certificate}); sslc.init(new KeyManager[]{keyManager}, null, null); SSLServerSocketFactory sslServer = sslc.getServerSocketFactory(); SSLServerSocket sslServerSocket = (SSLServerSocket) sslServer.createServerSocket(8030); Boolean flag = true; System.out.println("wait for customer connect"); while (flag) { Socket s = sslServerSocket.accept(); System.out.println("connected"); ObjectOutputStream os = new ObjectOutputStream(s.getOutputStream()); os.writeObject("server: hello"); os.flush(); ObjectInputStream input = new ObjectInputStream(s.getInputStream()); System.out.println(input.readObject()); os.close(); System.out.println(); s.close(); } sslServerSocket.close(); } catch (ClassNotFoundException ex) { Logger.getLogger(SSLServer.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(SSLServer.class.getName()).log(Level.SEVERE, null, ex); } catch (KeyManagementException ex) { Logger.getLogger(SSLServer.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(SSLServer.class.getName()).log(Level.SEVERE, null, ex); } } public static void main(String args[]) { SSLServer sslServer = new SSLServer(); sslServer.sslServerSocket(); } }
建立SSLServerSocket
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.ssl; import com.security.SSLClientSocket; import com.security.SSLTrustManager; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; public class SSLClient { public void clientSocket() { try { SSLContext context = getContext(); SSLSocketFactory ssf = context.getSocketFactory(); SSLSocket ss = (SSLSocket) ssf.createSocket("127.0.0.1", 8030); Certificate[] aCerts = ss.getSession().getPeerCertificates(); System.out.println(aCerts[0]); ObjectInputStream os = new ObjectInputStream(ss.getInputStream()); System.out.println(os.readObject()); ObjectOutputStream out = new ObjectOutputStream(ss.getOutputStream()); out.writeObject("client: hello"); os.close(); out.close(); ss.close(); } catch (ClassNotFoundException ex) { Logger.getLogger(SSLClient.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(SSLClient.class.getName()).log(Level.SEVERE, null, ex); } } public SSLContext getContext() { try { BuildCertificate buildCertificate = new BuildCertificate(); String x509Cert = buildCertificate.getX509Certificate(); X509Certificate x509Certificate = (X509Certificate) buildCertificate.buildCert(x509Cert); SSLContext context = SSLContext.getInstance("SSL"); context.init(null, new TrustManager[]{new SSLTrustManager(new X509Certificate[]{x509Certificate})}, null); return context; } catch (KeyManagementException ex) { Logger.getLogger(SSLClient.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(SSLClient.class.getName()).log(Level.SEVERE, null, ex); } return null; } public static void main(String args[]) { SSLClient sslClient = new SSLClient(); sslClient.clientSocket(); } }
建立SSLClientSocket
package com.security; import java.net.Socket; import java.security.Principal; import java.security.PrivateKey; import java.security.cert.X509Certificate; import javax.net.ssl.X509KeyManager; public class SSLKeyManager implements { private PrivateKey pk ; private X509Certificate[] x509; public SSLKeyManager(PrivateKey pk,X509Certificate[] x509){ this.pk = pk; this.x509 = x509; } public String[] getClientAliases(String string, Principal[] prncpls) { return new String[]{"default"}; } public String chooseClientAlias(String[] strings, Principal[] prncpls, Socket socket) { return "default"; } public String[] getServerAliases(String string, Principal[] prncpls) { return new String[]{"default"}; } public String chooseServerAlias(String string, Principal[] prncpls, Socket socket) { return "default"; } public X509Certificate[] getCertificateChain(String string) { return this.x509; } public PrivateKey getPrivateKey(String string) { return this.pk; } }
自定义X509KeyManager
package com.security; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; public class SSLTrustManager implements X509TrustManager{ private X509Certificate[] x509; public SSLTrustManager(X509Certificate[] x509){ this.x509 = x509; } public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { } public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { if (x509 == null) { return; } for (int i = 0; i < x509.length; i++) { if (xcs[0].equals(x509[i])) { System.out.println("verity pass"); return; } } throw new CertificateException("not match the certificate,verity failed"); } public X509Certificate[] getAcceptedIssuers() { return null; } }
自定义X509TrustManager,这里checkServerTrusted验证服务端证书。
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.ssl; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.HttpsURLConnection; public class HttpsConn { public void connenct() { try { URL url = new URL("https://www.liu.com"); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); https.setDoInput(true); https.setDoOutput(true); https.setRequestMethod("POST"); SSLClient client = new SSLClient(); https.setSSLSocketFactory(client.getContext().getSocketFactory()); //可以验证服务器证书 https.setRequestProperty("name", "liu"); https.setRequestProperty("password", "123"); BuildCertificate buildCertificate = new BuildCertificate(); String x509Cert = buildCertificate.getX509Certificate(); String data = "cert=" + x509Cert + "&computerName=abc"; OutputStream os = https.getOutputStream(); os.write(data.getBytes()); os.flush(); os.close(); } catch (IOException ex) { Logger.getLogger(HttpsConn.class.getName()).log(Level.SEVERE, null, ex); } } public void connect2() { try { URL url = new URL("https://www.liu.com"); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); https.setDoInput(true); https.setDoOutput(true); https.setRequestMethod("POST"); SSLClient client = new SSLClient(); https.setSSLSocketFactory(client.getContext().getSocketFactory()); //可以验证服务器证书 Signature sign = Signature.getInstance("MD5withRSA"); BuildCertificate buildCertificate = new BuildCertificate(); String pk = buildCertificate.getPrivateKey(); PrivateKey privateKey = buildCertificate.buildKey(pk); sign.initSign(privateKey); sign.update("abc".getBytes()); String computerName = Base64.encodeBase64String(sign.sign()); https.setRequestProperty("computerName", computerName); https.setRequestProperty("name", "liu"); https.setRequestProperty("password", "123"); } catch (InvalidKeyException ex) { Logger.getLogger(HttpsConn.class.getName()).log(Level.SEVERE, null, ex); } catch (SignatureException ex) { Logger.getLogger(HttpsConn.class.getName()).log(Level.SEVERE, null, ex); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(HttpsConn.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(HttpsConn.class.getName()).log(Level.SEVERE, null, ex); } } public static void main(String args[]) { HttpsConn httpsConn = new HttpsConn(); httpsConn.connenct(); } }
这里既验证了服务端,也验证了客户端,前提是客户端的证书已经传输过去。