mbedtls的ssl x509協(xié)議API

Nginx+openssl的web https訪問:

1證書的生成:

openssl genrsa -des3 -out host.key 2048

生成簽發(fā)機構密鑰

openssl req -new -x509 -days 7305 -key host.key -out host.crt

生成簽發(fā)用證書

openssl genrsa -des3 -out applier.pem 1024

請求認證的公司生成私鑰

openssl rsa -in applier.pem -out applier.key

生成applier.pem對應的解密密鑰applier.key

openssl req -new -key applier.pem -out applier.csr

請求認證的證書申請

openssl ca -policy policy_anything -days 1460 -cert host.crt -keyfile host.key -in applier.csr -out applier.crt

Ca對applier.csr簽名并發(fā)布證書applier.crt

//認證環(huán)境

mkdir -p CA/newcerts

touch CA/index.txt

touch CA/serial

echo "01" > CA/serial


2 Nginx的配置

Server{

Listen 443 ssl default_server;

Index index.html index.htm;

Location / {

Root /rootdir

}

Ssl on

Ssl_certificate /path/applier.crt ??#提供證書

Ssl_certificate_key /path/applier.key ?#提供解密私鑰

}

訪問時通過https協(xié)議直接訪問localhost,此時瀏覽器會與服務器握手并收到證書消息,由于試驗中使用的自簽名證書,因此瀏覽器會提示證書不可信,將此證書添加到exception中即可訪問。在服務器發(fā)給客戶機的證書報文段中,包含有服務器證書的公鑰;客戶機接收到該報文段后,按照協(xié)議規(guī)定,從報文段的對應位置中讀取出服務器證書的公鑰存入相關變量中。

與網(wǎng)站建立SSL安全連接時使用https協(xié)議,即采用https://ip:port/的方式來訪問。瀏覽器與Web Server之間要經(jīng)過一個握手的過程來完成身份鑒定與密鑰交換,從而建立安全連接。具體過程如下:

1用戶瀏覽器將其SSL版本號、加密設置參數(shù)、與session有關的數(shù)據(jù)以及其它一些必要信息發(fā)送到服務器。

服務器將其SSL版本號、加密設置參數(shù)、與session有關的數(shù)據(jù)以及其它一些必要信息發(fā)送給瀏覽器,同時發(fā)給瀏覽器的還有服務器的證書。如果配置服務器的SSL需要驗證用戶身份,還要發(fā)出請求要求瀏覽器提供用戶證書。

2客戶端檢查服務器證書,如果檢查失敗,提示不能建立SSL連接。如果成功,那么繼續(xù)。客戶端瀏覽器為本次會話生成pre-master secret,并將其用服務器公鑰加密后發(fā)送給服務器。如果服務器要求鑒別客戶身份,客戶端還要再對另外一些數(shù)據(jù)簽名后并將其與客戶端證書一起發(fā)送給服務器。

如果服務器要求鑒別客戶身份,則檢查簽署客戶證書的CA是否可信。如果不在信任列表中,結束本次會話。如果檢查通過,服務器用自己的私鑰解密收到的pre-master secret,并用它通過某些算法生成本次會話的master secret。

3客戶端與服務器均使用此master secret生成本次會話的會話密鑰(對稱密鑰)。在雙方SSL握手結束后傳遞任何消息均使用此會話密鑰。這樣做的主要原因是對稱加密比非對稱加密的運算量低一個數(shù)量級以上,能夠顯著提高雙方會話時的運算速度。 ?客戶端通知服務器此后發(fā)送的消息都使用這個會話密鑰進行加密。并通知服務器客戶端已經(jīng)完成本次SSL握手。 服務器通知客戶端此后發(fā)送的消息都使用這個會話密鑰進行加密。并通知客戶端服務器已經(jīng)完成本次SSL握手。

x509協(xié)議api

證書的初始化函數(shù):

void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ){

memset( crt, 0, sizeof(mbedtls_x509_crt) );}

證書的空間釋放函數(shù)

void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )

證書結構:

typedef struct mbedtls_x509_crt

{

mbedtls_x509_buf raw;隨機數(shù)據(jù)

mbedtls_x509_buf tbs;簽名

int version;版本

mbedtls_x509_buf serial; ??????????CA頒發(fā)的唯一序列號

mbedtls_x509_buf sig_oid;簽名算法,比如. sha1RSA *

mbedtls_x509_time valid_from;證書有效起始時間

mbedtls_x509_time valid_to;證書失效時間

mbedtls_pk_context pk;公鑰容器

int ext_types; ?????????????/**< Bit string containing detected and parsed extensions */

int max_pathlen;最大路徑長度

mbedtls_x509_buf sig;用私鑰加密后的簽名

mbedtls_md_type_t sig_md;信息摘要生成算法名稱. MBEDTLS_MD_SHA256mbedtls_pk_type_t sig_pk;簽名加密算法集的名稱MBEDTLS_PK_RSA */

struct mbedtls_x509_crt *next;指向下一個證書的指針

}

Mbedtls中的握手:

客戶端函數(shù)

int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )

輸入?yún)?shù)為ssl_context為安全連接的配置參數(shù),包含了握手狀態(tài)、握手參數(shù)、會話數(shù)據(jù)、客戶端ID以及相關回調(diào)入口等參數(shù)。

以下程序摘自ssl_tls.c文件,可以看出mbed根據(jù)宏定義分別實現(xiàn)了server端和client端

#if defined(MBEDTLS_SSL_CLI_C)

if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )

ret = mbedtls_ssl_handshake_client_step( ssl );

#endif

#if defined(MBEDTLS_SSL_SRV_C)

if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )

ret = mbedtls_ssl_handshake_server_step( ssl );

#endif

Client端的邏輯:

Client發(fā)起clienthello請求后,server回serverhello包以及certificate(如果對客戶端有認證需求則會跟隨發(fā)送一個certificate request包來請求客戶端的證書),之后client開始分析傳來的server證書是否有效合法:

首先確認是否需要證書驗證,通過判斷ssl->transform_negotiate->ciphersuite_info字段

MBEDTLS_KEY_EXCHANGE_ECJPAKE,

MBEDTLS_KEY_EXCHANGE_PSK,

MBEDTLS_KEY_EXCHANGE_DHE_PSK,

MBEDTLS_KEY_EXCHANGE_ECDHE_PSK

以上四種psk加密套件不需要證書交互,需要證書的加密套件如下:

MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,

MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,

MBEDTLS_KEY_EXCHANGE_ECDH_RSA,

MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,

其次驗證證書的有效性:mbedtls_x509_crt_verify_with_profile是x509_crt.c中的驗證函數(shù),其輸入?yún)?shù)是會話的peer證書、證書鏈、可信ca列表、認證配置文件、以及認證參數(shù)等。

1、對比CN字段是否匹配,若不匹配返回CN_MISMATCH錯誤---x509_memcasecmp函數(shù)

2、根據(jù)配置文件檢查密鑰大小和類型是否正確,不正確返回BAD_KEY錯誤----x509_profile_check_key函數(shù)

3、判斷CA的簽發(fā)方以及父簽發(fā)方(簽發(fā)鏈)是否可信-----x509_crt_check_parent函數(shù)

驗證完畢后,會判斷證書使用的是否是EC密鑰,如果是的話會使用函數(shù)mbedtls_ssl_check_curve來驗證橢圓曲線是否正確。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容