古詩詞大全網 - 個性簽名 - Netty中使用SSL 雙向認證(包括證書生成)

Netty中使用SSL 雙向認證(包括證書生成)

雙向證書認證的雙方稱為client和server,首先為client和server生成證書。由於僅僅是自己學習使用,因此可以在本地自建壹個CA,然後用CA的證書分別簽發client和server的證書。CA的創建和簽發使用OpenSSL。

在windows環境上安裝OpenSSL,然後依據OpenSSL目錄下的openssl.cnf中[ CA_default ]的配置創建相應的文件夾和文件

serial這個文件中可以初始寫入壹行記錄,包含兩個字符01,表示下壹個簽發的證書采用的序列號是01

接下來生成CA自己的公私鑰(public/private key),生成證書簽名請求(CSR, Certificate Signing Request)文件並對該請求進行自簽名

在openssl的根目錄下運行

genrsa —- 同時生成public key和private key

很多人將genrsa解釋為只生成private key,這是不對的。可以用下面的命令從文件中解出公鑰

註意最後的數字2048表示生成的RSA公私鑰的長度

JDK7中對證書檢查要求公鑰的長度最少為1024位,否則會拋出異常

java.security.cert.CertPathValidatorException: Algorithm constraints check failed

該長度限制是可以配置的,配置文件路徑是JAVA_HOME/jre/lib/security/java.security

jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024

然後用上面生成的公私鑰文件創建壹個證書簽名請求文件

req —- 創建CSR或者證書

-key —- openssl從這個文件中讀取private key

careq.pem的內容格式是

最後將該請求文件給CA機構做簽名,但我們現在是想在本地建CA,因此自己對該文件進行自簽名即可。

其實,上面生成CSR然後做自簽名的兩個步驟可合並到壹步完成

至此,我們已經建立了自己的CA,接下去來分別簽發client和server的證書。

以創建client的證書為例。由於jdk自帶的keytool工具可以方便的創建key store和公私鑰,因此公私鑰和csr的創建直接使用keytool

key store和trust store分別對應於ssl握手證書認證中自己的證書和自己所信任的證書列表,二者的文件格式相同,不同之處是key store裏面包含ssl握手壹方的公私鑰和證書,trust store裏面包含ssl握手壹方所信任的證書,壹般沒有這些證書所對應的私鑰

client證書中我們想添加證書的壹項擴展,比如client id,用來區分client的身份,因此需要額外的壹份擴展文件client.cnf,內容如下

在導入之前,需要先將CA的證書導入keystore文件

然後導入client自己的證書。註意alias是client,與生產keystore和key pair的必須匹配

keystore文件內容的查看可以使用

或者使用可視化工具KeyStore Explorer查看

由於server的證書也是本地CA簽發的,因此client只要信任CA的證書那麽自然會信任CA簽發出的證書,所以我們只需將CA的證書導入trust store即可

由於clienttruststore.keystore文件尚不存在,此命令首先創建該文件並將CA的證書導入該trust store

由於netty 5現在只有alpha版本,因此保險起見使用4.0.24.final版本的netty。

netty的SSLContext提供了newClientContext來為client創建ssl context,但查看其源碼未發現能支持雙向認證,即client端的ssl context只接收壹個trust store,而不能指定自己的證書以供server端校驗。仿照netty example下的securechat的ssl實現但做了修改

首先創建壹個能提供client和server的ssl context的工具類,分別加載server和client的key store和trust store裏面的證書

io.netty.example.securechat.SecureChatClientInitializer類的構造器接收壹個io.netty.handler.ssl.SslContext類型的對象,這個SslContext的對象最終被用來創建SslHandler,而上面factory產生的是javax.net.ssl.SSLContext的對象,因此可以做改動如下

最後添加jvm參數

來查看ssl握手過程控制臺的log

具體實現請參考附件源碼。

f文件中修改

unique_subject=no

[ policy_match ]

countryName = match

organizationName = match

organizationalUnitName = optional

commonName = supplied

emailAddress = optional