常用加密及其相关的概念、简介(对称、AES、非对称、RSA、散列、HASH、消息认证码、HMAC、签名、CA、数字证书、base64、填充)
PS:要转载请注明出处,本人版权所有。
PS: 这个只是基于《我自己》的理解,
如果和你的原则及想法相冲突,请谅解,勿喷。
环境说明
无
前言
在之前,一直是通过生活、工作零零碎碎接触过加密及加密算法相关的信息,但是也只是听说过,并不知道这些算法用处和区别。
最近由于工作安排,需要将Fernet算法实现一版C++的加解密定制程序,由于Fernet组合了许多的基础加密算法,因此在这个地方,对一些常用的基础加密算法做一个总结。
加密是什么?
介绍:把“原始数据”通过某种算法+秘钥变换后,得到了“加密数据”的这个过程叫做加密。从这里也可以看到,对于加密来说,其核心要素就是:加密算法+秘钥。
意义:对于“加密数据”来说,未授权的用户,不能够直接知道“原始数据”的内容。
下面介绍一些常见的加密类别和加密相关配套的其他内容。
对称加密
对称加密是指使用 一个相同秘钥 就能对消息进行加密和解密的加密方法。
对称加密的特点就是使用 一个相同秘钥。
我们常见的对称加密有:XOR、AES等。下面我们来简单分析一下AES加密。
AES加密
高级加密标准(Advanced Encryption Standard,AES),是一种区块加密标准。从它的定义来看,其特点是区块加密,一般来说,我们常见的有AES128和AES256。
例如我们可以用如下的openssl提供的方法进行AES的加解密:
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
AES_KEY *key);
//注意这里只是一种cbc加密方法,aes还有很多其他加密方法
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
其实我们从上面的描述来看,就知道AES一般以16字节或者32字节为一组(我们将其定义为区块大小),进行加密。这里就会引申出一个问题,如果我们的数据(最后一组消息)不够一个区块大小,我们应该怎么办?这里提供的常见方案就是做填充。
非对称加密(公钥加密算法)
我们知道,加密一般是用于消息传递,那么如果是对称加密的情况下,要传递的两个事务:加密消息+秘钥。对于对称加密来说,如果我们的秘钥泄露了,就基本上等于明文传递了。因此,有了非对称加密。其实后面很多的加密方法就在平衡 加密消息+秘钥 两个事情。
非对称加密就是有两个秘钥(私钥,公钥),实现1对多的双向通信。其中我们常见的加密方式是:RSA,ECC等。下面,我们尝试简单介绍RSA。
RSA 加密算法
简介(来自于Wikipedia):RSA加密算法是一种非对称加密算法。RSA是由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)在1977年一起提出的。当时他们三人都在麻省理工学院工作。RSA 就是他们三人姓氏开头字母拼在一起组成的。
RSA只从使用的角度来说,只需要了解如下的大致的概念:
- 模数N、公钥指数pubE、私钥指数priE
- 加密:秘文=明文^priE mod N,秘文=明文^pubE mod N
- 解密:明文=秘文^pubE mod N,明文=秘文^priE mod N
从上面来看,私钥= 私钥指数priE + 模数N,公钥= 公钥指数pubE + 模数N。至于公钥,私钥,模数怎么来的,网上已有许多资料,有兴趣可以去看看。
基于openssl的RSA代码节选:
// 生成秘钥,秘钥里面包含了私钥+公钥
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
// 基于公钥和私钥的加解密
int RSA_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int RSA_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int RSA_public_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int RSA_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
散列函数(Hash function)
介绍:使用 散列函数(md5, sha1, sha256) 对原始数据进行处理,生成散列值(数字摘要)。这些散列函数保证一个输入对应一个输出,并且通过散列值无法得到原始数据输入,因此不属于加密。
此外,如果散列函数不够健壮,可能会出现碰撞的可能性。
意义:由于其不同的数据输入会得到不同的散列值,因此主要用来校验数据的完整性。
基于openssl的常见散列函数代码节选:
//注意,根据官网的描述,如下这些接口已经逐步被弃用,这里只是起示例作用。
int SHA1_Init(SHA_CTX *c);
int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
int SHA1_Final(unsigned char *md, SHA_CTX *c);
//注意,根据官网的描述,如下这些接口已经逐步被弃用,这里只是起示例作用。
int SHA256_Init(SHA256_CTX *c);
int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA256_Final(unsigned char *md, SHA256_CTX *c);
其实做过编程的人,对hash这个概念并不陌生。
消息认证码
含义:使用 散列函数+秘钥来生成认证码(MAC)。相较于散列函数来说,对于同一个消息,需要指定的秘钥+散列函数才能够得到最终的认证码。
意义:在散列函数中,原始数据和散列值是绑定的。在一个消息传递系统中,散列函数只解决了数据完整性的问题,并没有解决数据来源是否可靠的问题(可以伪造原始数据+新散列值)。 通过消息验证码,由于有了秘钥的保护, 解决了 散列值+消息 来源不可靠的问题。
基于openssl的消息认证码代码节选:
//这里的evp_md用来描述不同的散列函数
unsigned char *HMAC(const EVP_MD *evp_md, const void *key,
int key_len, const unsigned char *d, size_t n,
unsigned char *md, unsigned int *md_len);
签名算法
下面是签名的一个简单流程:
- 基于公钥加密系统,生成秘钥对(公钥、私钥)。
- 对消息进行数字摘要计算。
- 对数字摘要进行私钥加密,得到数字签名。
- 将信息、数字签名、公钥发给接收者,接收者可以验证:信息的完整性+发送者的身份。
从这里来看,我们可以知道,签名其实和消息认证码具有相同的意义,都能够验证:完整性+发送者的身份。但是由于其原理,导致其应用场景不一致。例如:数字签名由于使用非对称加密,而消息认证码可以认为是使用了对称加密,导致他们的使用场景是不一样的。
CA机构与数字证书
其实从名字上来看,就知道CA机构与数字证书和签名算法相关,为了解决公钥加密系统中,公钥是否可信的问题。下面是它们的一些概念:
- CA(Certificate Authority)是“证书颁发机构”的简称,它是“受信任”的第三方组织,负责验证申请者身份并发放数字证书。
- 数字证书是:特定用户或系统身份信息(如域名、组织名等)+ 该用户公钥 + 由权威机构(CA)签署的数字签名(对用户的信息+公钥) 组成的数据结构。
简单来说,由于我们信任了CA的证书(CA的公钥),我们可以用CA的公钥解密出 数字证书用户的公钥,然后我们用 数字证书用户的公钥 和 数字证书用户加密通信。总的来说,数字证书其实是一个信任链的问题。
Base64 编码
介绍:一种将 二进制数据 编码为 可见字符 的编码方法。简单来说就是用 4个字节的可见字符 代替是 3个字节数据 的编码过程。
意义:可以将二进制数据表达为文本信息,方便后续对二进制数据进行处理。
数据区块填充,PKCS(Public-Key Cryptography Standards)
特别说明,PKCS是一系列公钥密码标准,里面具备很多的内容,其大概有15个标准,分别是pkcs1,pkcs2 ... ... pkcs14,pkcs15
从上面我们知道,现在常用的填充方法是:公钥加密标准(PKCS,Public-Key Cryptography Standards)里面的节选内容。其有很多填充类别,例如:PKCS1-padding节选, PKCS5-padding节选, PKCS7-padding节选,我们这里只讨论pkcs5和pkcs7。(注意,这些标准除了数据填充,还有其他定义内容。)
下面先介绍PKCS5-padding,先定义数据区块大小为SIZE,pkcs5和pkcs7的填充说明,下面以SIZE=8字节举例:
- 要填充7个字节,那么填入的值就是0×07;
- 如果只填充1个字节,那么填入的值就是0×01;
- 数据恰好是8的倍数时还要补8个字节的0×08。
从上面的PKCS5-padding,我们可以知道,这里需要数据区块固定为8字节。如果我们想给其他大小的数据区块做数据对齐,那么PKCS5-padding就不满足要求,因此就有PKCS7-padding的填充方法:
- PKCS7-padding的数据区块大小可以是:1-255字节。
- 其他的,PKCS7-padding填充原理和PKCS5一样。
从上面可知,PKCS7-padding节选包含了PKCS5-padding节选,且适用性范围更加的广泛。
到了这里,我们就能够对AES128或者AES256做基于PKCS7-padding的16字节对齐或者32字节对齐的操作了。
这里的代码实现很简单,这里提供一种方法,大概就是:首先对消息进行强制扩大255字节,然后根据数据区块大小做填充即可,基本可以实现pkcs7填充的原理。
后记
其实,我们从上面的内容来看,能发现一些规律:
由于信任链的存在,因此有了CA机构和数字证书,而数字证书与签名算法相关,而签名算法又与 非对称加密和散列函数强相关。
然后为了实现我们现在常见的加密系统,我们使用了:对称加密、非对称加密、散列函数、消息认证码和base64编码等手段。
参考文献
- 无
打赏、订阅、收藏、丢香蕉、硬币,请关注公众号(攻城狮的搬砖之路)

