Bootstrap

HttpsURLConnection的使用

HttpURLConnection的API参见这里

扩展方法及返回

getCipherSuite():获得此次连接过程中用到的加密算法套件

getDefaultHostnameVerifier():获得被该类继承实例的默认认证域名

getDefaultSSLSocketFactory():获得被该类继承实例的默认静态SSL套接字工厂

getHostnameVerifier():获得该实例的认证域名

getLocalCertificates():获得握手阶段发送给服务端的证书

getLocalPrincipal():获得握手阶段发送给服务端的主体对象

getPeerPrincipal():获得定义此次会话的服务端的主体对象

getServerCertificates():获得定义此次会话的服务端的证书链(证书数组,一般是X509证书实例,猜的)

getSSLSocketFactory():获得安全SSL套接字工厂实例,用于建立https安全套接字连接

setDefaultHostnameVerifier(HostnameVerifier v):设置认证域名

setDefaultSSLSocketFactory(SSLSocketFactory sf):

设置SSL套接字工厂

setHostnameVerifier(HostnameVerifier v):…

setSSLSocketFactory(SSLSocketFactory sf): …

### 如何利用HttpsURLConnection建立SSL安全连接(单/双向认证)

懒得BB,先上一段代码:

“`
class UploadSignResultThread extends Thread {
@Override
public void run() {
super.run();
HttpsURLConnection connection = null;
try {
//设置SSLContext
SSLContext sslcontext = SSLContext.getInstance(“TLS”);
sslcontext.init(null, new TrustManager[]{myX509TrustManager}, null);

                String head_str = "{\"aid\":" + "\"" + header.getAid() + "\"" + "}";

                String payload_str = "{\"signature\":" + "\"" + mySignedData + "\"" + "}";

                String nonce_str = header.getNonce();

                String HMac = encryptHmac(hexStringToBytes((header.getNonce())),
                        (base64UrlEncode(head_str.getBytes()) + "."
                                + base64UrlEncode(payload_str.getBytes()) + "."
                                + base64UrlEncode(nonce_str.getBytes())).getBytes());

                String POST_JWT = "SignedMessage=" + base64UrlEncode(head_str.getBytes()) + "."
                        + base64UrlEncode(payload_str.getBytes()) + "."
                        + HMac;

                URL url = new URL(payload.getVerify());
                connection = (HttpsURLConnection) url.openConnection();
                connection.setSSLSocketFactory(sslcontext.getSocketFactory());
                connection.setConnectTimeout(3000);
                connection.setRequestMethod("POST");
                connection.setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
                byte[] postRes = POST_JWT.getBytes();
                // 获得输出流,向服务器输出内容
                OutputStream outputStream = connection.getOutputStream();
                // 写入数据
                outputStream.write(postRes, 0, postRes.length);
                outputStream.close();
                if (connection.getResponseCode() == 200) {
                    PostFlag = 0;
                } else {
                    PostFlag = 2;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }

        }
    }

还是上次的验签过程,现在通过Https认证实现:

1.首先设置与服务端相同的握手协议: 

SSLContext sslcontext = SSLContext.getInstance(“TLS”);

这里指定的是TLS,还有SSLv3等

2.设置初始化SSLcontext上下文的信任管理者:

sslcontext.init(null, new TrustManager[]{myX509TrustManager}, null);


这里的myX509TrustManager是我定义的内部类,其实现如下:

private static TrustManager myX509TrustManager = new X509TrustManager() {

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
    };
    }

这里,getAcceptedIssuers():返回可接受的发行者X509证书数组;

checkServerTrusted(X509Certificate[] chain, String authType):检查服务端证书链,将其与预埋入指定位置(android一般预埋至assets或者res/raw文件夹下)的服务端证书,该方法用主体和发行者比对的方式验证服务端证书链是否可信;

checkClientTrusted(X509Certificate[] chain, String authType):检查客户端证书链,将其与预埋入指定位置(android一般预埋至assets或者res/raw文件夹下)的客户端证书,该方法用主体和发行者比对的方式验证客户端证书链是否可信.


双向认证:实现上述后2个方法;单向认证:实现上述第2个验证服务端证书的方法;

而我,不验证,意思就是完全信任(关系铁,老铁).

3.根据SSLcontext上下文设置套接字工厂:

connection.setSSLSocketFactory(sslcontext.getSocketFactory());


4.设置域名认证,我偷懒默认允许所有,可以new 出个HostnameVerifier实现里面的方法,允许或屏蔽掉一些域名.

connection.setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

“`

- 就先写这么多,之后因为keystore的使用肯定会扩充,先这样,待续…
;