Openssl数据安全传输平台011:base64的使用

news2024/12/22 20:46:13

文章目录

  • 1 base64
    • 1.1 概念
    • 1.2 应用场景
  • 2 base64 算法 (重要)
  • 3 openssl 中base64的使用
    • 3.1 BIO 操作
    • 3.2 base64 编码 -> bio链的写操作
    • 3.3 base64 解码 -> bio链的读操作

1 base64

1.1 概念

Base64是一种基于64个可打印字符表示二进制数据的表示方法。在Base64中的可打印字符包括字母A-Za-z、数字0-9,这样共有62个字符,加上**+/**, 共64个字符.

  • 普通的文本数据也可以使用base64进行编解码
  • Base64编解码的过程是可逆的
  • Base64不能当做加密算法来使用

1.2 应用场景

在计算机中任何数据都是按ascii码存储的,而ascii码的128~255之间的值是不可见字符。 而在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备,由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。所以就先把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了。

  • base64 应用

    • 它可用来作为电子邮件的传输编码。
      • 附件: 图片/音频/视频-> 二进制
      • 邮件传输协议只支持 ASCII字符传递,因此如果要传输二进制文件:图片、视频是无法实现的。
    • Http协议
      • HTTP协议要求请求行和请求头都必须是ASCII编码
    • 数据库数据读写 - blob
      • blob格式: - 文件、音频、视频、图片
      • blob格式的数据中有一些特殊的数据:
        • 中文
          • 写之前进行编码
          • 读出来之后解码
        • 二进制数据

2 base64 算法 (重要)

  • 把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24)
    • 假设有一个字符串, 需要对这个字符串分组, 每3个字节为一组, 分成N组
    • 将每一组的3个字节拆分, 拆成4个字节, 每个字节有6bit
  • 在6位的前面补两个0,形成8位一个字节的形式
    • 每个组就从3个字节变成了4个字节
    • 结论: base64编码之后的字符串变大了,
  • 如果剩下的字符不足3个字节,则用0填充,输出字符使用’=‘,因此编码后输出的文本末尾可能会出现1或2个’=', 表示补了多少字节,解码的时候,会自动去掉。
  • 数据通过base64编码, 编码之后的数据边长了还是变短了?
    - 变长了
    - 每三个字节一组, 编码之后每组增加一个字节

  • 编码之后的数据末尾有可能有=, 这个=是什么意思?
    - =代表0, 0是给最后一组补位用的, 最后一组缺几个字节就补几个0
    - 在解码的时候根据=的个数去掉对应的字节数

在这里插入图片描述Base64 将 8 位为一个单元的字节数据,拆分为 6 位为一个单元的二进制片段。每一个 6 位单元对应 Base64 索引表中的一个字符。简单举个例子,下图中 M 的 ASCII 码是 77 , 而转换为二进制后前六位二进制对应值为 19,为 Base64 字典中的 T。
在这里插入图片描述

3 openssl 中base64的使用

3.1 BIO 操作

// 创建BIO对象
BIO *BIO_new(const BIO_METHOD *type);

// 封装了base64编码方法的BIO,写的时候进行编码,读的时候解码
BIO_METHOD* BIO_f_base64();

// 封装了内存操作的BIO接口,包括了对内存的读写操作
BIO_METHOD* BIO_s_mem();

// 创建一个内存型的BIO对象
// BIO * bio = BIO_new(BIO_s_mem());
BIO *BIO_new_mem_buf(void *buf, int len);

// 创建一个磁盘文件操作的BIO对象
BIO* BIO_new_file(const char* filename, const char* mode);

// 从BIO接口中读出len字节的数据到buf中。
// 成功就返回真正读出的数据的长度,失败返回0或-1,如果该BIO没有实现本函数则返回-2。
int BIO_read(BIO *b, void *buf, int len);
    - buf: 存储数据的缓冲区地址
    - len: buf的最大容量

// 往BIO中写入长度为len的数据。
// 成功返回真正写入的数据的长度,失败返回0或-1,如果该BIO没有实现本函数则返回-2。
int BIO_write(BIO *b, const void *buf, int len);
    - buf: 要写入的数据, 写入到b对应的设备(内存/磁盘文件)- len: 要写入的数据的长度
    - 
// 将BIO内部缓冲区的数据都写出去, 成功: 1, 失败: 0或-1
int BIO_flush(BIO *b);
    - 在使用BIO_write()进行写操作的时候, 数据有时候在openssl提供的缓存中
    - 将openssl提供的缓存中的数据刷到设备(内存/磁盘文件)// 把参数中名为append的BIO附加到名为b的BIO上,并返回b
// 连接两个bio对象到链表中
// 在链表中的关系: b->append
BIO * BIO_push(BIO *b, BIO *append);
    - b: 要插入到链表中的头结点
    - append: 头结点的后继
    - 
// 把名为b的BIO从一个BIO链中移除并返回下一个BIO,如果没有下一个BIO,那么就返回NULL。
BIO * BIO_pop(BIO *b);

typedef struct buf_mem_st BUF_MEM;
struct buf_mem_st {
    size_t length;              /* current number of bytes */
    char *data;
    size_t max;                 /* size of buffer */
    unsigned long flags;
};

