JAVA https ssl 连接验证服务端证书

在服务端部署的应用,很多情况下是采用HTTPS SSL 方式,这种方式唯一的好处是数据在通过浏览器传输到 web application server  之间是加密的,一般不容易破解。有时候需要另外一个客户端:比如是Android 应用用https 方式去调用 API , 从安全性角度考虑,服务端颁发的证书授权的域名或者IP或者主机名,应该与客户端请求的URL 是一致的。如果不一致,就可能存在安全隐患。

一般这种情况是在单向HTTPS 的情况才考虑,因为只有服务端证书,而没有客户端证书, 所以才需要验证客户端请求的URL 与服务端 证书授权的域名等是否一致。

看上去有点多此一举,但有些特例的情况下还是会用到, 它的一个基本思路是,首先是信任所有服务端的证书,连接上之后,再去获得证书的信息,然后对比请求的URL ,后面就是你自己的逻辑,想怎么玩就怎么玩, 下面是一段DEMO 代码
程序代码 程序代码

package com.test.www;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.security.cert.CertPath;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class Test1 {
    public static void main(String args[]) throws Exception {
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                System.out.println("Warning: URL Host: " + urlHostName
                        + " vs. " + session.getPeerHost());
                return true;
            }
        };
        trustAllHttpsCertificates();
        HttpsURLConnection.setDefaultHostnameVerifier(hv);

        SSLSocketFactory factory = HttpsURLConnection
                .getDefaultSSLSocketFactory();
        SSLSocket socket = (SSLSocket) factory.createSocket("portal.xxxxx.com",
                9443);// portal.xxxxx.com 192.168.1.15

        socket.startHandshake();
        SSLSession session = socket.getSession();
        // String sslHost = session.getPeerHost();
        // String host = "portal.xxxxx.com";
        // System.out.println("Host=" + host);
        // System.out.println("SSL Host=" + sslHost);
        // if (host.equals(sslHost)) {
        // System.out.println("good");
        // } else {
        // System.out.println("bad");
        // }

        java.security.cert.Certificate[] servercerts = session
                .getPeerCertificates();

        for (int i = 0; i < servercerts.length; i++) {
            X509Certificate c = (X509Certificate) servercerts[i];
            System.out.println(getValByAttributeTypeFromIssuerDN(c.getSubjectDN().toString(), "CN="));
        }

    }

    private static String getValByAttributeTypeFromIssuerDN(String dn,
            String attributeType) {
        String[] dnSplits = dn.split(",");
        for (String dnSplit : dnSplits) {
            if (dnSplit.contains(attributeType)) {
                String[] cnSplits = dnSplit.trim().split("=");
                if (cnSplits[1] != null) {
                    return cnSplits[1].trim();
                }
            }
        }
        return "";
    }

    private static void trustAllHttpsCertificates() throws Exception {
        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
        javax.net.ssl.TrustManager tm = new miTM();

        trustAllCerts[0] = tm;
        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
                .getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
                .getSocketFactory());
    }

    static class miTM implements javax.net.ssl.TrustManager,
            javax.net.ssl.X509TrustManager {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }

        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
    }
}



除非申明,文章均为一号门原创,转载请注明本文地址,谢谢!
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: java ssl https
相关日志:
评论: 0 | 引用: 0 | 查看次数: -
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.