前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据处理思想和程序架构: 使用Mbedtls包中的SSL,和服务器进行网络加密通信

数据处理思想和程序架构: 使用Mbedtls包中的SSL,和服务器进行网络加密通信

作者头像
杨奉武
发布2020-10-27 11:03:42
2.6K0
发布2020-10-27 11:03:42
举报
文章被收录于专栏:知识分享

<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/单片机知识点总结/directory.html" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

单向认证忽略认证方式

1.首先保证自己的程序已经实现了普通TCP连接通信

为了保证此篇文章能够让所有人都能应用,我就假设我的程序里面已经实现了TCP连接\

然后规定:

代码语言:javascript
复制
/*假设接收网络数据函数*/
int net_recv(char *data);
/*假设TCP发送数据函数*/
int net_send(char *data,int len);

2.按照上一节 把MBEDTLS包添加到工程

3.config.h打开以下宏

#define MBEDTLS_HAVE_ASM

#define MBEDTLS_NO_UDBL_DIVISION

#define MBEDTLS_HAVE_TIME

#define MBEDTLS_ENTROPY_HARDWARE_ALT

#define MBEDTLS_AES_ROM_TABLES

#define MBEDTLS_CIPHER_MODE_CBC

#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED

#define MBEDTLS_NO_PLATFORM_ENTROPY

#define MBEDTLS_PKCS1_V15

#define MBEDTLS_SSL_PROTO_TLS1_2

#define MBEDTLS_AES_C

#define MBEDTLS_ASN1_PARSE_C

#define MBEDTLS_ASN1_WRITE_C

#define MBEDTLS_BIGNUM_C

#define MBEDTLS_CIPHER_C

#define MBEDTLS_CTR_DRBG_C

#define MBEDTLS_ENTROPY_C

#define MBEDTLS_GCM_C

#define MBEDTLS_MD_C

#define MBEDTLS_MD5_C

#define MBEDTLS_OID_C

#define MBEDTLS_PK_C

#define MBEDTLS_PK_PARSE_C

#define MBEDTLS_PLATFORM_C

#define MBEDTLS_RSA_C

#define MBEDTLS_SHA1_C

#define MBEDTLS_SHA256_C

#define MBEDTLS_SHA512_C

#define MBEDTLS_SSL_CLI_C

#define MBEDTLS_SSL_TLS_C

#define MBEDTLS_X509_USE_C

#define MBEDTLS_X509_CRT_PARSE_C

//下面这个是自己设置的加密套件

#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256

4.编译一下

5.选择C99模式

6.再编译一下

7.增加自己的随机数函数 和 时间戳返回函数

代码语言:javascript
复制
/*随机数函数*/
int mbedtls_hardware_poll( void *data,
                    unsigned char *output, size_t len, size_t *olen )
{
    unsigned long randomValue = ((rand()*20) + 1000);//生成随机数
    ((void) data);
    *olen = 0;
    
    if( len < sizeof(unsigned long) ) return( 0 );    

    memcpy( output, &randomValue, sizeof(unsigned long) );
    *olen = sizeof(unsigned long);
  return 0;
}

/**
* @brief  时间函数(SSL底层会调用时间验证证书是否过期)
**/
//struct tm *lcTime;
//time_t startTime;
//    lcTime = localtime (&startTime);
_ARMABI time_t time(time_t *t)
{
//    time_t it;
    if (t) {
        return *t;
    }
    else
    {
//        startTime = 0;
//        lcTime = localtime (&startTime);
//        it = mktime(lcTime);
//        return it ;
        return 0;
    }
}

8.增加SSL底层获取数据函数

咱们在后面设置好SSL接收回调函数以后, SSL底层会调用 custom_ssl_recv 函数

SSL底层要多少个数据,咱们才返回多少个数据,这是SSL底层规定的,所以为了配合SSL底层,程序写的比较多.

SSL底层调用的时候最后一个参数 size_t len是指定要多少个数据.

代码语言:javascript
复制
/**
* @brief  自定义接收函数(把自己的接收函数放到此函数中)
* @param  None
* @param  None
* @param  None
* @retval None
* @example 
**/
int net_recv_data_len=0; 
int net_recv_data_len_count=0;
char net_recv_buff[2000];
static int custom_ssl_recv( void *ctx, unsigned char *buf, size_t len )
{
    int rbCanReadLen;
    
    if(net_recv_data_len ==0)
    {
        net_recv_data_len=net_recv(net_recv_buff);//调用自己的函数接收数据
        if(net_recv_data_len>0)//有数据
        {
            if(len >= net_recv_data_len)//希望读取的数据个数大于实际的数据个数
            {
                len = net_recv_data_len;
                memcpy(buf, net_recv_buff, len);
                
                net_recv_data_len = 0;
                net_recv_data_len_count=0;
                return len;
            }
            else//实际的数据个数比希望读取的多
            {
                memcpy(buf, net_recv_buff, len);
                net_recv_data_len_count = len;
                return len;
            }
        }
        else
        {
            return MBEDTLS_ERR_NET_RECV_FAILED;
        }
    }
    else
    {
        if(len >= net_recv_data_len - net_recv_data_len_count)//希望读取的数据个数大于实际的数据个数
        {
            len = net_recv_data_len - net_recv_data_len_count;
            memcpy(buf, net_recv_buff+net_recv_data_len_count, len);
            net_recv_data_len = 0;
            net_recv_data_len_count=0;
            return len;
        }
        else//实际的数据个数比希望读取的多
        {
            memcpy(buf, net_recv_buff + net_recv_data_len_count, len);
            net_recv_data_len_count = net_recv_data_len_count + len;
            return len;
        }
    }
}