PS: 请尊重原创,不喜勿喷。
PS: 要转载请注明出处,本人版权所有。
PS: 有问题请留言,看到后我会第一时间回复。
常用加密及其相关的概念、简介(对称、AES、非对称、RSA、散列、HASH、消息认证码、HMAC、签名、CA、数字证书、base64、填充)的更多相关文章
- hmac库 密钥相关的哈希运算消息认证码
# -*- coding: cp936 -*- #xiaodeng #python 2.7.10 #HMAC是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一 ...
- 理解 HTTPS 工作原理(公钥、私钥、签名、数字证书、加密、认证)(转)
本文摘录参考: 细说 CA 和证书(主要讲解 CA 的使用) 数字签名是什么?(简单理解原理) 深入浅出 HTTPS 工作原理(深入理解原理) HTTP 协议由于是明文传送,所以存在三大风险: 1.被 ...
- Java使用Cipher类实现加密,包括DES,DES3,AES和RSA加密
一.先看一个简单加密,解密实现 1.1 加密 /** * content: 加密内容 * slatKey: 加密的盐,16位字符串 * vectorKey: 加密的向量,16位字符串 */ publi ...
- Redis散列(Hash)的相关命令
散列 就像一个减配的Redis 内部及其类似Java的Map 内容就是key:value结构 hash类型在面向对象编程的运用中及其适合,因为它可以直接保存编程语言中的实体类关系 增 hset hse ...
- Algorithm:Java加密解密之MAC(消息认证码)
MD5 消息摘要(数字摘要) 它是把一个文本/文件 通过摘要函数(hash函数)计算出一个结果.然后把文本/文件和摘要结果一同发给接受者接受者接收到文件之后,也进行摘要,把两个摘要结果进行对比.如果一 ...
- PHP的几个常用加密函数
在php的开发过程中,常常需要对部分数据(如用户密码)进行加密 一.加密类型: 1.单向散列加密 就是把任意长度的信息进行散列计算,得到固定长度的输出,这个散列计算过程是单向的,即不能对固定长度的输出 ...
- 2019-2-20C#开发中常用加密解密方法解析
C#开发中常用加密解密方法解析 一.MD5加密算法 我想这是大家都常听过的算法,可能也用的比较多.那么什么是MD5算法呢?MD5全称是 message-digest algorithm 5[|ˈmes ...
- https原理及其中所包含的对称加密、非对称加密、数字证书、数字签名
声明:本文章已授权公众号Hollis转载,如需转载请标明转载自https://www.cnblogs.com/wutianqi/p/10654245.html(安静的boy) 一.为什么要使用http ...
- HTTPS加密那点事-对称、非对称加密、数字证书
转自:[漫画]https 加密那点事 首先,HTTP协议的缺点:没有对数据进行加密,都是明文传输的.如果要改进这种明文传输的协议,该如何做呢? 对称加密: 在每次发送真实数据之前,服务器先生成一把密钥 ...
- C#开发中常用加密解密方法解析
一.MD5加密算法 我想这是大家都常听过的算法,可能也用的比较多.那么什么是MD5算法呢?MD5全称是message-digest algorithm 5,简单的说就是单向的加密,即是说无法根据密文推 ...
随机推荐
- 23.2 SEH之异常处理--《Windows核心编程》结构化异常处理
(structured exception handing)SEH 包含终止处理和异常处理.本章讨论异常处理. 当一个硬件或者软件异常被抛出的时候,操作系统会给我们程序一个查看异常类型的机会,并允 ...
- RocketMQ—RocketMQ消费重试和死信消息
RocketMQ-RocketMQ消费重试和死信消息 消费重试 生产者重试 设置重试的代码如下 // 失败的情况重发3次 producer.setRetryTimesWhenSendFailed(3) ...
- nginx做白名单和限流
在我们生产环境中使用到了地图服务,每个月有免费请求次数,近一个月请求次数突然暴涨,导致直接开启付费模式,一个月上百刀的花销着实难扛,根据实际我们的业务使用情况,远达不到付费标准,故考虑做白名单和限 ...
- NC22600 Rinne Loves Dynamic Graph
题目链接 题目 题目描述 Rinne 学到了一个新的奇妙的东西叫做动态图,这里的动态图的定义是边权可以随着操作而变动的图. 当我们在这个图上经过一条边的时候,这个图上所有边的边权都会发生变动. 定义变 ...
- 在PWM控制下的直流有刷电机性能优化
结论 为了避免各位浪费时间, 先说结论: 选择合适的电机驱动模式和PWM频率, 能大幅提升直流电机的性能和可控性, 在常见的48:1减速电机上, 使用慢衰减模式和低于100Hz的PWM频率, 能达到最 ...
- 【Unity3D】顶点和片元着色器
1 前言 上文介绍了渲染管线.固定管线着色器和表面着色器,如下: 渲染管线 固定管线着色器一 固定管线着色器二 表面着色器 固定管线着色器通过命令方式实现光照和贴图等效果,表面着色器通过给 S ...
- python中两个不同shape的数组间运算规则
1 前言 声明:本博客讨论的数组间运算是指四则运算,如:a+b.a-b.a*b.a/b,不包括 a.dot(b) 等运算,由于 numpy 和 tensorflow 中都遵循相同的规则,本博客以 nu ...
- Spring Boot图书管理系统项目实战-10.借还统计
导航: pre: 9.归还图书 next:11.检索图书 只挑重点的讲,具体的请看项目源码. 1.项目源码 需要源码的朋友,请捐赠任意金额后留下邮箱发送:) 2.页面设计 2.1 bookStat. ...
- oracle 使用comment语句添加表注释
使用oracle comment语句可以给表.字段.视图等对象添加备注信息. 大致语法为: comment on TABLE table_name IS '备注内容'; 权限要求: 默认情况下用户只能 ...
- 【Azure Redis 缓存 Azure Cache For Redis】Redis支持的版本及不同版本迁移风险
问题描述 1. Azure Redis缓存支持的版本包括4.0以及6.0(预览) 这种情形下,可以使用PaaS服务提供的 Azure Redis 缓存(4.0版本).Azure Redis对6.0的支 ...