Web证书?看这篇就够了

499 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

SSL安全证书

image

SSL证书是数字证书的一种,因为配置在服务器上,也称为SSL服务器证书。 SSL证书就是遵守 SSL协议,由受信任的数字证书颁发机构CA,在验证服务器身份后颁发,具有服务器身份验证和数据传输加密功能。 SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socket layer(SSL)安全协议是由Netscape Communication公司设计开发。该安全协议主要用来提供对用户和服务器的认证;对传送的数据进行加密和隐藏;确保数据在传送中不被改变,即数据的完整性,

SSL证书分为如下种类:

  • 扩展验证型(EV)SSL证书
  • 组织验证型(OV)SSL证书
  • 域名验证型(DV)SSL证书

网站使用ssl证书的好处

  • 传输加密(防止数据被窃取)
  • 防止钓鱼网站
  • 防止网站被劫持(被插入一些广告信息)
  • 提高SEO排名

获取证书的几种方式

1.自己签发

使用openssl给自己签发证书(自签CA)

1. openssl genrsa -out server.key 2048 #创建私钥
2. openssl req -new -key server.key -out server.csr #构造证书请求文件
3. openssl x509 -req -in server.csr -out server.crt -signkey server.key -days 3650 #自签证书
4. openssl x509 -in server.crt -out server.pem -outform PEM #生成pem格式的证书
#自签名的证书可以作为自己的CA(根)证书再签名二级证书
#ca.crt就是自签的ca证书,ca.key同上
openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key

#格式化创建CA的命令行
#CABase 作为CA的根目录
#CAType CA类型可以填RSA/RSA2SM2
#Orgnize 组织信息
#Name    授权名称
str := fmt.Sprintf("openssl req -new -x509 -days 3650  -extensions v3_ca -key %v/.%v.ca.key -subj=\"/C=CN/ST=shanghai/L=shanghai/O=%v/CN=%v\" -out %v/.%v.ca.crt ",CABase, CAType, Orgnize, Name, CABase, CAType)

#格式化证书请求文件命令行
#keypath 私钥路径
#Subject 证书请求主体:fmt.Sprintf("/C=CN/ST=shanghai/L=shanghai/O=%v/CN=%v",Orgnize, Name),
#csrpath 证书请求文件输出路径
str := fmt.Sprintf("openssl req -nodes -new -key %v -subj \"%v\" -out %v ", keypath,Subject, csrpath)

#格式化签发证书的命令行
#Days 证书有效期(天)
#csrpath 证书请求文件路径
#Serial 证书流水号
#crtpath 证书输出路径
signStr := fmt.Sprintf("openssl x509 -req -sha256 -extensions v3_req -days %v -in %v -CA %v/.%v.ca.crt -CAkey %v/.%v.ca.key -set_serial %v -out %v ", Days, csrpath,CABase,KeyType,CABase,Name,Serial, crtpath)
			

2.找云服务商买域名签发证书

阿里云和腾讯云等服务商有提供证书业务,可以购买证书或者使用免费的DV证书

3.LetsEncrypt免费的CA签发服务

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./certbot-auto certonly  -d *.你的域名 --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
#使用crontab自动续期

crontab -e  #编辑定时任务
0 */12 * * * certbot renew --quiet --renew-hook "/etc/init.d/nginx reload"

证书双向认证

1. 服务端配置(Nginx)

server {
        ...
        ssl                  on;  
        ssl_certificate      /data/sslKey/server-cert.cer;  #server证书公钥
        ssl_certificate_key  /data/sslKey/server-key.key;  #server私钥
        #双向认证的核心配置,配置客户端证书CA和开启客户端证书认证
        ssl_client_certificate /data/sslKey/root-cert.cer;  #根级证书公钥,用于验证各个二级client
        ssl_verify_client on;  #开启客户端证书验证  
        ...
    }

2.客户端配置(Java)

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
 
public class HttpsDemo {
    private final static String PFX_PATH = "client.p12";    //客户端证书路径
    private final static String PFX_PWD = "****";    //客户端证书密码
    
   public static String sslRequestGet(String url) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        InputStream instream = new FileInputStream(new File(PFX_PATH));
        try {
            keyStore.load(instream, PFX_PWD.toCharArray());
        } finally {
            instream.close();
        }
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, PFX_PWD.toCharArray()).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext
                , new String[] { "TLSv1" }    // supportedProtocols ,这里可以按需要设置
                , null    // supportedCipherSuites
                , SSLConnectionSocketFactory.getDefaultHostnameVerifier());    
  
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        try {
            HttpGet httpget = new HttpGet(url); 
//            httpost.addHeader("Connection", "keep-alive");// 设置一些heander等
            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                HttpEntity entity = response.getEntity();
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");//返回结果
                EntityUtils.consume(entity);
                return jsonStr;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
 
    public static void main(String[] args) throws Exception {
        System.out.println(sslRequestGet("https://www.test.com/"));
    }
}

3.curl命令行带证书和私钥访问

curl -k --cert client.pem --key key.pem https://www.xxxx.com

传送门

  1. Curl传送门
  2. letsencrypt.org传送门
  3. certbot|GitCode传送门