9.增加发送函数以供SSL底层调用

代码语言:javascript
复制
/*增加发送函数*/
static int custom_ssl_send( void *ctx, unsigned char *buf, size_t len )
{
    ctx = ctx;
    net_send(buf,len);//调用自己的TCP发送函数
    return (int)len;
}

10,定义需要的变量,并初始化SSL

代码语言:javascript
复制
int ret;//
const char *pers = "ssl_client1";
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;


void ssl_int(void)
{
    mbedtls_ssl_close_notify( &ssl );
    mbedtls_ssl_free( &ssl );
    mbedtls_ssl_config_free( &conf );
    mbedtls_ctr_drbg_free( &ctr_drbg );
    mbedtls_entropy_free( &entropy );
    
    //    mbedtls_debug_set_threshold( 1 );//
    mbedtls_ssl_init( &ssl );
    mbedtls_ssl_config_init( &conf );
    mbedtls_ctr_drbg_init( &ctr_drbg );
    mbedtls_entropy_init( &entropy );

    printf( "\n  . Seeding the random number generator..." );
    //DRBG---->Deterministic Random Bit Generators 伪随机数产生器
    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
                                                         (const unsigned char *) pers,
                                                         strlen( pers ) ) ) != 0 )
    {
            printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
    }
    
    
    //MBEDTLS_SSL_IS_CLIENT 表示配置为客户端
    //MBEDTLS_SSL_TRANSPORT_STREAM 表示传输方式为TLS
    //设置版本, MBEDTLS_SSL_PRESET_DEFAULT 表示 TLS1.0
    if( ( ret = mbedtls_ssl_config_defaults( &conf,
                                    MBEDTLS_SSL_IS_CLIENT,
                                    MBEDTLS_SSL_TRANSPORT_STREAM,
                                    MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
    {
            printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\r\n", ret );
    }
 
 
    /*设置数字证书检查模式 
    *  MBEDTLS_SSL_VERIFY_NONE:      peer certificate is not checked
    *                        (default on server)
    *                        (insecure on client)
    *
    *  MBEDTLS_SSL_VERIFY_OPTIONAL:  peer certificate is checked, however the
    *                        handshake continues even if verification failed;
    *                        mbedtls_ssl_get_verify_result() can be called after the
    *                        handshake is complete.
    *
    *  MBEDTLS_SSL_VERIFY_REQUIRED:  peer *must* present a valid certificate,
    *                        handshake is aborted if verification failed.
    *                        (default on client)
    */
    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE );
    // 配置随机数生成器的回调函数
    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
    // 配置调试回调函数
    //    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
    
    // 根据conf设置ssl结构
    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
    {
            mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned 0x%x\r\n", -ret );
    }

    // 设置host name 用到动态内存分配
    if( ( ret = mbedtls_ssl_set_hostname( &ssl, "替换自己的域名" ) ) != 0 )
    {
            mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\r\n", ret );
    }
    // 设置发送和接收接口
    mbedtls_ssl_set_bio( &ssl, NULL, custom_ssl_send, custom_ssl_recv, NULL );
}

11. 替换自己的域名

12,连接上TCP以后,等待SSL握手成功

13,发送和接收数据

注意:

1.如果显示这个..单片机不行,换个大点的型号的

我用的STM32F103RET6现在都有点不够使用,正在研究源码,看看怎么省内存.

2.我堆设置的是  a000

3.如果不能连接,可以打开DEBUG

#define MBEDTLS_DEBUG_C

4.配置DEBUG

代码语言:javascript
复制
/*设置 debug 输出函数*/
static void my_debug( void *ctx, int level,
                      const char *file, int line, const char *str )
{
    printf("%s:%04d: %s\r\n", file, line, str );
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-10-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单向认证忽略认证方式
  • 注意:
相关产品与服务
SSL 证书
腾讯云 SSL 证书(SSL Certificates)为您提供 SSL 证书的申请、管理、部署等服务,为您提供一站式 HTTPS 解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档