Intro
Two-way SSL 即 Server 端也要求 Client 端提供 certificate 做驗證,handshake 流程上是 Client 端先驗證 Server 端後才換 Server 端驗證 Client 端。
圖片來源:web-service-principles - HTTP
Client端憑證
Client 端需設定終端憑證及其對應的 Private Key,即可在 request 交握時提供終端憑證與簽名;
Server 端需設定 Client 憑證鏈對應的 CA 憑證,以用於驗證 Client 提供的終端憑證。
[Server] TLS/SSL憑證(Certificate)常用指令 – 製作CSR
Server 端範例
Server 端會需要指定 CA certificate,若有多張憑證鏈的應用,則可以合併多張 CA certificate 至同一個檔案。
Nginx 設定
Nginx 可以在 Server block 上啟用驗證 Client 端 certificate:
server {
listen 443 ssl;
ssl_certificate / etc / nginx / ssl / public.crt;
ssl_certificate_key / etc / nginx / ssl / private.rsa;
#
Client certificate verification
ssl_client_certificate / etc / nginx / ssl / client_ca.pem;
ssl_verify_client on;
server_name api.my_domain.com;
location / {
# ...
}
}
Apache 設定
<VirtualHost *:443>
ServerName example.com
# Enable SSL
SSLEngine on
# SSL server settings (for server authentication)
SSLCertificateFile /path/to/server.crt
SSLCertificateKeyFile /path/to/server.key
# Two-way SSL settings (for client authentication)
SSLCACertificateFile /path/to/combined_ca.crt
SSLVerifyClient require
SSLVerifyDepth 2
</VirtualHost>
Client 端範例
CURL
$ curl https://two-way-ssl.local --cert client.crt' --key client.key [--pass passPhrase]
# Key也可以bundle至CRT
$ curl https://two-way-ssl.local --cert crt-with-key.crt'
# PKCS#12 方法
$ curl https://two-way-ssl.local --cert-type P12 --cert cert.p12:password
PHP Guzzle
$response = $client->get('/', [
'cert' => '/path/client.crt',
'ssl_key' => '/path/client.key',
]
);
Pass Phrase情況:
'cert' => ['/path/client.crt', 'password'],
'ssl_key' => ['/path/client.key', 'password'],
JAVA (KeyStore)
JAVA 一般使用包含憑證與私鑰的 PKCS#12 格式或者轉成 JKS 載入 java.security.KeyStore
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(getClass().getResourceAsStream("/path/to/client_certificate.p12"), "passpharse".toCharArray());
// Build SSL configuration by keyStore