// 该函数也是一个宏定义函数,它将b底层的BUF_MEM结构放在指针pp中。
BUF_MEM* ptr;
long BIO_get_mem_ptr(BIO *b, BUF_MEM **pp);
// 释放整个bio链
void BIO_free_all(BIO *a);

我们举几个简单的例子说明BIO_push和BIO_pop的作用,假设md1、md2是digest类型的BIO,b64是Base64类型的BIO,而f是file类型的BIO,那么如果执行操作,那么就会形成md1-md2-b64-f的BIO链,大家可以看到,在构造完一个BIO后,头一个BIO就代表了整个BIO链,这根链表的概念几乎是一样的

这时候,任何写往md1的数据都会经过md1,md2的摘要(或说hush运算),然后经过base64编码,最后写入文件f。可以看到,构造一条好的BIO链后,操作是非常方便的,你不用再关心具体的事情了,整个BIO链会自动将数据进行指定操作的系列处理。

需要注意的是,如果是读操作,那么数据会从相反的方向传递和处理,对于上面的BIO链,数据会从f文件读出,然后经过base64解码,然后经过md1,md2编码,最后读出。

BIO* md1 = BIO_new();    // md1 hash计算
BIO* md2 = BIO_new();    // md2 hash计算
BIO* b64 = BIO_new();    // base64 编解码
BIO* f = BIO_new();        // 操作磁盘文件

// 组织bio链
// b64->f
BIO_push(b64, f);
// 那么就会形成一个b64-f的链。然后再执行下面的操作:
// md2->b64->f
BIO_push(md2, b64);
// md1->md2->b64->f
BIO_push(md1, md2);

// bIO链
md1->md2->b64->f
// 写数据操作
int BIO_write(md1, "hello, world", 11);
// 数据的处理过程
// 进行md1 的哈希计算 -> md2的哈希计算 -> base64编码 -> 数据被写到磁盘

在这里插入图片描述

3.2 base64 编码 -> bio链的写操作

char* data = "hello, world";

// 创建base64编码的bio对象
BIO* b64 = BIO_new(BIO_f_base64());

// 最终在内存中得到一个base64编码之后的字符串
BIO* mem = BIO_new(BIO_s_mem());

// 将两个bio对象串联, 结构: b64->mem
BIO_push(b64, mem);

// 将要编码的数据写入到bio对象中
BIO_write(b64, data, strlen(data)+1);

// 将数据从bio对象对应的内存中取出 -> char*
BUF_MEM* ptr;

// 数据通过ptr指针传出
long BIO_get_mem_ptr(b64, &ptr);
char* buf = new char[ptr->length];
memcpy(buf, ptr->data, ptr->length);
printf("编码之后的数据: %s\n", buf);

3.3 base64 解码 -> bio链的读操作

