常用加密及其相关的概念、简介(对称、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,简单的说就是单向的加密,即是说无法根据密文推 ...
随机推荐
- P3509 [POI2010] ZAB-Frog 题解
题目链接:ZAB-Frog 基于一个根据距离第 \(k\) 大的事实: 容易知道,对于红色的点而言,与它相近最近的 \(k\) 个点是连续的.而第 \(k\) 远的要么是最左侧要么是最右侧.而我们注意 ...
- 19.2 显式加载/隐式加载--《Windows核心编程》
部分笔记来自于:https://blog.csdn.net/blade1080/article/details/81364161 注:关于DLL存放位置,一般是放到可执行文件的目录下. 下面时加载程序 ...
- google三驾马车之一:Bigtable解读(英文版)
本文重点关注了系统设计相关的内容,paper后半部分的具体应用此处没有过多涉及.从个人笔记修改而来,因此为英文版本. Bigtable: A Distributed Storage System fo ...
- 如何做好一个基础的搜索功能?记一个因客户大数据量而导致的后发先至Bug
壹 ❀ 引 上篇文章算是开了一个新系列,因为工作缘故,我基本每天都在跟各式各样的bug打交道.其实站在一个开发的角度,我想每个人应该都更喜欢创造新代码,创造新bug,而不是每天都泡在茫茫代码海洋中定位 ...
- NC214362 第k小
题目链接 题目 题目描述 有一个长度为n的数组,值为 a[i], 牛牛想找到数组中第 k 小的数.比如 1 2 2 3 4 6 中,第 3 小的数就是2. 牛牛觉得这个游戏太简单了,想加一点难度,现在 ...
- springboot+vue+elementui实现文件上传下载删除DEMO
说明 前面搜索了几个关于springboot+vue+elementui上传下载的文章,感觉写的都不尽如人意.要么是功能不完善,不好用.再者就是源码提供的实在差劲,都不完整.一气之下,自己搞了一个实用 ...
- Oracle使用由字符串索引的二维数组
–参考文章:http://www.oracle.com/technetwork/issue-archive/2014/14-sep/o54plsql-2245345.html –SAMPLE DATA ...
- Java并发编程实例--14.在一个同步类中安排独立属性
当你使用synchronized关键字去保护一个代码块时,你必须传入一个对象的引用. 正常来讲,你讲使用this关键字去引用执行这个方法的对象,但是你可以使用其他对象的引用. 通常的,这些对象将会是专 ...
- js结合canvas画任意多边形
实现六边形 // html <canvas></canvas> // js const canvas = document.querySelector("canvas ...
- 通过命令修改git提交的注释信息
1.修改最新一条 commit 注释信息 通过 git commit --amend 命令修改注释信息,然后:wq 进行保存,再重新提交 2. 修改多条 commit 注释信息 输入命令:git re ...