发送基于TLS1.2的HTTPS请求

来源:互联网 发布:前端怎么获取后端数据 编辑:程序博客网 时间:2024/05/16 10:28

本文主要介绍了如何发送基于TLS1.2安全协议的HTTPS请求

由于目前对网络安全越来越重视,我们会在HTTP的基础上加上一些安全协议

目前最为广泛所使用的安全协议是TLS1.2

很多服务端容器都已经支持通过配置来设置HTTPS的端口从而支持HTTPS协议

在发送HTTPS的请求之前我们需要获取服务端提供的签名证书

之后将签名证书通过keytool命令导入到本地的keystore中,方便java应用对其进行访问

想要发送HTTPS(TLS1.2)请求需要2个类的支持:

第一个类:

package com.HTTPtransfer.test;import java.io.FileInputStream;import java.security.KeyStore;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.cert.Certificate;import java.security.cert.CertificateFactory;import java.security.cert.X509Certificate;import java.util.Date;import javax.crypto.Cipher;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManagerFactory;/** * Certificate Model *  * @author  * @version 1.0 * @since 1.0 */public class CertificateManager extends Coder {    /**     * Java key store (Java Key Store,JKS)KEY_STORE     */    public static final String KEY_STORE = "JKS";    public static final String X509 = "X.509";    public static final String SunX509 = "SunX509";    public static final String SSL = "SSL";    /**     * accord KeyStore get private key     *      * @param keyStorePath     * @param alias     * @param password     * @return     * @throws Exception     */    private static PrivateKey getPrivateKey(String keyStorePath, String alias, String password) throws Exception {        KeyStore ks = getKeyStore(keyStorePath, password);        PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray());        return key;    }    /**     * accord Certificate get public key     *      * @param certificatePath     * @return     * @throws Exception     */    private static PublicKey getPublicKey(String certificatePath) throws Exception {        Certificate certificate = getCertificate(certificatePath);        PublicKey key = certificate.getPublicKey();        return key;    }    /**     * get Certificate     *      * @param certificatePath     * @return     * @throws Exception     */    private static Certificate getCertificate(String certificatePath) throws Exception {        CertificateFactory certificateFactory = CertificateFactory.getInstance(X509);        FileInputStream in = new FileInputStream(certificatePath);        Certificate certificate = certificateFactory.generateCertificate(in);        in.close();        return certificate;    }    /**     * get Certificate     *      * @param keyStorePath     * @param alias     * @param password     * @return     * @throws Exception     */    private static Certificate getCertificate(String keyStorePath, String alias, String password) throws Exception {        KeyStore ks = getKeyStore(keyStorePath, password);        Certificate certificate = ks.getCertificate(alias);        return certificate;    }    /**     * get KeyStore     *      * @param keyStorePath     * @param password     * @return     * @throws Exception     */    private static KeyStore getKeyStore(String keyStorePath, String password) throws Exception {        FileInputStream is = new FileInputStream(keyStorePath);        KeyStore ks = KeyStore.getInstance(KEY_STORE);        ks.load(is, password.toCharArray());        is.close();        return ks;    }    /**     * private key encrypt     *      * @param data     * @param keyStorePath     * @param alias     * @param password     * @return     * @throws Exception     */    public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath, String alias, String password)            throws Exception {        PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);        Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());        cipher.init(Cipher.ENCRYPT_MODE, privateKey);        return cipher.doFinal(data);    }    /**     * private key decrypt     *      * @param data     * @param keyStorePath     * @param alias     * @param password     * @return     * @throws Exception     */    public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath, String alias, String password)            throws Exception {        PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);        Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());        cipher.init(Cipher.DECRYPT_MODE, privateKey);        return cipher.doFinal(data);    }    /**     * public key encrypt     *      * @param data     * @param certificatePath     * @return     * @throws Exception     */    public static byte[] encryptByPublicKey(byte[] data, String certificatePath) throws Exception {        PublicKey publicKey = getPublicKey(certificatePath);        Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());        cipher.init(Cipher.ENCRYPT_MODE, publicKey);        return cipher.doFinal(data);    }    /**     * public key decrypt     *      * @param data     * @param certificatePath     * @return     * @throws Exception     */    public static byte[] decryptByPublicKey(byte[] data, String certificatePath) throws Exception {        PublicKey publicKey = getPublicKey(certificatePath);        Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());        cipher.init(Cipher.DECRYPT_MODE, publicKey);        return cipher.doFinal(data);    }    /**     * verify Certificate     *      * @param certificatePath     * @return     */    public static boolean verifyCertificate(String certificatePath) {        return verifyCertificate(new Date(), certificatePath);    }    /**     * verify Certificate is expired or invaild     *      * @param date     * @param certificatePath     * @return     */    public static boolean verifyCertificate(Date date, String certificatePath) {        boolean status = true;        try {            Certificate certificate = getCertificate(certificatePath);            status = verifyCertificate(date, certificate);        } catch (Exception e) {            status = false;        }        return status;    }    /**     * verify Certificate is expired or invaild     *      * @param date     * @param certificate     * @return     */    private static boolean verifyCertificate(Date date, Certificate certificate) {        boolean status = true;        try {            X509Certificate x509Certificate = (X509Certificate) certificate;            x509Certificate.checkValidity(date);        } catch (Exception e) {            status = false;        }        return status;    }    /**     * sign     *      * @param keyStorePath     * @param alias     * @param password     *      * @return     * @throws Exception     */    public static String sign(byte[] sign, String keyStorePath, String alias, String password) throws Exception {        X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath, alias, password);        KeyStore ks = getKeyStore(keyStorePath, password);        PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password.toCharArray());        Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());        signature.initSign(privateKey);        signature.update(sign);        return encryptBASE64(signature.sign());    }    /**     * vilidate sign     *      * @param data     * @param sign     * @param certificatePath     * @return     * @throws Exception     */    public static boolean verify(byte[] data, String sign, String certificatePath) throws Exception {        X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath);        PublicKey publicKey = x509Certificate.getPublicKey();        Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());        signature.initVerify(publicKey);        signature.update(data);        return signature.verify(decryptBASE64(sign));    }    /**     * validate Certificate     *      * @param keyStorePath     * @param alias     * @param password     * @return     */    public static boolean verifyCertificate(Date date, String keyStorePath, String alias, String password) {        boolean status = true;        try {            Certificate certificate = getCertificate(keyStorePath, alias, password);            status = verifyCertificate(date, certificate);        } catch (Exception e) {            status = false;        }        return status;    }    /**     * vilidate Certificate     *      * @param keyStorePath     * @param alias     * @param password     * @return     */    public static boolean verifyCertificate(String keyStorePath, String alias, String password) {        return verifyCertificate(new Date(), keyStorePath, alias, password);    }    /**     * get SSLSocektFactory     *      * @param password     * @param keyStorePath     * @param trustKeyStorePath     * @return     * @throws Exception     */    private static SSLSocketFactory getSSLSocketFactory(String password, String keyStorePath, String trustKeyStorePath)            throws Exception {        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(SunX509);        KeyStore keyStore = getKeyStore(keyStorePath, password);        keyManagerFactory.init(keyStore, password.toCharArray());        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(SunX509);        KeyStore trustkeyStore = getKeyStore(trustKeyStorePath, password);        trustManagerFactory.init(trustkeyStore);        SSLContext ctx = SSLContext.getInstance(SSL);        ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);        SSLSocketFactory sf = ctx.getSocketFactory();        return sf;    }    /**     * config SSLSocketFactory for HttpsURLConnectioncon     *      * @param conn     * HttpsURLConnection     * @param password     * @param keyStorePath     *      * @param trustKeyStorePath     * @throws Exception     */    public static void configSSLSocketFactory(HttpsURLConnection conn, String password, String keyStorePath,            String trustKeyStorePath) throws Exception {        conn.setSSLSocketFactory(getSSLSocketFactory(password, keyStorePath, trustKeyStorePath));    }}