// 要解码的数据
char* data = "xxxxxxxxxxxxxxxxxxxx";

// 创建base64解码的bio对象
BIO* b64 = BIO_new(BIO_f_base64());
#if 0
// 存储要解码的数据
BIO* mem = BIO_new(BIO_s_mem());
// 将数据写入到mem对应的内存中
BIO_write(mem, data, strlen(data));
#else
BIO *mem = BIO_new_mem_buf(data, strlen(data));
#endif

// 组织bio链
BIO_push(b64, mem);

// 读数据
char buf[1024];
int BIO_read(b64, buf, 1024);
printf("base64解码的数据: %s\n", buf);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1138900.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CTF-Web(3)文件上传漏洞

笔记目录 CTF-Web(2)SQL注入CTF-Web(3)文件上传漏洞 1.WebShell介绍 (1)一句话木马定义 一种网页后门,以asp、php、jsp等网页文件形式存在的一种命令执行环境,而 一句话木马往往只有一行WebShell代码。 作用: 攻击获得网站控制权限 查看、修改…

p5.js 状态管理

本文简介 带尬猴,我是德育处主任 原生 canvas 提供了 save() 和 restore() 两个方法去管理画布状态。p5.js 作为一个 canvas 库,也理所当然的提供了状态管理的方法。在 p5.js 里这两个方法叫 push() 和 pop()。 本文主要讲解 p5.js 的 push() 和 pop()…

Q41F-25C软密封球阀型号解析

Q41F-25C型号字母含义解析 Q41F-25C是德特森阀门常用的软密封球阀型号字母分别代表的意思是: Q——代表阀门类型《球阀》 4——代表连接方式《法兰》 1——代表结构形式《浮动式》 F——代表阀座材料《聚四氟乙烯PTFE》 -《分隔键》 25——代表公称压力《2.5MPA》 C——…

Ubuntu编译 PCL 1.13.1 详细流程

Ubuntu编译 PCL 1.13. 详细流程 一、编译环境二、虚拟机准备1. 虚拟机扩容2. 配置交换分区 三、Cmake - gui 生成 MakeFile1. 解决 flann 依赖问题2. 配置 Cmake 四、编译安装1.编译:2. 安装 一、编译环境 Ubuntu:Ubuntu 20.04 VMware:VMwar…

护眼灯亮度多少合适?2023最专业的护眼灯品牌推荐

护眼灯是现在广大台灯消费者使用最多的一个灯具种类,它主要带来了更加柔和的用光环境与护眼效果。而其中,护眼灯的国家级照度又是其挑选的重点,那A级跟AA级具体有啥区别呢?首先,护眼台灯的国家A级或者AA级标准&#xf…

R与Python结合,在安装tensorflow时遇到了报错--尚未解决

在服务器上安装tensorflow时,遇到了一个报错信息: 在网上找到一个类似的错误(TensorFlow_error),见下图,但是博主没有给出解决办法。

使用Hystrix实现请求合并,降低服务器并发压力

1.引入Hystrix <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency> 2.在启动类上开启Hystrix功能 EnableHystrix 3.请求合并实现代码 import com…

走进国产机器人领军品牌华数机器人,共探数字化变革魔力

近日&#xff0c;纷享销客举办的“一院两司服务对接会暨走进纷享销客【数字化标杆】游学示范基地活动”在佛山顺利举行&#xff0c;本期活动走进华中数控旗下品牌、国家级专精特新“小巨人”企业华数机器人&#xff0c;特邀佛山华数机器人有限公司常务副总经理杨林、纷享销客广…

Ubuntu 内核降级到指定版本

reference https://www.cnblogs.com/leebri/p/16786685.html 前往此网站&#xff0c;找到所需的内核 https://kernel.ubuntu.com/~kernel-ppa/mainline/ 查看系统架构 dpkg --print-architecture 二、下载安装包 注意&#xff1a;下载除lowlatency以外的deb包 三、安装内核 3…

