目录
- 1 使用openssl生成自签名证书
- 2 VS2013编译mbedtls
- 3 mbdtls默认对证书的要求
- 4 mbdtls测试例子详解
- 5、运行测试程序
1 使用openssl生成自签名证书
openssl是一个安全套接字层密码库,囊括主要的密码算法、常用密钥、证书封装管理功能及实现ssl协议。其下载链接为https://www.openssl.org/。在ubuntu系统的安装方法,将源码拷贝到ubuntu中,然后执行下列语句:
sudo ./config 注:稍后测试,修改安装目录
sudo make
sudo make install
生成自签名证书:
生成RSA私钥(无加密)ca.key
openssl genrsa -out ca.key 2048
生成自签名证书ca.crt
openssl req -new -x509 -key ca.key -out ca.crt -days 365
注:需要注意Common Name (e.g. server FQDN or YOUR name) []:localhost,实际应用时应该是要对应自己的域名,如果不匹配握手会失败
生成服务端证书:
生成RSA私钥(无加密)server.key
openssl genrsa -out server.key 2048
生成证书请求server.csr
openssl req -new -key server.key -out server.csr
使用我们生成的ca.crt对我们的server.csr进行签名
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -days 365
生成客户端证书:
生成RSA私钥(无加密)client.key
openssl genrsa -out client.key 2048
生成证书请求client.csr
openssl req -new -key client.key -out client.csr
使用我们生成的ca.crt对我们的client.csr进行签名
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt -days 365
2 VS2013编译mbedtls
下载mbdtls源码,这里需要下载稳定版本的源码,才会有vs的工程,开发版本的源码是没有vs的工程的,下载完源码后打开如下目录:
mbedtls-2.16.5-apache\mbedtls-2.16.5\visualc\VS2010
选择ssl_server工程进行编译,会出现如下错误:
由图可知缺少windows的文件,在系统环境变量增加两个变量,如下所示:
WindowsSDK_LibraryPath_x86 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib;
WindowsSDK_IncludePath C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\include;
出现如下错误时
修改平台集为Visual Studio 2013 - Windows XP (v120_xp),到此可正常完成编译。
3 mbdtls默认对证书的要求
配置的结构体位于x509_crt.c
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
{
#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES)
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
#endif
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
0xFFFFFFF,
0xFFFFFFF,
2048,
};
注:这里表示最低支持密钥长度为2048
4 mbdtls测试例子详解
单向认证例子验证:
在ssl_client.c中将下列代码的MBEDTLS_SSL_VERIFY_OPTIONAL修改为MBEDTLS_SSL_VERIFY_REQUIRED模式
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
如果设置为MBEDTLS_SSL_VERIFY_OPTIONAL模式,那么客户端不会验证服务器证书的有效性,换句话说,即使验证失败,也可以正常通信,甚至于将CA测试证书mbedtls_test_cas_pem删除也没有关系。
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem,
mbedtls_test_cas_pem_len );
if( ret < 0 )
{
mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
goto exit;
}
单向认证的情况下,服务器端持有服务器证书(server.crt),CA证书(ca.crt),和服务器私钥(server.key),这些可用我们上述生成的证书文件,用winhex保存成数组后(末尾添加0x00)使用。
ret = mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) servercrt,
sizeof(servercrt) );
if( ret != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret );
goto exit;
}
ret = mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) cacrt,
sizeof(cacrt));
if( ret != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret );
goto exit;
}
ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *)server_key,
sizeof(server_key), NULL, 0);
if( ret != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret );
goto exit;
}
客户端持有CA证书(ca.crt),以求对服务器的证书做验证.
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) cacrt,
sizeof(cacrt) );
if( ret < 0 )
{
mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
goto exit;
}
双向认证例子验证:
双向认证的情况下,服务器端持有服务器证书(server.crt),CA证书(ca.crt),和服务器私钥(server.key),客户端持有客户端证书(client.crt),CA证书(ca.crt)客户端私钥(client.crt),这些可用我们上述生成的证书文件,用winhex保存成数组后(末尾添加0x00)使用。
服务端验证代码需要增加
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
客户端代码改动如下:
#if 1
ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *)clientcrt,
sizeof(clientcrt));
if (ret < 0)
{
mbedtls_printf(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
goto exit;
}
#endif
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) cacrt,
sizeof(cacrt) );
if( ret < 0 )
{
mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
goto exit;
}
#if 1
mbedtls_pk_context pkey;
mbedtls_pk_init(&pkey);
ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *)client_key,
sizeof(client_key), NULL, 0);
if (ret != 0)
{
mbedtls_printf(" failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret);
goto exit;
}
#endif
以及
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
if ((ret = mbedtls_ssl_conf_own_cert(&conf, &cacert, &pkey)) != 0)
{
mbedtls_printf(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret);
goto exit;
}
注:如果没有调用mbedtls_ssl_conf_own_cert,那么我们的证书就没有设置到,双向认证时,握手就会由于服务器读不到客户端证书而导致失败。
5、运行测试程序
先运行服务器程序,再运行客户端程序
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)