欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SSL练习代码 博客分类: secure javasecurity证书sslhttpsConnection

程序员文章站 2024-03-15 00:01:41
...
创建证书
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();
    }
}

这里既验证了服务端,也验证了客户端,前提是客户端的证书已经传输过去。