C++前缀和算法的应用:从栈中取出 K 个硬币的最大面值和 原理源码测试用例

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 题目 一张桌子上总共有 n 个硬币 栈 。每个栈有 正整数 个带面值的硬币。 每一次操作中&#xff0c;你可以从任意一个栈的 顶部 取出 1 个硬币&#xff0c;从栈中移除…

【智能座舱】- 汽车产业的变革,电动化是上半场,而智能化则是下半场

“汽车产业的变革,电动化是上半场,而智能化则是下半场”,已成为汽车行业的普遍共识。对于制造业企业,伴随业务发展、长时间的生产经营,往往积淀着海量专业性知识,同时存在知识管理集中化与结构化困难、缺乏系统化知识体系、关键业务知识依靠传授、检索效率低下、精准度不…

STM32的BOOT1和BOOT0查找及配置-都有BOOT1引脚的

STM32 BOOT0和BOOT1引脚查找 STM32是有BOO0和BOOT1的&#xff0c;有的芯片原理图没有标注BOOT1&#xff0c;但是可以正在手册查到BOOT0和BOOT1引脚的。 STM32 BOOT配置方式 1&#xff09;主Flash 主Flash起始地址为0x08000000&#xff0c;它指的是STM32内置Flash&#xff0c;通…

共享办公:一种新型的工作方式

随着互联网技术的发展和创业文化的兴起&#xff0c;越来越多的人选择了在共享办公室工作。共享办公室是一种提供灵活、便捷和经济的工作空间的服务模式&#xff0c;它可以让不同的个人或团队在同一地点共享办公设施和资源。那么&#xff0c;共享办公室是什么&#xff1f;它有什…

TSINGSEE青犀省级高速公路视频上云联网方案:全面实现联网化、共享化、智能化

一、需求背景 随着高速铁路的建设及铁路管理的精细化&#xff0c;原有的模拟安防视频监控系统已经不能满足视频监控需求&#xff0c;越来越多站点在建设时已开始规划高清安防视频监控系统。高速公路视频监控资源非常丰富&#xff0c;需要对其进行综合管理与利用。通过构建监控…

国际腾讯云直播推流配置教程!

云直播的服务本质是一个广播的过程&#xff0c;类似于电视台的直播节目通过有线电视网发送给千家万户。为了完成这个过程&#xff0c;云直播需要有采集和推流设备&#xff08;类似摄像头&#xff09;、云直播服务&#xff08;类似电视台的有线电视网&#xff09;和播放设备&…

银河麒麟v10x86或者arm离线安装服务

银河麒麟v10x86或者arm离线安装服务 最近有个项目&#xff0c;甲方的服务器用的全是国产化服务器银河麒麟&#xff0c;架构是x86的然后也无法连接外网&#xff0c;需要离线安装服务正常思路就是找到离线安装的包&#xff0c;然后拷贝到现场的服务器中进行安装所以问题就在于如…

【计算机网络笔记】Web应用之HTTP协议(涉及HTTP连接类型和HTTP消息格式)

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

C++ Qt/VTK装配体组成联动连接杆

效果 关键代码 #include "View3D.h" #include "Axis.h"#include <vtkActor.h> #include <vtkAppendPolyData.h > #include <vtkAreaPicker.h> #include <vtkAxesActor.h> #include <vtkBox.h> #include <vtkCamera.h>…

使用内网穿透本地MariaDB数据库,并实现在公网环境下使用navicat图形化工具

公网远程连接MariaDB数据库【cpolar内网穿透】 文章目录 公网远程连接MariaDB数据库【cpolar内网穿透】1. 配置MariaDB数据库1.1 安装MariaDB数据库1.2 测试局域网内远程连接 2. 内网穿透2.1 创建隧道映射2.2 测试随机地址公网远程访问3. 配置固定TCP端口地址3.1 保留一个固定的…

基于单片机的智能电子鼻的设计

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式 文章目录 概要 一、智能电子鼻系统的设计方案1.1智能电子鼻系统的设计思路1.2智能电子鼻系统的设计流程图1.3智能电子鼻系统的硬件数…