简介
- OpenSSL是一个用于TLS/SSL协议的工具包。它也是一个通用密码库。·15-5-2020 OpensSL 3.0 Alpha2 Release(支持国密sm2 sm3 sm4)
- 包含对称加密,非对称加密,单项散列,伪随机,签名,密码交换,证书等一系列算法库
- mysql,python,libevent
环境
安装好vs2019社区版本
下载 http://www.openssl.vip/download
安装好ubuntu 18.04系统
目标
·在windows上使用vs2019编译OpenSSL
·使用vs2019编写第一个openssl项目. ubuntu下编译OpenSSL3.0
·编写第一个linux下OpenSSL项目
Windows上编译OpenSSL3.0
.openssl.vip安装过程和工具下载
·安装vs2019
perl
nasm
·生成项目文件
perl Configure VC-WIN32
perl Configure VC-WIN64A --prefix=%cd %lout
·以管理员运行控制台x64 Native Tools Command Prompt for VS 2019
· nmake
. nmake install
Linux编译openssl3.0
wget --no-check-certificate https://www.openssl.org/sourcelopenssl-3.0.0-alpha2.tar.gz
tar -xvf openssl-3.0.0-alpha2.tar.gz
cd openssl-3.0.0-alpha2
./config
·#三十二线程编译·make -j32
·#安装so库,头文件和说明文档
make install
openssl命令行/usr/local/bin
配置安装在/usr/local/ssl
头文件/usr/local/include/openssl
so库文件/usr/local/lib
(特别注意的是在linux环境下,项目引用的时候是先去环境变量里面去找的,还有的项目用到多个openssl版本,一定要指定版本)
Base64概述和应用场景
·概述
·二进制转字符串·应用场景
·邮件编码(base64)
· xml或者json存储二进制内容。网页传递数据URL
·数据库中以文本形式存放二进制数据
·可打印的比特币钱包地址base58Check(hash校验,后面再讲)
·比特币地址 bech32 (base32)
·基本学习目标:
·从0编写base16编解码算法
·理解base64原理
·使用OpensSL BIO接口完成base64编解码
·高级目标
·理解比特币钱包地址base58原理并读懂源码
抽取比特币base58代码并测试
Openssl 接口
BIO包含了多种接口,用于控制在BIO_METHOD中的不同实现函数,包括6种filter型和8种source/sink型。
应用场景
BlO_new创建一个BIO对象
数据源:source/sink类型的BIO是数据源BIO_new(BIO_s_mem())
过滤: filter BIO就是把数据从一个BIO转换到另外一个BIO或应用接口
BIO_new(BIO_f_base64())
BIO链: 一个BIO链通常包括一个source BIO和一个或多个filter BIO
·BIO_push(b64__bio, mem_bio);
写编码,读解码 BIO_write BlO_read_ex
时间为种子的伪随机数
#include <iostream>
#include <openssl/rand.h>
#include <time.h>
using namespace std;
int test(int argc, char* argv[])
{
cout << "First opensll code" << endl;
time_t t = time(0);
unsigned char buf[16] = { 0 };
int re = RAND_bytes(buf, sizeof(buf));
for (int i = 0; i <= sizeof(buf); i++)
{
cout << "["<<(int)buf[i]<<"]"<<endl;
}
getchar();
return 0;
}
base16
#include <iostream>
#include <string.h>
using namespace std;
static const char BASE_16_ENCODE[] = "0123456789ABCDEF";
// '0'~~'9' => 48~~57 'A'~~'F' => 65~~70
static const char BASE_16_DECODE[] = {
-1, //0
-1,-1,-1,-1,-1, -1,-1,-1,-1,-1, //1-10
-1,-1,-1,-1,-1, -1,-1,-1,-1,-1, //11-20
-1,-1,-1,-1,-1, -1,-1,-1,-1,-1, //21-30
-1,-1,-1,-1,-1, -1,-1,-1,-1,-1, //31-40
-1,-1,-1,-1,-1, -1,-1, 0, 1, 2, //41-50
3, 4, 5, 6, 7, 8, 9,-1,-1,-1, //51-60
-1,-1,-1,-1,10, 11,12,13,14,15 //61-70
};
int Base16Encode(const unsigned char* in, int size, char* out1)
{
for (int i = 0; i < size; i++)
{
char h = in[i] >> 4; //1000 0001 >> 4 == 0000 1000
char l = in[i] & 0x0F; //1000 0001&0000 FFFF == 0000 0001
out1[i * 2] = BASE_16_ENCODE[h];
out1[i * 2 + 1] = BASE_16_ENCODE[l];
}
return size * 2;
}
int Base16Decode(const string& in,unsigned char* out2)
{
//将两个字节拼成一个字节
for (size_t i = 0; i < in.size(); i += 2)
{
unsigned char ch = in[i]; //高位转换的字符 ‘B'=>66->10
unsigned char cl = in[i + 1]; //低位转换的字符 ‘B'=>50->2
unsigned char h = BASE_16_DECODE[ch]; //转换为原来的值
unsigned char l = BASE_16_DECODE[cl];
//两个4位拼接成一个字节(8位)
out2[i / 2] = (int)(h << 4 | l);
}
return in.size() / 2;
}
int main1(int argc, int* argv[])
{
cout << "Test Base16" << endl;
const unsigned char data[] = "测试Base16";
cout << data << endl;
int len = sizeof(data);
char out1[1024] = { 0 };
unsigned char out2[1024] = { 0 };
int re = Base16Encode(data, len, out1);
cout << "编码后长度:"<< re <<endl<< out1 << endl;
int Result = Base16Decode(out1, out2);
cout << "解码:" << out2 << endl;
getchar();
return 0;
}
base64
#include <iostream>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
using namespace std;
int Base64Encode(const unsigned char* in, int len, char* out)
{
if (!in || len <= 0 || !out) return 0;
//内存源
auto mem_bio = BIO_new(BIO_s_mem());
if (!mem_bio) return 0;
//Base64 filter
auto b64_bio = BIO_new(BIO_f_base64());
if (!b64_bio)
{
BIO_free(mem_bio);
return 0;
}
//形成BIO链表
//b64-------mem
BIO_push(b64_bio, mem_bio);
//设置属性超过64字节不添加换行符号
BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL);
//写入到base64 filter 进行编码,结果会传递到链表的下一个节点
//到mem中读取结果(链表头部代表了整个链表)
//write是编码 三字节转化位4个字节,不足就补0和=
//编码数据每64字节会 加\n 换行
int re