创建证书
上面创建了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();
}
}
这里既验证了服务端,也验证了客户端,前提是客户端的证书已经传输过去。