第二个类:

package com.HTTPtransfer.test;import java.security.MessageDigest;import javax.crypto.KeyGenerator;import javax.crypto.Mac;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;/** * Base Encrypt Model *  * @author  * @version 1.0 * @since 1.0 */public abstract class Coder {    public static final String KEY_SHA = "SHA";    public static final String KEY_MD5 = "MD5";    /**     * Optional in many of the following algorithm MAC algorithm     *      * <pre>     * HmacMD5      * HmacSHA1      * HmacSHA256      * HmacSHA384      * HmacSHA512     * </pre>     */    public static final String KEY_MAC = "HmacMD5";    /**     * BASE64 Decrypt     *      * @param key     * @return     * @throws Exception     */    public static byte[] decryptBASE64(String key) throws Exception {        return (new BASE64Decoder()).decodeBuffer(key);    }    /**     * BASE64 Encrypt     *      * @param key     * @return     * @throws Exception     */    public static String encryptBASE64(byte[] key) throws Exception {        return (new BASE64Encoder()).encodeBuffer(key);    }    /**     * MD5 Encrypt     *      * @param data     * @return     * @throws Exception     */    public static byte[] encryptMD5(byte[] data) throws Exception {        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);        md5.update(data);        return md5.digest();    }    /**     * SHA Encrypt     *      * @param data     * @return     * @throws Exception     */    public static byte[] encryptSHA(byte[] data) throws Exception {        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);        sha.update(data);        return sha.digest();    }    /**     * InIt HMAC secret key     *      * @return     * @throws Exception     */    public static String initMacKey() throws Exception {        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);        SecretKey secretKey = keyGenerator.generateKey();        return encryptBASE64(secretKey.getEncoded());    }    /**     * HMAC Encrypt     *      * @param data     * @param key     * @return     * @throws Exception     */    public static byte[] encryptHMAC(byte[] data, String key) throws Exception {        SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);        Mac mac = Mac.getInstance(secretKey.getAlgorithm());        mac.init(secretKey);        return mac.doFinal(data);    }}

