为什么我们要加密?
加密
是为了信息传递更加安全!
这样才能更好的让信息传递更具有保密性
,不会被他人随意篡改
、也能够让信息真实有效的到达指定对象的手里!
我们加密的目的,多数是围绕这上面这些情况来的!
举个栗子
在信息通信过程当中,比如你发送一条重要信息给对方, 在这个过程中其实有很多人可以利用一些技术手段接触到这一段信息! 如果是很重要的信息但个别人利用,说不一定就会产生严重的经济损失!
例如: 信息中包含了一些敏感信息,如身份证、银行卡、密码、
而这些敏感信息是最容易被人偷窥的!
如图
为了避免出现以上的情况,我们就要将信息进行加密处理
, 这样子即便是被人拿到了关键信息,他也是在短时间内无法查看的,也就是让任何第三方都无法直接读取和读懂的信息!
只有发送方
和接收方
能看懂整个数据传输的信息。
加密系统的简单架构
加密
的产生过程,简单点说其实就是: 明文+密钥+算法=密文
如图
从上面的图来看,其实明文
和算法
都还是比较好理解,但其中有一个叫密钥
的东西,它就好比是像彼此约定好了的暗号
一样, 也是最简单的加密方式!
举个栗子
从生活中我们用一个锁家里的门来举例的话,就是家中有价值的物品,就是你的明文
、那么密钥
就是你的钥匙
,那么算法
就是你是通过什么样的情况来锁门的! 当门锁好之后,那么一个家
就形成了一个加密
状态了!
所以这个密钥
通常都是需要保密的,就是这个意思,你总不可能把你的钥匙
随便丢吧!
对称加密
那么在计算机中,我们也一些有比较安全和常见的加密方式, 例如:对称加密
对称加密
其实分为两种形式: 对称加密
和非对称加密
简单的说对称加密
也就是加密
和解密
都会使用同样密钥
非对称加密
则恰恰相反,这种加密
和解密
使用的是不同密钥
AES对称加密算法
AES
全称:advanced encryption standard
它是密码学中的高级加密标准
,也是美国联邦政府采用的区块加密的标准,也是当下比较流行的对称密码算法
!
我们前面提到的对称加密
中就包含了AES
也就是加密
和解密
都会使用同样密钥
的加密算法
简单的说发送方
将明文
和密钥
一起经过特殊加密算法
处理后,使其变成复杂的加密密文
再发送出去!
接收方
如果想解读明文
, 那么需要使用加密
用过的密钥
及相同算法
然后按照与加密
时相反的顺序逆推算法对密文
进行解密,才能使其恢复成可读的明文
信息!
前面说了,在对称AES加密算法
中,使用的密钥
只有一个, 发送方
和接收方
都使用这个密钥
对数据进行加密
和解密
,那么这就要求解密
的一方事先必须知道加密密钥
对吧!
如图
这就像是它要求发送方
和接收方
在通信之前,约定一个密钥(暗号)
对称算法的安全性依赖于密钥
,如果泄漏密钥
就意味着任何人都可以对他们发送
或接收
的数据进行解密
所以密钥
的保密性对AES
通信的安全性至关重要!
对称加密算法
的优点在于加密和解密
的快速
和使用长密钥时的难破解性,而这种加密算法支持长度为 128比特
的密钥长度, 同时也支持192、256比特
一共三种选择!
我们知道加密的核心在于密钥
而算法本身
其实最终都会被破解的,所以现在流行的密码算法
都是公开的,所以从密码学
的角度而言也没有人去保密算法来提高安全性,所以说对于现在某些密码攻击
手段对于一些高级加密标准算法
本身并没有效果,真正核心的还是密钥
, 这里密钥
的长度直接就会影响到蛮力攻击
要取得成功需要耗费相当长的时间,而这种对称加密算法
的安全性
取决于密钥
的保存情况来决定!
所以普通情况下,没有特殊需求,基本上首先的是AES加密
应用场景
这里我简单说一个案例
假设我们现在有一个包含用户个人信息的JSON对象
,需要进行加密处理
如下
{
"name": "张三",
"age": 30,
"email": "zhangsan@example.com",
"phone": "13812345678"
}
那么此时我们可以使用一些加密算法,比如:AES、RSA
对这个JSON对象
中的一些数据进行加密处理。
然后加密之后的数据会变成一串密文,用户是无法直接阅读和理解。
例如:使用AES算法
加密上述JSON对象
,结果可能类似于以下形式:
{
"name": "张三",
"age": 30,
"email": "zhangsan@example.com",
"phone": "tv/yxsWlDIPHOnD50WVnFw=="
}
现在可以看到,加密后的JSON对象
中的phone
电话字段已经被替换为一串看似随机的字符串,我们是无法直接读取原始的手机号
的, 这样也对整个JSON对象
也变得难以理解和解析。
这里加密后的JSON数据
需要解密
后才能还原为原始数据
,而解密过程
与加密相反
,
需要使用相应的解密算法
和密钥
来还原数据。
PHP实现AES对称加密
我们来实现一个简单的加密案例,有兴趣的朋友可以来看看,java、php、python
等等用什么语言都可以!
我用php
中的OpenSSl扩展库
来实现AES对称加密与解密
不用我们去了解底层,只需要轻松几步就可以实现一个简单加密和解密
数据的过程!
代码如下
<?php
function encryptAES($data, $key, $iv) {
$encrypted = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$encrypted = base64_encode($encrypted);
return $encrypted;
}
function decryptAES($encryptedData, $key, $iv) {
$encryptedData = base64_decode($encryptedData);
$decrypted = openssl_decrypt($encryptedData, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
return $decrypted;
}
// 加密数据
$data = 'Hello-World!';
$key = '0123456789abcdef';
$iv = '1234567890abcdef';
$encryptedData = encryptAES($data, $key, $iv);
echo '加密后的数据:' . $encryptedData;
echo '<hr>';
// 解密数据
$decryptedData = decryptAES($encryptedData, $key, $iv);
echo '解密后的数据:' . $decryptedData;
?>
效果如下
代码分析
这里简单的使用到了php
中OpenSSl扩展库
的openssl_encrypt
和openssl_decrypt
函数来实现的AES
openssl_encrypt函数解释
如下表
参数列表 | 含义 |
---|---|
参数1:data |
待加密的明文信息数据, 也就是需要加密的数据,你可以把它想象成你想要锁起来的秘密信息 |
参数2:method |
加密方式, 也就是你想要用来加密数据 的加密算法 , 常见的加密算法包括 AES, 具体可以查看官方文档 例如: 你使用 AES-256-CBC 算法,那么 CBC 表示加密模式 ,256 表示密钥的长度 |
参数3:key |
约定加密和解密的一把钥匙, 而这把密钥 的长度必须与所选择的加密算法相匹配.........例如,如果使用 AES-256-xxx ,那么你的密钥应该是 256 位长! 所以我们最好要给定相应字节长度的字符串密钥 ,虽然有时候我们没有定义指定长度的字符的密钥,但仍然能够成功加密数据,是因为PHP 的OpenSSL扩展 自动处理了密钥的填充和生成! 但是为了确保最佳的安全性,最好显式地指定一个符合长度要求的密钥! 这样可以避免任何潜在的填充问题,并确保密钥的长度与所选加密算法的要求相匹配, 比如说: 在 AES-256 算法中,密钥的长度为 32 字节(256 位)的字符串就可以了! 这里我采用的是AES ,而AES 密钥的长度通常可以是128位、192位、256位 |
参数4:options |
它可以控制如何处理返回的数据, 它有两种常量设置方式: OPENSSL_RAW_DATA 和 OPENSSL_ZERO_PADDING 例如,你可以设置 OPENSSL_RAW_DATA 常量选项,这样函数会返回原始的二进制数据 ,一把也都设置这个! |
参数5:iv |
它是一个初始化向量 , 用于增加加密 的安全性 和随机性 ! 这里所谓的初始化向量 其实就是一个随机字符串 ,但是这个随机字符串是有一定讲究的,它的字符长度 通常需要与加密模式 的要求相匹配, 也就是说不同的加密模式 可能会有不同的iv 要求, 例如: 当我们使用AES-256-CBC 加密模式时,iv 参数应该至少为16字节长度 的随机字符串, 如果使用AES-128-CBC 加密模式时, iv 参数必须为16字节长度 的随机字符串,多一个或少一个都会报错! 所以iv 这个参数,最好是要和加密模式 中的长度一致就行了! 为了更加安全,这个iv 最好不能写死,用一种算法方式生成指定长度的iv 这样子在每次加密操作时都会改变加密结果! |
.................................... |
返回值:成功时返回加密后的字符串
openssl_decrypt函数解释
如下表
参数列表 | 描述 |
---|---|
参数1:data |
要解密的数据字符串,通常是由 openssl_encrypt 函数加密后的结果。 |
参数2:method |
填写加密方式,既然要解密 那么就要知道是如何加密 的,所以这里就必须填写与加密 时使用的算法模式相同! 例如: 加密模式 为 AES-256-CBC 那么这里就必须填写AES-256-CBC |
参数3:key |
解密密钥。这是用于解密的密钥,与加密时使用的密钥相同! 举个生活上的案例,你用什么钥匙锁门,那么你就要用相应的钥匙来开门,对吧! 并且这个密钥 的长度也要一致! |
参数4:options |
数据以什么形式进行处理并返回 它有两种常量设置方式: OPENSSL_RAW_DATA 和 OPENSSL_ZERO_PADDING , 加密时设置的什么,这里就设置什么! |
参数5:iv |
解密时需要使用加密时相同的 iv |
......................................... |
所以在上面的案例中encryptAES
函数接受要加密的数据、密钥
和初始向量
,并返回加密后的结果。
而且decryptAES
函数接受加密后的数据、密钥
和初始向量
,并返回解密后的原始数据。
特别注意的是密钥
和初始向量
的长度,必须要符合加密算法的要求!
大致流程如下图:
小结
看到这里你也应该大致了解了一下对称加密
了吧, 其实关于对称加密
还有很多有趣的内容,以后可以慢慢给跟大家分享!