数据加密
加密三要素:
- 明文/密文
- 秘钥
- 定长的字符串
- 对称加密 ->自己生成
- 非对称加密 -> 有对应的算法可以直接生成
- 算法
常用加密方式
-
对称加密
- 秘钥比较短
- 秘钥只有一个
- 加密的效率高
- 加密强度相对较低( 相对于非对称加密 )
- 秘钥分发困难 -> 因为秘钥要保密不能泄露
-
非对称加密
- 秘钥比较长
- 秘钥有两个, 所有的非对称加密算法都有生成密钥对的函数
- 这两个秘钥对保存到不同的文件中, 一个文件是公钥(比较小), 一个是私钥(比较大)
- 公钥 -> 可以公开的
- 私钥 -> 不能公开
- 加解密使用的秘钥不同
- 如果使用公钥加密,
必须 私钥解密 - 如果使用私钥加密,
必须 公钥解密 - 效率低
- 加密强度相对较高( 相对于对称加密 )
- 秘钥可以直接分发 -> 分发的公钥
对称加密
- DES/3DES
- DES -> 已经被破解了, 不安全
- 秘钥长度 8byte
- 对数据分段加密, 每组8字节
- 3DES -> 3重des
- 安全的, 效率比较低
- 对数据分段加密, 每组8字节
- 得到的密文和明文长度是相同的 == 8字节
- 秘钥长度24字节, 在算法内部会被平均分成3份, == 每份8字节
- 加密处理逻辑:
- 加密: -> 秘钥1 * 加密算法
- 解密 -> 秘钥2 * 解密算法
- 加密 -> 秘钥3 * 加密算法
- 三组秘钥都不同, 加密的等级是最高的
- AES
- 最安全, 效率最高的公开的对称加密算法
- 秘钥长度: 16字节, 24字节, 32字节
分组加密, 每组长度 16 字节 - 每组的密文和明文的长度相同 == 16byte
- Blowfish
- RC2/RC4/RC5
- IDEA
- SKIPJACK
非对称加密
加密算法
- RSA(数字签名和密钥交换)
- 项目中用的是rsa
- ECC(椭圆曲线加密算法 - 数字签名)
- Diffie-Hellman(DH, 密钥交换)
- El Gamal(数字签名)
- DSA(数字签名)
秘钥交换过程
假设通信的双方为: 客户端C, 服务器端S 为什么要交换?
- 非对称加密秘钥分发方便, 但是效率低 -> 改进: 需要使用对称加密
- 使用对称加密 -> 秘钥分发困难 -> 改进: 使用非对称加密进行秘钥分发
分发是对称加密的秘钥, 本质就是一个字符串
秘钥交换的过程:
- 在服务器端生成一个非对称加密的密钥对: 公钥, 私钥
- 服务器将公钥发送给客户端, 客户端有了公钥
- 在客户端生成一个随机字符串 -> 这就是对称加密需要使用的秘钥
- 在客户端使用公钥对生成的对称加密的秘钥进行加密 -> 密文
- 将加密的密文发送给服务器
- 服务器端使用私钥解密 -> 对称加密的秘钥
- 双方使用同一秘钥进行对称加密通信
Hash算法 (单向散列函数)
特点:
- 不管原始数据有多长, 通过哈希算法进行计算, 得到的结果的长度是固定的
- 只要是原始数据不一样, 得到的结果就不一样
- 有很强的抗碰撞性
- 碰撞: 原始数据不同, 但是通过同样的哈希算法进行计算能得到相同的结果
- 推导的结论:
- 数据不同得到的结果就不同
- 应用场景:
- 数据校验
- 登录验证
- 秒传
- 不可逆
哈希运算的结果:
- MD4/MD5
- SHA-1
- SHA-2
- sha224
- 散列值长度: 224bit / 8 = 28byte
- sha256
- 散列值长度: 256bit / 8 = 32byte
- sha384
- 散列值长度: 384bit / 8 = 48byte
- sha512
- 散列值长度: 512bit / 8 = 64byte
- SHA3-224/SHA3-256/SHA3-384/SHA3-512
消息认证码 -> HMAC
作用:
- 在通信的时候, 校验通信的数据有没有被篡改(完整性)
- 没有加密的功能
使用:
- 消息认证码的本质是一个散列值
(原始数据 + 秘钥) * 哈希函数 = 消息认证码
校验的过程:
- 数据发送方A, 数据接收方B
- 在A或B端生成一个秘钥: X, 进行分发 -> A和B端都有了 秘钥: X
- 在A端进行散列值运算: (原始数据 + x) * 哈希函数 = 得到散列值
- 在A端: 将原始数据和散列值同时发送给B
- 在B端: -> AB端使用的哈希算法是相同的
- 接收数据
- 校验: (接收的原始数据 + x) * 哈希函数 = 散列值New
- 比较散列值: 散列值New 和 接收的散列值 是不是相同
缺点:
数字签名
作用:
- 校验数据有没有被篡改(完整性)
- 鉴别数据的所有者
- 不能对数据加密
数字签名的过程: -> 私钥加密数据
- 生成一个非对称加密的密钥对, 分发公钥
- 使用哈希函数对原始数据进行哈希运算 -> 散列值
- 使用私钥对散列值加密 -> 密文
- 将原始数据和密文一起发送给接收者
校验签名的过程:
- 接收签名的一方分发的公钥
- 接收签名者发送的数据:
接收的原始数据 + 签名 - 对数据进行判断:
- 对
接收的原始数据 进行哈希运算 -> 散列值new
- 使用公钥对签名(密文) 解密 -> 得到了散列值old
- 比较两个散列值
- 相同: 数据的所有者确实是A, 并且数据没有被篡改
- 不同: 数据的所有者不是A或者数据被篡改了
OpenSSL OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。
SSL是Secure Sockets Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。Netscape公司在推出第一个Web浏览器的同时,提出了SSL协议标准。其目标是保证两个应用间通信的保密性和可靠性,可在服务器端和用户端同时实现支持。已经成为Internet上保密通讯的工业标准。
windows下Visual Studio配置
项目属性 -> 配置属性 -> VC++目录 ->
- 包含目录:F:\OpenSSL-Win64\include
- 库目录:F:\OpenSSL-Win64\lib
打开项目属性窗口, 添加openssl相关的库到项目中 项目属性 -> 链接器 -> 输入 -> 附件依赖项
测试代码:
void getMD5(const char* str, char* result)
{
MD5_CTX ctx;
// 初始化
MD5_Init(&ctx);
// 添加数据
MD5_Update(&ctx, str, strlen(str));
// 计算结果
unsigned char md[16] = { 0 };
MD5_Final(md, &ctx);
for (int i = 0; i < 16; ++i)
{
sprintf(&result[i * 2], "%02x", md[i]);
}
}
int main()
{
char result[33] = { 0 };
getMD5("hello, md5", result);
printf("md5 value: %s\n", result);
system("pause");
return 0;
}
输出结果
md5 value: 33b3bc8e05b4fcc16bd531dd9adac166
Linux下配置
下载之后解压,然后在当前目录下运行这四个指令
If you want to just get on with it, do:
79
80 on Unix (again, this includes Mac OS/X):
81
82 $ ./config
83 $ make
84 $ make test
85 $ make install
记得要添加一下:(权限不足的要sudo)
- 在/etc/ld.so.conf.d/libc.conf 文件中添加一行/usr/lib
- 运行ldconfig命令
再编译以上的md5_test程序:
kimi@kimi-pc:~/share$ vim md5_test.c
kimi@kimi-pc:~/share$ gcc md5_test.c -o md5 -lcrypto
kimi@kimi-pc:~/share$ ./md5
md5 value: 33b3bc8e05b4fcc16bd531dd9adac166
sh: 1: pause: not found
成功输出表示配置成功!
|