天天看點

OpenSSL配置HTTPS

最近項目在配 HTTPS,又在弄什麼證書,想着自己也弄一下吧

1. OpenSSL

OpenSSL 是一個實作加密和認證的軟體,而OpenSSH 是實作 SSH 遠端安全登入的軟體(其安全功能借用了OpenSSL),其提供秘鑰證書管理、對稱加密和非對稱加密等功能

常用參數如下:

  • -new:表示生成一個新證書簽署請求
  • genrsa:生成私鑰
  • rsa:提取公鑰
  • req:生成證書請求
  • x509:用于簽署證書請求檔案、生成自簽名證書、轉換證書格式等等的一個公鑰基礎設施

首先來了解下非對稱加密,然後再看 HTTPS 的流程,最後舉例使用

2. 非對稱加密

pem 是一種 Base64 編碼的消息傳輸編碼文法(還有der 文法), PKSC1,PKSC12 這些是證書的内部的存儲結構方式

Base64 防止不可見字元在傳輸過程中不同裝置對其不同處理導緻傳輸結果不同(隻包含英文、數字、+、/)

2.1 預設無密碼方式

openssl 預設采用 pem 文法,PKSC1格式存儲、注意 Java 是需要 PKSC12、JKS 格式才能使用,轉換格式(公鑰無需轉換)

# 生成私鑰
$openssl genrsa -out private.pem 1024

# PKSC1 格式轉成 pkcs8
$openssl pkcs8 -topk8 -inform PEM -in private.pem -outform pem -nocrypt -out private-pkcs8.pem

# pkcs8 格式轉成 PKSC1
$openssl rsa -in private-pkcs8.pem -out private.pem

# 提取公鑰
$openssl rsa -in private.pem -pubout -out public.pem
           
私鑰字尾常用 xxx.pem 或者 xxx.key,這裡容易混淆

2.2 指定加密算法加密碼

# 生成私鑰
$openssl genrsa -aes256 -out rsa_aes_private.key 2048

# 提取公鑰
$openssl rsa -in rsa_aes_private.key  -pubout -out rsa_aes_public.key

# 轉換格式
$openssl pkcs8 -topk8 -inform PEM -in rsa_aes_private.key -outform PEM -nocrypt -out rsa_aes_private_pkcs8.key
           

2.3 Java 生成密鑰對

public class Test {

    public static void main(String[] args) throws NoSuchAlgorithmException {
        
        // 密鑰對生成器
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        KeyPair keyPair = keyGen.generateKeyPair();

        byte[] privateKey = keyPair.getPrivate().getEncoded();
        byte[] publicKey = keyPair.getPublic().getEncoded();

        System.out.println(base64Encode(privateKey));
        System.out.println(base64Encode(publicKey));
    }

    // Base64 編碼
    static String base64Encode(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }
}
           

2.4 非對稱加密 RAS 算法原理

利用大整數因式分解困難、大素數乘積歐拉函數複雜的特點來保證鑰匙的安全性

流程:

  • 随機找兩個大質數 p、q
  • 算出兩質數的乘積 n
  • 算出質數乘積的歐拉函數 φ(n) (互質數複雜性:(p-1)(q-1) )
  • 随機選擇一個 φ(n) 的互質數 e
  • 根據 e 和 φ(n) 找出其中一個模反元素 d (二進制一次方程,d衆多解)
  • n 和 e 封裝成公鑰,其餘不公開
  • n 和 d 封裝成密鑰

安全性在于:知道公鑰(n、e)也解不出密鑰所需的 d:

  • d 源于模反,是以得知道e 和 φ(n) 才有解,而e在公鑰中已知,隻需知道 φ(n) 即可
  • φ(n) = (p-1)(q-1),得知道兩個質數才行,n 在公鑰中已知
  • n = p * q,(目前因式分解無解,安全性在此)

2. HTTPS 流程

3. 證書

3.1 名詞解釋

  • PKC:公鑰證書,簡稱證書。cer證書隻包含公鑰資訊,提供給用戶端使用
  • CA:認證機構,對證書進行管理
  • PKI:公鑰基礎設施,是為了更高效地運用公鑰而制定的一系列規範和規格的總稱(有PKCS、X509)
  • x509證書:一般會用到三類檔案,key,csr,crt
  • Key:私用密鑰,openssl格式,通常是rsa算法
  • csr:是證書請求檔案,用于申請證書。制作csr檔案時,必須使用自己的私鑰來簽署申請,還可以設定一個密鑰
  • crt:CA認證後的證書檔案(windows下面的csr,其實是crt),簽署人用自己的key給你簽署的憑證

3.2 準備

檢視 OpenSSL 預設配置,需将下面生成的檔案放入對應的目錄下。或者自行建立所需檔案

# 檢視版本全部資訊
openssl version -a


# 配置檔案位址
# OPENSSLDIR: "/etc/pki/tls"


# 配置檔案内容
touch /etc/pki/CA/index.txt 生成證書索引資料庫檔案
echo 01 > /etc/pki/CA/serial 指定第一個頒發證書的序列号
           

3.3 CA

CA 機構需要生成根證書,即自簽名的證書

# 生成 CA 的私鑰
openssl genrsa -out ca.key 2048


# 生成 CA 的自簽證書
openssl req -new -x509 -key ca.key -out ca.crt
           

3.4 Server

伺服器端需要将自己的證書請求交給 CA 機構簽署來生成伺服器端證書檔案

# 私鑰
openssl genrsa -out server.key 2048


# 生成證書請求檔案(有公鑰資訊)
# Common Name (eg, YOUR name) []:192.168.1.246   一定要寫伺服器所在的ip位址
openssl req -new -key server.key -out server.csr


# 将伺服器的證書請求檔案交給 CA 機構簽署,生成x509格式證書
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt


# 将證書轉成 Java 支援的.p12格式	
openssl pkcs12 -export -clcerts -in server.crt -inkey server.key -out server.pfx
           
也可生成 Client 證書(用于雙向認證)

3.5 示例

用戶端(Chrome)安裝 ca.crt,伺服器端指定 server.crt(伺服器端用 SpringBoot 測試)

server:
  port: 8443
  ssl:
    enabled: true
    key-store: classpath:server.pfx
    key-store-password: xxx
    keyStoreType: PKCS12