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

文章目录

  • 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.mzph.cn/news/119930.shtml

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

相关文章

聊聊“JVM 调优JVM 性能优化”是怎么个事?

所谓“调优”就是一个诊断和处理手段,最终的目标是让系统的处理能力,也就是“性能”达到最优化。 计算机系统中,性能相关的资源主要分为这几类: CPU:CPU 是系统最关键的计算资源,在单位时间内有限&#xf…

IDEA 断点高阶

一、按钮介绍 1.1 补充 返回断点处: 设置debug配置: 二、增加/切换debugger视图 三、window快捷键 所在行处: CtrlF8断点属性编辑: CtrlShiftF8 四、一些常用的高级功能 4.1 查看对象内存-Attach memory agent 1.勾选Atta…

react的table合并行时,出现border-bottom重复问题

背景: 需求是呈现一个表格,根据操作人跟操作时间是否相同来进行合并行数据 数据结构: 经过跟后端的同事商量,需要在每一行数据中返回rowSpanNum的值,前端在column中根据值来判断是否满足合并行(没有合并行…

基于FPGA的图像PSNR质量评估计算实现,包含testbench和MATLAB辅助验证程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 设置较大的干扰,PSNR15。 设置较小的干扰,PSNR25。 2.算法运行软件版本 matlab2022a vivado2019.2 3.部分核心程序 ti…

SDL窗口创建以及简单显示(1)

项目创建步骤 1. 使用Qt Creator创建一个C项目 2. 将SDL库文件放到源文件目录下 在项目pro文件中添加库文件 win32{INCLUDEPATH $$PWD/SDL2-2.0.10/includeLIBS $$PWD/SDL2-2.0.10/lib/x86/SDL2.lib } 使用SDL创建一个窗口 #include <stdio.h>#include <SDL.h>…

只需这个下毒小工具,让Stable Diffusion彻底崩溃!狗变猫,车变牛,AI侵权打响反击战

作者 | 谢年年 文生图模型如DALL-E、Midjourney和Stable Diffusion等越来越火热&#xff0c;只需要一句话几秒钟就可以生成质量不逊艺术家辛辛苦苦创作数月的图片。 艺术家们表示很气但又无能为力。 大模型研究测试传送门 GPT-4传送门&#xff08;免墙&#xff0c;可直接测试…

HCIA数据通信——交换机(Vlan间的通信与安全)

前言 之前的提到了交换机的概念和实验。不过交换机的一些功能还没有说完&#xff0c;我们的实验也仅仅是阻止相同地址段的IP地址互通&#xff0c;也没有用到子接口和路由器。显然&#xff0c;那样的配置过于简单。 端口安全 Port Security&#xff08;端口安全&#xff09;的功…

关于高并发你必须知道的几个概念

&#x1f388;个人公众号:&#x1f388; :✨✨✨ 可为编程✨ &#x1f35f;&#x1f35f; &#x1f511;个人信条:&#x1f511; 为与不为皆为可为&#x1f335; &#x1f349;本篇简介:&#x1f349; 本篇记录高并发必须知道的几个概念&#xff0c;如有出入还望指正。 关注公众…

Java-数据类型

Java-数据类型 一、字面常量二、数据类型&#xff08;1&#xff09;基本数据类型 三、变量1、变量概念2、语法格式&#xff08;1&#xff09;语法&#xff1a;&#xff08;2&#xff09;示例&#xff1a; 3、整型变量&#xff08;1&#xff09;整型变量&#xff08;int&#xf…

CentOS 搭建本地 yum 源方式 安装 httpd 服务

CentOS 搭建本地 yum 源方式 安装 httpd 服务 修改 yum 源 挂载光驱 mkdir -p /mnt/cdrom mount /dev/cdrom /mnt/cdromvi /etc/fstab追加以下内容&#xff1a; /dev/cdrom /mnt/cdrom iso9660 defaults 0 0手动修改CentOS-Base.repo 备份 yum 源配置文件 mv /etc/yum.re…

将Sketch文件转化为PSD文件的简单在线工具!

设计工作不仅需要UI设计工具&#xff0c;还需要Photoshop。常见的UI设计工具Sketch与Photoshop软件不兼容。如果你想在实际工作中完成Sketch转psd&#xff0c;你需要使用其他软件进行转换。但是在转换过程中容易丢失文件&#xff0c;导致同样的工作需要重复多次才能完成&#x…

OpenCV官方教程中文版 —— 2D 直方图

OpenCV官方教程中文版 —— 2D 直方图 前言一、介绍二、OpenCV 中的 2D 直方图三、Numpy 中 2D 直方图四、绘制 2D 直方图 前言 本节我们会学习如何绘制 2D 直方图&#xff0c;我们会在下一节中使用到它。 一、介绍 在前面的部分我们介绍了如何绘制一维直方图&#xff0c;之…

APP分发-CDN加速原理

摘要 CDN的全称是(Content Delivery Network)&#xff0c;即内容分发网络。其目的是通过在现有的Internet中增加一层新的CACHE(缓存)层&#xff0c;将网站的内容发布到最接近用户的网络”边缘“的节点&#xff0c;使用户可以就近取得所需的内容&#xff0c;提高用户访问网站的…

辅助驾驶功能开发-功能规范篇(23)-2-Mobileye NOP功能规范

5.2 状态机要求 5.2.1 NOP/HWP 状态机 NOP/HWP状态机如下所示: 下表总结了这些状态: 状态描述Passive不满足功能条件,功能无法控制车辆执行器。Standby满足功能条件。该功能不是由驾驶员激活的。功能不控制车辆执行器。Active - Main功能由驾驶员激活。功能是控制…

Qt 序列化函数和反序列化函数

文章目录 界面学生类序列化函数反序列化函数刷新所选择的下拉表值添加 界面 学生类 // 创建学生信息类 class studentInfo { public:QString id; // 学号QString name; // 学生姓名QString age; // 学生年龄// 重写QDataStream& operator<<操作符&…

传智书城源码+课程设计文档基于JSP+Servlet实现

下载地址: https://juzhendongli.store/commodity/details/19 包括源码参考论文

华为---DHCP中继代理简介及示例配置

DHCP中继代理简介 IP动态获取过程中&#xff0c;客户端&#xff08;DHCP Client&#xff09;总是以广播&#xff08;广播帧及广播IP报文&#xff09;方式来发送DHCPDISCOVER和DHCPREQUEST消息的。如果服务器&#xff08;DHCP Server&#xff09;和 客户端不在同一个二层网络(二…

哪一个更好?Spring boot还是Node.js

前言 本篇文章有些与众不同&#xff0c;由于我自己手头有些关于这个主题的个人经验&#xff0c;受其启发写出此文。虽然SpringBoot和Node.js服务于很不一样的场景&#xff0c;但是这两个框架共性惊人。其实每种语言都有不计其数的框架&#xff0c;但仅仅一部分是真正卓越的。如…

计算机网络相关硬件介绍

计算机相关硬件 计算机由运算器、控制器、存储器、输入设备和输出设备等五个逻辑计算机硬件部件组成。 一、中央处理器&#xff08;CPU&#xff09;&#xff08;运算器、控制器&#xff09; &#xff08;1&#xff09;运算器 运算器是对数据进行加工处理的部件&#xff…

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…