前言
各位对HTTPS
不陌生吧?几乎涉及安全的领域,均要求通过HTTPS协议进行数据传输。而在传输过程中,又涉及到了SSL证书的使用。既然提到了SSL证书
,那咱们先了解了解什么是SSL证书
:
SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(
Secure socket layerSSL
,安全套接层)安全协议是由Netscape Communication公司设计开发。该安全协议主要用来提供对用户和服务器的认证;对传送的数据进行加密和隐藏;确保数据在传送中不被改变,即数据的完整性,现已成为该领域中全球化的标准。——百度百科
简单讲,是一个连接客户与服务之间的“安全通道”
。通过它,我们可以确保数据的完整性、保密性,实现防泄露,防篡改等安全目的。
一、SSL原理
因为SSL证书可以满足绝大多数场景的数据传输安全,所以越来越多的数据厂商或者云服务商皆提供了免费的SSL证书服务。当然也有收费的(推荐
),毕竟数据安全永远是第一位的,“不怕一万,只怕万一”
。
1. 底层交互图
2. 重要术语
术语 | 作用 |
---|---|
CA(Certificate Authority,证书授权) | 一般理解为证书的服务机构。 负责证书签发、审核等。 |
Server | 使用证书的服务方 |
Client | 使用证书的客户方 |
一句话总结
:CA
向Server
签发一个有效的证书,当Client请求Server时,先会收到一个证书,Client基于此证书完成核验并协商下一步数据的传输。
二、SSL验证基础
1. X.509简介
X.509
是密码学里公钥证书的格式标准。 X.509 证书己应用在包括TLS/SSL
(WWW万维网安全浏览的基石)在内的众多 Internet协议里。同时它也用在很多非在线应用场景里,比如电子签名服务。
X.509
证书里含有公钥、身份信息(比如网络主机名,组织的名称或个体名称等)和签名信息(可以是证书签发机构CA的签名,也可以是自签名)。对于一份经由可信的证书签发机构签名或者可以通过其它方式验证的证书,证书的拥有者就可以用证书及相应的私钥来创建安全的通信,对文档进行数字签名。另外除了证书本身功能,X.509还附带了证书吊销列表和用于从最终对证书进行签名的证书签发机构直到最终可信点为止的证书合法性验证算法。
X.509
是ITU-T标准化部门基于他们之前的ASN.1定义的一套证书标准。
一句话总结
:X.509是一个证书规范和标准,据此我们可以完成相应的证书签发、核验等操作。
2. Java核心类
2.1 javax.net.ssl.SSLContext
根据javadoc
可SSLContext
是SSL协议的封装类。
解释
:此类的实例表示安全套接字协议的实现,它充当用于安全套接字工厂或 SSLEngine 的工厂。用可选的一组密钥和信任管理器及安全随机字节源初始化此类。
2.2 java.security.cert.X509Certificate
根据javadoc
可知X509Certificate
是SSL证书的封装类。
解释
:X.509 是证书的抽象类。此类提供了一种访问 X.509 v1 证书所有属性的标准方式。无法通过此接口提供专用于 X.509 v2 或 v3 的属性。以后的 API 发展会提供对全部 X.509 v3 属性的完全访问。
基本的 X.509 格式由 ISO/IEC 和 ANSI X9 所定义,用 ASN.1 描述如下:
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING }
这些证书被广泛使用以支持 Internet 安全系统中的身份验证和其他功能。常见的应用包括增强保密邮件 (PEM)、传输层安全 (SSL)、用于受信任软件发布的代码签名和安全电子交易 (SET)。
由证书颁发机构 (CA) 来管理和担保这些证书。CA 的工作是创建证书,方法是将数据置于 X.509 标准格式,然后以数字方式签署该数据。CA 充当受信任的第三方,在不能直接通信的主体之间传递信息。CA 证书可由其自身签名,也可由其他 CA 签名,如“根”CA。
2.3 javax.net.ssl.X509TrustManager
根据javadoc
可知X509TrustManager
是SSL证书验证的“凭据”
封装类。
解释
:TrustManager 负责管理做出信任决定时使用的的信任材料,也负责决定是否接受同位体提供的凭据。通过使用 TrustManagerFactory,或实现 TrustManager 子类之一创建 TrustManager。
三、SSL验证示例
通过一、二的介绍,我们具备了一定的理论基础和实践方向,接下来可以通过一个示例“小试牛刀”
了。且看以下代码:
SSLContext sc = SSLContext.getInstance("ssl");
sc.init(null, new TrustManager[] { new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// 验证服务器证书链
TrustManagerFactory trustManagerFactory;
try {
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
for (TrustManager trustManager : trustManagers) {
if (trustManager instanceof X509TrustManager) {
((X509TrustManager) trustManager).checkServerTrusted(chain, authType);
return;
}
}
} catch (NoSuchAlgorithmException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
throw new CertificateException("验证证书失败,请核查!");
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
} }, new java.security.SecureRandom());
在对SSL验证的时候,我们主要关注服务端证书的有效性,因此只需对其中的checkServerTrusted
方法进行实现。你只需要将以上代码贴在一个POST请求中,即可完成对服务端SSL证书的验证。
结语
本文对Springboot中如何完成服务端SSL证书的校验进行了介绍,相关背景和支持的工具均已阐述并提供。如需满足此需求,可直接贴博主的示例源码即可,欢迎关注与支持。