常见的对称加密算法有:
- DES 数据加密标准
- 3DES 使用3个秘钥,对相同的数据执行3次加密,强度增强
- AES 高级加密标准
对称加密的加密、解密使用的是同一个KEY。
模式
-
ECB模式(Electronic Code Book)---电子密码本,他是对每一个独立的数据块进行加解密
image.png
我们新建一个123.txt文件,里面的内容如“123.txt图1”:使用ECB加密生成二进制文件,然后在终端xxd message.bin
看一下二进制文件数据。然后修改123.txt文件里面的一个数字“123.txt如图2”,再进行ECB加密输出message1.bin,在终端xxd message1.bin
对比一下这两个二进制数据。



我们发现这两个二进制文件其他的数据一样,只有
49ca bbb3 aab0 3fc0
和e576 4bac a6da e8a0
这8个字节不一样,我们基本可以验证,ECB是以8个字节为一个数据块进行独立加密,修改其中一个数据块并不影响其他数据的解密。*另外一点:经过测试,我改1个数字、2个数字和3个数字结果都是只改变一个数据块,当我改4个数据的时候,发现修改了两个数据块如下图:

- CBC 模式(Cipher Block Chaining)密码分组
模式。使用一个
+
进行加密。
- 明文被加密前要与前面的密文进行异或运算后再加密,因此只要选择不同的初始向量,相同的密文加密后会形成不同的密文,这是目前应用最广泛的模式。CBC加密后的密文是上下文相关的,但明文的错误不会传递到后续分组,但如果一个分组丢失,后面的分组将全部作废(同步错误)
- 因为其只要有一个数据被修改、丢失、失效会导致后面的数据无法解密,所以一般会用于数据
验证

我们使用ECB同样123.txt文件,里面的内容如“123.txt图1”:使用CBC加密生成二进制文件
message.bin
,然后,然后修改123.txt文件里面的一个数字“123.txt如图2”,再进行CBC加密输出message1.bin,在终端输入xxd message.bin
和xxd message1.bin
对比一下这两个二进制数据。除了第一个数据块一样,其他的都不一样,这就验证了,下一个数据块的加密依赖于上一个数据块,只要修改某一个数据块,后面的加密否不一样。
终端测试指令
-
DES(ECB)加密
-
$ echo -n mingwenshuju | openssl enc -des-ecb -K 616263 -nosalt | base64
-
DES(ECB)解密
-
$ echo -n JJP6Um4hTUnP6piKKEkbnw== | base64 -D | openssl enc -des-ecb -K 616263 -nosalt -d
image.png
-
DES(CBC)加密
-
$ echo -n hello | openssl enc -des-cbc -iv 12345678 -K 616263 -nosalt | base64
-
DES(CBC)解密
-
$ echo -n alvrvb3Gz88= | base64 -D | openssl enc -des-cbc -iv 12345678 -K 616263 -nosalt -d
image.png
-
AES(ECB)加密
-
$ echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
-
AES(ECB)解密
-
$ echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d
image.png
-
AES(CBC)加密
-
$ echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
-
AES(CBC)解密
-
$ echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d

系统提供的API--CCCrypt
/**
1.kCCEncrypt 加密/kCCDecrypt解密
2.加密算法
3.加密选项 ECB/CBC
4.KEY 的地址
5.KEY 的长度
6.iv 初始化向量
7.加密的数据(地址)
8.加密的数据长度
9.密文的内存地址
10.密文缓冲区的大小
11.加密结果大小
*/
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
self.algorithm,
option,
cKey,
self.keySize,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&encryptedSize);
对称加密都要使用到这个系统函数CCCrypt
,因为这个函数参数很全面,还有明文数据,使用它存在一定的安全隐患。通过下符号断点,可以断在这个函数,然后通过x6寄存器(第7个参数)拿到明文数据:




所以说使用这个函数的话,需要在加密前做一些处理,通过处理后再返回,或者对每一个关键参数做一定处理:
比如我们使用不仅限于8字节的Key/IV,我们希望支持多于8字节的Key/IV,那么简单的异或计算将所有被8除后余数相等的数组元素都合起来,变成8字节
即:
private byte[] FixSize(byte[] input) {
byte[] output = new byte[8];
for (int i = 0; i < input.length; I++)
output[i & 7] ^= input[I];
return output;
}
当然因为加解密都是用同一个KEY/iV向量,所以对一些关键参数的保护和算法的实现原理要做高度保密才能保证安全。
网友评论