升级 Https 的那些事

2,590 阅读3分钟

一、为什么升级Https

1、苹果iOS强制开启ATS标准

苹果宣布2017年1月1日起,所有提交到App Store 的App必须强制开启ATS安全标准(App Transport Security),所有连接必须使用Https加密。(后延期了,具体日期还没确定,详情见:developer.apple.com/news/?id=12…

2、Http协议无法加密数据

Http明文协议的缺陷,是导致数据泄露、数据篡改、流量劫持、钓鱼攻击等安全问题的重要原因。Http协议无法加密数据,所有通信数据都在网络中明文“裸奔”,通过网络的嗅探设备及一些技术手段,就可还原Http报文内容。

二、证书申请

1、货比三家

(1)、赛门铁克

优点:国际大厂,信誉保证
缺点:证书价格太贵,购买售后全为英文,不方便

(2)、沃通

优点:价格公道,国内多家网站使用,中文网站及客服
缺点:最便宜的证书不是沃通直接颁发

(3)、免费SSL

优点:免费,申请快
缺点:不适合企业使用

2、购买

综合考虑,个人可以考虑申请免费SSL,企业申请沃通的SSL

购买地址:www.wosign.com/price.htm

三、服务器配置证书(基于Wildfly(Jboss))

参考文档:www.cnblogs.com/maximo/p/57…

1、配置证书

找到Wildfly的配置文件路径 wildfly9\standalone\configuration\standalone.xml,在应用域加入keystore信息,并将证书(juemuren.com.jks)复制到同目录下,如下:


    
        
        
    
    
        
    



    
        
            
        
    

2、配置https监听

打开wildfly9\standalone\configuration\standalone.xml,在应用域加入


    
    
        
        
        
        
        
            
            
            
        
    
    
        
    
    
        
    
    
        
        
    

3、设置http跳转https

(1)、全局自动监听

修改wildfly9/standalone/deployments/juemuren.com.war/WEB-INF\web.xml


    
        juemuren.com
        /*
    
    
        CONFIDENTIAL
    

(2)、JS监听

在对应的页面html最开始添加下面的js代码:

四、APP配置(安卓端)

参考文档:www.cnblogs.com/punkisnotde…

1、Volley启用https支持

(1)、修改Volley源码

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.http.AndroidHttpClient;
import android.os.Build;
import android.util.Log;
import com.android.volley.Network;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.BasicNetwork;
import com.android.volley.toolbox.DiskBasedCache;
import com.android.volley.toolbox.HttpClientStack;
import com.android.volley.toolbox.HttpStack;
import com.android.volley.toolbox.HurlStack;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
public class Volley {
    /**
     * Default on-disk cache directory.
     */
    private static final String DEFAULT_CACHE_DIR = "volley";
    private static BasicNetwork network;
    private static RequestQueue queue;
    private Context mContext;
    /**
     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
     *
     * @param context A {@link Context} to use for creating the cache dir.
     * @param stack   An {@link HttpStack} to use for the network, or null for default.
     * @return A started {@link RequestQueue} instance.
     */
    public static RequestQueue newRequestQueue(Context context, HttpStack stack, boolean selfSignedCertificate, int rawId) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (NameNotFoundException e) {
        }
        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                if (selfSignedCertificate) {
                    stack = new HurlStack(null, buildSSLSocketFactory(context, rawId));
                } else {
                    stack = new HurlStack();
                }
            } else {
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                if (selfSignedCertificate)
                    stack = new HttpClientStack(getHttpClient(context, rawId));
                else {
                    stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
                }
            }
        }
        Network network = new BasicNetwork(stack);
        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();
        return queue;
    }
    /**
     * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
     *
     * @param context A {@link Context} to use for creating the cache dir.
     * @return A started {@link RequestQueue} instance.
     */
    public static RequestQueue newRequestQueue(Context context) {
        return newRequestQueue(context, null, false, 0);
    }
    private static SSLSocketFactory buildSSLSocketFactory(Context context, int certRawResId) {
        KeyStore keyStore = null;
        try {
            keyStore = buildKeyStore(context, certRawResId);
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = null;
        try {
            tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("TLS");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        try {
            sslContext.init(null, tmf.getTrustManagers(), null);
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslContext.getSocketFactory();
    }
    private static HttpClient getHttpClient(Context context, int certRawResId) {
        KeyStore keyStore = null;
        try {
            keyStore = buildKeyStore(context, certRawResId);
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (keyStore != null) {
        }
        org.apache.http.conn.ssl.SSLSocketFactory sslSocketFactory = null;
        try {
            sslSocketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(keyStore);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        }
        HttpParams params = new BasicHttpParams();
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
        ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
        return new DefaultHttpClient(cm, params);
    }
    private static KeyStore buildKeyStore(Context context, int certRawResId) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        Certificate cert = readCert(context, certRawResId);
        keyStore.setCertificateEntry("ca", cert);
        return keyStore;
    }
    private static Certificate readCert(Context context, int certResourceID) {
        InputStream inputStream = context.getResources().openRawResource(certResourceID);
        Certificate ca = null;
        CertificateFactory cf = null;
        try {
            cf = CertificateFactory.getInstance("X.509");
            ca = cf.generateCertificate(inputStream);
        } catch (CertificateException e) {
            e.printStackTrace();
        }
        return ca;
    }
}

(2)、使用for other server的证书(juemuren.crt),将证书放在raw文件夹下,RequestQueue按下面获取

RequestQueue mQueue= Volley.newRequestQueue(context, null, true, R.raw.juemuren);

(3)、StringRequest延长超时时长

StringRequest request=new StringRequest();
request.setRetryPolicy(new DefaultRetryPolicy(30 * 1000, 2, 1.0f))

2、兼容旧版本

新版本的接口全换成https的,要想兼容旧版本,服务器配置http跳转https的监听可以设置为js版本的监听。

完成以上设置之后,就可以愉快的用Https访问网站了,enjoy~