Linux-实现链路加密
1 mbedtls
mbedtls为嵌入式提供了最小化的链路加密方式,资源网站:tls.mbed.org
2 mbedtls交叉编译
1 在CMakeList.txt中添加 set(CMAKE_C_FLAGS "-std=c99") //mbedtls 3.0.0 以上需要
2 cmake -DUSE_SHARED_MBEDTLS_LIBRARY:Bool=ON -DENABLE_TESTING:Bool=OFF - DENABLE_PROGRAMS:Bool=ON -DCMAKE_C_COMPILER=arm-fsl-linux-gnueabi-gcc
3 make
3 证书生成方法
3.1 tls证书
3.1.1 正文
SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socketlayer(SSL),SSL安全协议主要用来提供对用户和服务器的认证;对传送的数据进行加密和隐藏;确保数据在传送中不被改变,即数据的完整性,现已成为该领域中全球化的标准。由于SSL技术已建立到所有主要的浏览器和WEB服务器程序中,因此,仅需安装服务器证书就可以激活该功能了)。即通过它可以激活SSL协议,实现数据信息在客户端和服务器之间的加密传输,可以防止数据信息的泄露。保证了双方传递信息的安全性,而且用户可以通过服务器证书验证他所访问的网站是否是真实可靠。 SSL网站不同于一般的Web站点,它使用的是“HTTPS”协议,而不是普通的“HTTP”协议。因此它的URL(统一资源定位器)格式为“”。
3.1.2 概念
首先要有一个CA根证书,然后用CA根证书来签发用户证书。 用户进行证书申请:一般先生成一个私钥,然后用私钥生成证书请求(证书请求里应含有公钥信息),再利用证书服务器的CA根证书来签发证书。
特别说明:(1)自签名证书(一般用于顶级证书、根证书): 证书的名称和认证机构的名称相同.(2)根证书:根证书是CA认证中心给自己颁发的证书,是信任链的起始点。任何安装CA根证书的服务器都意味着对这个CA认证中心是信任的。数字证书则是由证书认证机构(CA)对证书申请者真实身份验证之后,用CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机构的公章)后形成的一个数字文件。数字证书包含证书中所标识的实体的公钥(就是说你的证书里有你的公钥),由于证书将公钥与特定的个人匹配,并且该证书的真实性由颁发机构保证(就是说可以让大家相信你的证书是真的),因此,数字证书为如何找到用户的公钥并知道它是否有效这一问题提供了解决方案。
1 openssl中有如下后缀名的文件
.key格式:私有的密钥.csr格式:证书签名请求(证书请求文件),含有公钥信息,certificate signing request的缩写.crt格式:证书文件,certificate的缩写.crl格式:证书吊销列表,Certificate Revocation List的缩写.pem格式:用于导出,导入证书时候的证书的格式,有证书开头,结尾的格式
2 CA根证书的生成步骤
生成CA私钥(.key)-->生成CA证书请求(.csr)-->自签名得到根证书(.crt)(CA给自已颁发的证书)。
在实际的软件开发工作中,往往服务器就采用这种自签名的方式,因为毕竟找第三方签名机构是要给钱的,也是需要花时间的。
3 用户证书的生成步骤
生成私钥(.key)-->生成证书请求(.csr)-->用CA根证书签名得到证书(.crt)服务器端用户证书
3.2 根证书生成
1 openssl genrsa -out ca.key 2048
2 openssl req -new -key ca.key -out ca.csr
3 openssl x509 -req -days 3650 -in ca.csr -signkey ca.key -out ca.crt
4 openssl x509 -in ca.crt -text //查看证书内容
3.3 服务器证书生成
1 openssl genrsa -out server.key 2048
2 openssl req -new -key server.key -out server.csr
3 openssl x509 -req -days 3650 -inserver.csr -CAkey ca.key -CA ca.crt -CAcreateserial -out server.crt
4 openssl x509 -in server.crt -text
3.4 客户端证书生成
1 openssl genrsa -out client.key 2048
2 openssl req -new -key client.key -out client.csr
3 openssl x509 -req -days 3650 -inclient.csr -CAkey ca.key -CA ca.crt -CAcreateserial -out client.crt
4 openssl x509 -in client.crt -text
4 利用mbedtls实现链路加密
4.2 服务端实现方式
-
#if !defined(MBEDTLS_CONFIG_FILE)
-
#include "mbedtls/config.h"
-
#else
-
#include MBEDTLS_CONFIG_FILE
-
#endif
-
-
#if defined(MBEDTLS_PLATFORM_C)
-
#include "mbedtls/platform.h"
-
#else
-
#include
-
#include
-
#define mbedtls_time time
-
#define mbedtls_time_t time_t
-
#define mbedtls_fprintf fprintf
-
#define mbedtls_printf printf
-
#endif
-
-
#include "mbedtls/entropy.h"
-
#include "mbedtls/ctr_drbg.h"
-
#include "mbedtls/certs.h"
-
#include "mbedtls/x509.h"
-
#include "mbedtls/ssl.h"
-
#include "mbedtls/net_sockets.h"
-
#include "mbedtls/error.h"
-
#include "mbedtls/debug.h"
-
-
#if defined(MBEDTLS_SSL_CACHE_C)
-
#include "mbedtls/ssl_cache.h"
-
#endif
-
-
#define HTTP_RESPONSE \
-
"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
-
"mbed TLS Test Server\r\n" \
-
-
"Successful connection using: %s\r\n"
-
-
#define DEBUG_LEVEL 0
-
-
static char *ca_path = "/root/openssl/ca.crt"; //根证书
-
static char *cert_path = "/root/openssl/server.crt"; //服务器证书
-
static char *key_path = "/root/openssl/server.key"; //证书密钥
-
-
static void my_debug( void *ctx, int level,
-
const char *file, int line,
-
const char *str )
-
{
-
((void) level);
-
mbedtls_fprintf( (FILE *) ctx, "%s:%04d: %s", file, line, str );
-
fflush( (FILE *) ctx );
-
}
-
-
int main( void )
-
{
-
int ret, len;
-
mbedtls_net_context listen_fd, client_fd;
-
unsigned char buf[1024];
-
const char *pers = "ssl_server";
-
-
mbedtls_entropy_context entropy;
-
mbedtls_ctr_drbg_context ctr_drbg;
-
mbedtls_ssl_context ssl;
-
mbedtls_ssl_config conf;
-
mbedtls_x509_crt srvcert;
-
mbedtls_x509_crt cacert;
-
mbedtls_pk_context pkey;
-
#if defined(MBEDTLS_SSL_CACHE_C)
-
mbedtls_ssl_cache_context cache;
-
#endif
-
mbedtls_net_init( &listen_fd );
-
mbedtls_net_init( &client_fd );
-
mbedtls_ssl_init( &ssl );
-
mbedtls_ssl_config_init( &conf );
-
-
#if defined(MBEDTLS_SSL_CACHE_C)
-
mbedtls_ssl_cache_init( &cache );
-
#endif
-
-
mbedtls_x509_crt_init( &srvcert );
-
mbedtls_x509_crt_init( &cacert );
-
mbedtls_pk_init( &pkey );
-
mbedtls_entropy_init( &entropy );
-
mbedtls_ctr_drbg_init( &ctr_drbg );
-
-
#if defined(MBEDTLS_DEBUG_C)
-
mbedtls_debug_set_threshold( DEBUG_LEVEL );
-
#endif
-
mbedtls_printf( "\n . Loading the server cert. and key..." );
-
fflush( stdout );
-
-
ret = mbedtls_x509_crt_parse_file(&(cacert), ca_path);
-
if( ret != 0 )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret );
-
goto exit;
-
}
-
ret = mbedtls_x509_crt_parse_file(&(srvcert), cert_path);
-
if( ret != 0 )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret );
-
goto exit;
-
}
-
-
ret = ret = mbedtls_pk_parse_keyfile(&pkey, key_path, "");
-
if( ret != 0 )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret );
-
goto exit;
-
}
-
-
mbedtls_printf( " ok\n" );
-
-
mbedtls_printf( " . Bind on ..." );
-
fflush( stdout );
-
-
if( ( ret = mbedtls_net_bind( &listen_fd, NULL, "873", MBEDTLS_NET_PROTO_TCP ) ) != 0 )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_net_bind returned %d\n\n", ret );
-
goto exit;
-
}
-
-
mbedtls_printf( " ok\n" );
-
-
mbedtls_printf( " . Seeding the random number generator..." );
-
fflush( stdout );
-
-
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
-
(const unsigned char *) pers,
-
strlen( pers ) ) ) != 0 )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
-
goto exit;
-
}
-
-
mbedtls_printf( " ok\n" );
-
-
mbedtls_printf( " . Setting up the SSL data...." );
-
fflush( stdout );
-
-
if( ( ret = mbedtls_ssl_config_defaults( &conf,
-
MBEDTLS_SSL_IS_SERVER,
-
MBEDTLS_SSL_TRANSPORT_STREAM,
-
MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
-
goto exit;
-
}
-
-
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
-
mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
-
-
#if defined(MBEDTLS_SSL_CACHE_C)
-
mbedtls_ssl_conf_session_cache( &conf, &cache,
-
mbedtls_ssl_cache_get,
-
mbedtls_ssl_cache_set );
-
#endif
-
-
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
-
if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
-
goto exit;
-
}
-
-
if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret );
-
goto exit;
-
}
-
-
ret = mbedtls_ssl_set_hostname(&(ssl), "sixents");
-
if(ret != 0)
-
{
-
printf("mbedtls_x509_crt_parse failed, returned %d", ret);
-
return -1;
-
}
-
-
mbedtls_printf( " ok\n" );
-
-
reset:
-
#ifdef MBEDTLS_ERROR_C
-
if( ret != 0 )
-
{
-
char error_buf[100];
-
mbedtls_strerror( ret, error_buf, 100 );
-
mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf );
-
}
-
#endif
-
-
mbedtls_net_free( &client_fd );
-
mbedtls_ssl_session_reset( &ssl );
-
-
mbedtls_printf( " . Waiting for a remote connection ..." );
-
fflush( stdout );
-
-
if( ( ret = mbedtls_net_accept( &listen_fd, &client_fd,
-
NULL, 0, NULL ) ) != 0 )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_net_accept returned %d\n\n", ret );
-
goto exit;
-
}
-
-
mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
-
-
mbedtls_printf( " ok\n" );
-
-
mbedtls_printf( " . Performing the SSL/TLS handshake..." );
-
fflush( stdout );
-
-
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
-
{
-
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned %d\n\n", ret );
-
goto reset;
-
}
-
}
-
-
mbedtls_printf( " ok\n" );
-
-
mbedtls_printf( " < Read from client:" );
-
fflush( stdout );
-
-
do
-
{
-
len = sizeof( buf ) - 1;
-
memset( buf, 0, sizeof( buf ) );
-
ret = mbedtls_ssl_read( &ssl, buf, len );
-
-
if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
-
continue;
-
-
if( ret <= 0 )
-
{
-
switch( ret )
-
{
-
case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
-
mbedtls_printf( " connection was closed gracefully\n" );
-
break;
-
case MBEDTLS_ERR_NET_CONN_RESET:
-
mbedtls_printf( " connection was reset by peer\n" );
-
break;
-
default:
-
mbedtls_printf( " mbedtls_ssl_read returned -0x%x\n", -ret );
-
break;
-
}
-
break;
-
}
-
-
len = ret;
-
mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
-
-
if( ret > 0 )
-
break;
-
}
-
while( 1 );
-
-
/*
-
* 7. Write the 200 Response
-
*/
-
mbedtls_printf( " > Write to client:" );
-
fflush( stdout );
-
-
len = sprintf( (char *) buf, HTTP_RESPONSE,
-
mbedtls_ssl_get_ciphersuite( &ssl ) );
-
-
while( ( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0 )
-
{
-
if( ret == MBEDTLS_ERR_NET_CONN_RESET )
-
{
-
mbedtls_printf( " failed\n ! peer closed the connection\n\n" );
-
goto reset;
-
}
-
-
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret );
-
goto exit;
-
}
-
}
-
-
len = ret;
-
mbedtls_printf( " %d bytes written\n\n%s\n", len, (char *) buf );
-
mbedtls_printf( " . Closing the connection..." );
-
-
while( ( ret = mbedtls_ssl_close_notify( &ssl ) ) < 0 )
-
{
-
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
-
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
-
{
-
mbedtls_printf( " failed\n ! mbedtls_ssl_close_notify returned %d\n\n", ret );
-
goto reset;
-
}
-
}
-
mbedtls_printf( " ok\n" );
-
-
ret = 0;
-
goto reset;
-
-
exit:
-
-
#ifdef MBEDTLS_ERROR_C
-
if( ret != 0 )
-
{
-
char error_buf[100];
-
mbedtls_strerror( ret, error_buf, 100 );
-
mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf );
-
}
-
#endif
-
-
mbedtls_net_free( &client_fd );
-
mbedtls_net_free( &listen_fd );
-
mbedtls_x509_crt_free( &srvcert );
-
mbedtls_pk_free( &pkey );
-
mbedtls_ssl_free( &ssl );
-
mbedtls_ssl_config_free( &conf );
-
#if defined(MBEDTLS_SSL_CACHE_C)
-
mbedtls_ssl_cache_free( &cache );
-
#endif
-
mbedtls_ctr_drbg_free( &ctr_drbg );
-
mbedtls_entropy_free( &entropy );
-
-
#if defined(_WIN32)
-
mbedtls_printf( " Press Enter to exit this program.\n" );
-
fflush( stdout ); getchar();
-
#endif
-
-
return( ret );
-
}
-
-
4.3 客户端实现方式
-
typedef struct {
-
mbedtls_net_context net_context;
-
mbedtls_ssl_context ssl_context;
-
mbedtls_ssl_config conf;
-
mbedtls_x509_crt cacert;
-
-
mbedtls_x509_crt certchain;
-
mbedtls_pk_context pkey;
-
mbedtls_entropy_context entropy;
-
mbedtls_ctr_drbg_context ctr_drbg;
-
} tls_parm_t;
-
-
int tlscomm_init(tls_parm_t *tls_parm, tlsconf_t *tlsconf, const char *ser_addr, const char *ser_port)
-
{
-
int ret = 0;
-
int force_ciphersuite;
-
int corebuf_len = 8*1024;
-
int get_corebuf_len;
-
int len = 0;
-
-
-
if(tls_parm == NULL || tlsconf == NULL || ser_addr == NULL || ser_port == NULL)
-
{
-
zlog_error(o, "input parameter error!");
-
return -1;
-
}
-
-
len = sizeof(get_corebuf_len);
-
-
mbedtls_debug_set_threshold(tlsconf->debuglevel);
-
zlog_info(o, "init environment.");
-
-
mbedtls_net_init(&(tls_parm->net_context));
-
mbedtls_ssl_init(&(tls_parm->ssl_context));
-
mbedtls_ssl_config_init(&(tls_parm->conf));
-
mbedtls_x509_crt_init(&(tls_parm->cacert));
-
mbedtls_x509_crt_init(&(tls_parm->certchain));
-
mbedtls_pk_init(&(tls_parm->pkey));
-
mbedtls_entropy_init(&(tls_parm->entropy));
-
mbedtls_ctr_drbg_init(&(tls_parm->ctr_drbg));
-
-
ret = mbedtls_x509_crt_parse_file(&(tls_parm->cacert), tlsconf->cacert);
-
if(ret != 0)
-
{
-
mbedtls_strerror(ret, error_buf, 128);
-
zlog_error(o, "mbedtls_x509_crt_parse failed, returned %d - %s", ret, error_buf);
-
return -1;
-
}
-
-
ret = mbedtls_x509_crt_parse_file(&(tls_parm->certchain), tlsconf->cert);
-
if( ret != 0 )
-
{
-
mbedtls_strerror(ret, error_buf, 128);
-
zlog_error(o, "mbedtls_x509_crt_parse failed, returned %d - %s", ret, error_buf);
-
return -1;
-
}
-
-
-
ret = mbedtls_pk_parse_keyfile(&(tls_parm->pkey), tlsconf->key, "");
-
if(ret != 0)
-
{
-
mbedtls_strerror(ret, error_buf, 128);
-
zlog_error(o, "mbedtls_pk_parse_key failed, returned %d - %s", ret, error_buf);
-
return -1;
-
}
-
-
if((ret = mbedtls_ctr_drbg_seed(&(tls_parm->ctr_drbg), mbedtls_entropy_func, &(tls_parm->entropy),
-
(const unsigned char *)tlsconf->seed, tlsconf->seedlen)) != 0)
-
{
-
mbedtls_strerror(ret, error_buf, 128);
-
zlog_error(o, "mbedtls_ctr_drbg_seed failed, returned %d - %s", ret, error_buf);
-
return -1;
-
}
-
-
zlog_info(o, "config default environment.");
-
if((ret = mbedtls_ssl_config_defaults(&(tls_parm->conf),
-
MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
-
{
-
mbedtls_strerror(ret, error_buf, 128);
-
zlog_error(o, "mbedtls_ssl_config_defaults failed, returned %d - %s", ret, error_buf);
-
return -1;
-
}
-
-
force_ciphersuite = mbedtls_ssl_get_ciphersuite_id(tlsconf->ciphersuit);
-
mbedtls_ssl_conf_ciphersuites(&(tls_parm->conf), &force_ciphersuite);
-
mbedtls_ssl_conf_dbg(&(tls_parm->conf), my_debug, stdout);
-
mbedtls_ssl_conf_authmode(&(tls_parm->conf), MBEDTLS_SSL_VERIFY_REQUIRED);
-
mbedtls_ssl_conf_rng(&(tls_parm->conf), mbedtls_ctr_drbg_random, &(tls_parm->ctr_drbg));
-
mbedtls_ssl_conf_ca_chain(&(tls_parm->conf), &(tls_parm->cacert), NULL);
-
if((ret = mbedtls_ssl_conf_own_cert(&(tls_parm->conf), &(tls_parm->certchain), &(tls_parm->pkey))) != 0)
-
{
-
mbedtls_strerror(ret, error_buf, 128);
-
zlog_error(o, "mbedtls_ssl_conf_own_cert failed, returned %d - %s", ret, error_buf);
-
return -1;
-
}
-
-
if((ret = mbedtls_ssl_setup(&(tls_parm->ssl_context), &(tls_parm->conf))) != 0)
-
{
-
mbedtls_strerror(ret, error_buf, 128);
-
zlog_error(o, "mbedtls_ssl_setup failed, returned %d - %s", ret, error_buf);
-
return -1;
-
}
-
-
if((ret = tlscomm_connect(tls_parm, ser_addr, ser_port)) != 0)
-
{
-
zlog_error(o, "tlscomm_connect is error!");
-
return -1;
-
}
-
-
mbedtls_net_set_nonblock(&tls_parm->net_context);
-
-
setsockopt(tls_parm->net_context.fd, SOL_SOCKET, SO_SNDBUF,
-
(const char *)&corebuf_len, sizeof(int));
-
-
getsockopt(tls_parm->net_context.fd, SOL_SOCKET, SO_SNDBUF, &get_corebuf_len,
-
(socklen_t*)&len);
-
-
if((ret = mbedtls_ssl_set_hostname(&(tls_parm->ssl_context), tlsconf->certcn)) != 0)
-
{
-
mbedtls_strerror(ret, error_buf, 128);
-
return -1;
-
}
-
mbedtls_ssl_set_bio(&(tls_parm->ssl_context), &(tls_parm->net_context), mbedtls_net_send,
-
mbedtls_net_recv, mbedtls_net_recv_timeout);
-
mbedtls_ssl_conf_read_timeout(&(tls_parm->conf), 6000);
-
-
if((ret = mbedtls_ssl_handshake(&(tls_parm->ssl_context))) != 0)
-
{
-
mbedtls_strerror(ret, error_buf, 128);
-
zlog_error(o, "mbedtls_ssl_handshake failed, returned -0x%x - %s", -ret, error_buf);
-
if(ret == -0x6800)
-
{
-
tls_outtime_handle();
-
}
-
return -1;
-
}
-
-
if((ret = mbedtls_ssl_get_verify_result(&(tls_parm->ssl_context))) != 0)
-
{
-
char vrfy_buf[512];
-
mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", ret);
-
zlog_error(o, "mbedtls_ssl_get_verify_result failed, %s", vrfy_buf);
-
return -1;
-
}
-
return 0;
-
}
阅读(1910) | 评论(0) | 转发(0) |