接下来才是发送HTTPS请求的方法:

package com.HTTPtransfer.test;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.URL;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLSession;import com.HTTPtransfer.test.Client_HTTP.ResponseBean;public class TLS_Https {    public static void httpsRequest(String urlpath, String body) {        ResponseBean resBean = new ResponseBean();        int responseCode = -1;        String responseMessage = "Exception.";        HttpsURLConnection conn = null;        try {            java.lang.System.setProperty("https.protocols", "TLS1.2");            URL u = new URL(urlpath);            conn = (HttpsURLConnection) u.openConnection();            conn.setHostnameVerifier(new HostnameVerifier() {                public boolean verify(String hostname, SSLSession session) {                    return true;                }            });            conn.setDoOutput(true);            conn.setDoInput(true);            conn.setConnectTimeout(20000);            conn.setReadTimeout(15000);            conn.setRequestMethod("POST");            conn.setUseCaches(false);            conn.setRequestProperty("Content-Type", "text/html;charset=UTF-8");            CertificateManager.configSSLSocketFactory(conn, Configuration.CLIENTPASSWORD,                    Configuration.CLIENTKEYSTOREPATH, Configuration.CLIENTTRUSTOREPATH);            conn.connect();            OutputStream out = conn.getOutputStream();            out.write(body.getBytes());            out.flush();            out.close();            // Sleep 50 mill seconds wait for response.            Thread.sleep(50);            responseCode = conn.getResponseCode();            if (responseCode == HttpURLConnection.HTTP_OK) {                InputStream in = conn.getInputStream();                BufferedReader br = new BufferedReader(new InputStreamReader(in, ConfigurationFiles.CLIENT_CHARSET));                String line = null;                StringBuilder sb = new StringBuilder();                while ((line = br.readLine()) != null) {                    sb.append(line);                }                in.close();                conn.disconnect();                String responseMsg = sb.toString();                resBean.httpstatus = responseCode;                if (null == resBean.result_code) {                    resBean.result_code = "999";                }                if (responseMessage == null) {                    responseMessage = conn.getResponseMessage();                }            } else {                resBean.httpstatus = responseCode;                resBean.result_code = "999";            }        } catch (Exception e) {            e.printStackTrace();        }        resBean.httpstatus = responseCode;        resBean.result_code = "999";    }}

在上面类中有3个对象是需要我们指定的,主要是keystore的绝对目录

Configuration.CLIENTPASSWORD
Configuration.CLIENTKEYSTOREPATH
Configuration.CLIENTTRUSTOREPATH

java.lang.System.setProperty("https.protocols", "TLS1.2")

能够将HTTPS的安全协议指定为TLS1.2