密码学:对称加密

一、算法介绍

对称加密:明文通过密钥加密得到密文,密文通过密钥解密得到明文。

1.1常见算法

  • DES:数据加密标准(用得少,因为强度不够)。
  • 3DES:使用3个密钥,对相同的数据执行3次加密,强度增强。是通过数量级来增加强度,有3个密钥难保管,没有大量使用。
  • AES:高级密码标准。苹果的钥匙串访问就是使用AES

1.2应用模式

  • ECBElectronic Code Book):电子密码本模式。每一块数据,独立加密。

    • 最基本的加密模式,也就是通常理解的加密,相同的明文将永远加密成相同的密文,无初始向量,容易受到密码本重放攻击,一般情况下很少用。
      独立加密,独立解密。一块丢失不影响其他块。但是如果有一块被破解其他也一样被破解了。


      image.png
  • CBCCipher Block Chaining):密码分组链接模式。使用一个密钥和一个初始化向量[IV]对数据执行加密。

    • 明文被加密前要与前面的密文进行异或运算后再加密,因此只要选择不同的初始向量,相同的密文加密后会形成不同的密文,这是目前应用最广泛的模式。
    • CBC加密后的密文是上下文相关的,明文的错误不会传递到后续分组,但如果一个分组丢失,后面的分组将全部作废(同步错误)。
    • CBC可以有效的保证密文的完整性,如果一个数据块在传递是丢失或改变,后面的数据将无法正常解密。
      加密和解密依赖,后面的数据依赖前面的数据。一块被破解其他块不一定被破解。
      image.png

二、终端命令

2.1 ECB验证

有一个文本文件内容如下:

0000000000
1111111111 
2222222222
0000000000
1111111111 
2222222222
0000000000
1111111111 
2222222222

加密命令:

//openssl默认会加盐
openssl enc -des-ecb -K 616263 -nosalt -in message.txt -out message.bin

加密结果:

➜  对称加密 cat message.bin
�vz��HWm|+��B��ӭN�5��`T�IC_Iʻ���?�|{\���9�_���le��xG_�w��"�(��_�7���6�TNj��{F�xU�s�
   �r%                                                                          
➜  对称加密 xxd message.bin
00000000: d1f8 0876 7a80 0184 4857 6d7c 2bb7 9742  ...vz...HWm|+..B
00000010: d1f7 951b f7d3 ad4e c835 cec6 991c 08a2  .......N.5......
00000020: 6054 9914 1649 435f 49ca bbb3 aab0 3fc0  `T...IC_I.....?.
00000030: 7c7b 5c9c 8795 39cc 5fbb c6fa 6c65 a990  |{\...9._...le..
00000040: 7847 5fd9 0677 fdeb 22c8 28b9 905f 1701  xG_..w..".(.._..
00000050: d037 d2e2 c336 b854 4e15 6aab 9b7b 4681  .7...6.TN.j..{F.
00000060: 7855 a173 820b 9e72                      xU.s...r

修改下原始文件内容:

0000000000
1111111111 
8822222222
0000000000
1111111111 
2222222222
0000000000
1111111111 
2222222222

再次加密查看:

image.png

发现只有改动部分(16字节)不同,其他数据完全相同。

那么ECB分块的最小数据是多少呢?
只改一个数字试试看:

0000000000
1111111111 
8222222222
0000000000
1111111111 
2222222222
0000000000
1111111111 
2222222222
image.png

只修改一个二进制位看下:

1000000000
1111111111 
2222222222
0000000000
1111111111 
2222222222
0000000000
1111111111 
2222222222

image.png

可以看到是以8字节为单位进行加密的。只影响修改的数据,前后都不影响。

2.2CBC验证

加密命令:

openssl enc -des-cbc -K 616263 -iv 0102030405060708  -nosalt -in message.txt -out message.bin

同样修改文本对比:

0000000000
1111111111 
8822222222
0000000000
1111111111 
2222222222
0000000000
1111111111 
2222222222
image.png

可以看到后面的数据都变了。

2.3其它命令

2.3.1DES

DES(ECB)
加密

echo -n HotpotCat | openssl enc -des-ecb -K 616263 -nosalt | base64

9Ple3xnjfQogNxIjWHxWwg==

解密

echo -n 9Ple3xnjfQogNxIjWHxWwg== | base64 -D | openssl enc -des-ecb -K 616263 -nosalt -d

HotpotCat%

DES(CBC)
加密

echo -n HotpotCat | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt | base64

I6AD5342iBkvkzwFHDafFg==

解密

echo -n I6AD5342iBkvkzwFHDafFg== | base64 -D | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -d
HotpotCat%

2.3.1AES

AES(ECB)
加密

echo -n HotpotCat | openssl enc -aes-128-ecb -K 616263 -nosalt | base64

pqQyRfTkZVNQgO4wd2WFXQ==

解密

 echo -n pqQyRfTkZVNQgO4wd2WFXQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d

HotpotCat%

AES(CBC)
加密

echo -n HotpotCat | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64

LEtbC/NKpyNRfz7ko1mhIA==

解密

echo -n LEtbC/NKpyNRfz7ko1mhIA== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d

HotpotCat%

⚠️
1.加密过程是先加密,再base64编码。
2.解密过程是先base64解码,再解密。
3.加密和解密都是enc,通过-d区分是加密还是解密。

2.4key转换

可以通过xxd获取key对应的二进制数据
比如Hotpot(486f74706f74):

➜  对称加密 xxd message.txt
00000000: 486f 7470 6f74                           Hotpot

三、代码

iOS通过CommonCrypto库支持。

/*
algorithm 控制AES  DES
iv控制 ECB CBC
*/

//key
NSString *key = @"abc";
//iv
uint8_t iv[8] = {1,2,3,4,5,6,7,8};
NSData *ivData = [NSData dataWithBytes:iv length:sizeof(iv)];
//message
NSString *message = @"HotpotCat";



//AES + ECB 加密
NSString *encAES_ECBResult = [[HPCryptoTools sharedEncryptionTools] encryptString:message keyString:key iv:nil];
NSLog(@"AES_ECB enc:%@",encAES_ECBResult);

//AES + ECB 解密
NSString *decAES_ECBResult = [[HPCryptoTools sharedEncryptionTools] decryptString:encAES_ECBResult keyString:key iv:nil];
NSLog(@"AES_ECB dec:%@",decAES_ECBResult);

//AES + CBC 加密
NSString *encAES_CBCResult = [[HPCryptoTools sharedEncryptionTools] encryptString:message keyString:key iv:ivData];
NSLog(@"AES_CBC enc:%@",encAES_CBCResult);

//AES + CBC  解密
NSString *decAES_CBCResult = [[HPCryptoTools sharedEncryptionTools] decryptString:encAES_CBCResult keyString:key iv:ivData];
NSLog(@"AES_CBC dec:%@",decAES_CBCResult);


//修改加密为DES
[HPCryptoTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;

//DES + ECB 加密
NSString *encDES_ECBResult = [[HPCryptoTools sharedEncryptionTools] encryptString:message keyString:key iv:nil];
NSLog(@"DES_ECB enc:%@",encDES_ECBResult);

//AES + ECB 解密
NSString *decDES_ECBResult = [[HPCryptoTools sharedEncryptionTools] decryptString:encDES_ECBResult keyString:key iv:nil];
NSLog(@"DES_ECB dec:%@",decDES_ECBResult);

//AES + CBC 加密
NSString *encDES_CBCResult = [[HPCryptoTools sharedEncryptionTools] encryptString:message keyString:key iv:ivData];
NSLog(@"DES_CBC enc:%@",encDES_CBCResult);

//AES + CBC  解密
NSString *decDES_CBCResult = [[HPCryptoTools sharedEncryptionTools] decryptString:encDES_CBCResult keyString:key iv:ivData];
NSLog(@"DES_CBC dec:%@",decDES_CBCResult);

输出:

AES_ECB enc:pqQyRfTkZVNQgO4wd2WFXQ==
AES_ECB dec:HotpotCat
AES_CBC enc:LEtbC/NKpyNRfz7ko1mhIA==
AES_CBC dec:HotpotCat
DES_ECB enc:9Ple3xnjfQogNxIjWHxWwg==
DES_ECB dec:HotpotCat
DES_CBC enc:I6AD5342iBkvkzwFHDafFg==
DES_CBC dec:HotpotCat

Demo

四、CCCrypt函数

4.1CCCrypt介绍

CCCrypt对称加密算法的核心函数(加密/解密),共有11个参数:

CCCryptorStatus CCCrypt(
    CCOperation op,         /* kCCEncrypt, etc. */
    CCAlgorithm alg,        /* kCCAlgorithmAES128, etc. */
    CCOptions options,      /* kCCOptionPKCS7Padding, etc. */
    const void *key,
    size_t keyLength,
    const void *iv,         /* optional initialization vector */
    const void *dataIn,     /* optional per op and alg */
    size_t dataInLength,
    void *dataOut,          /* data RETURNED here */
    size_t dataOutAvailable,
    size_t *dataOutMoved)
    API_AVAILABLE(macos(10.4), ios(2.0));
  • CCOperationkCCEncrypt 加密,kCCDecrypt 解密
enum {
    kCCEncrypt = 0,
    kCCDecrypt,
};
typedef uint32_t CCOperation;
  • CCAlgorithm:加密算法、默认为AES
enum {
    kCCAlgorithmAES128 = 0, /* Deprecated, name phased out due to ambiguity with key size */
    kCCAlgorithmAES = 0,
    kCCAlgorithmDES,
    kCCAlgorithm3DES,
    kCCAlgorithmCAST,
    kCCAlgorithmRC4,
    kCCAlgorithmRC2,
    kCCAlgorithmBlowfish
};
typedef uint32_t CCAlgorithm;
  • CCOptions:加密模式
    ECBkCCOptionPKCS7Padding | kCCOptionECBMode
    CBCkCCOptionPKCS7Padding
enum {
    /* options for block ciphers */
    kCCOptionPKCS7Padding   = 0x0001,
    kCCOptionECBMode        = 0x0002
    /* stream ciphers currently have no options */
};
typedef uint32_t CCOptions;
  • key:密钥
  • keyLength:密钥长度
  • iviv 初始化向量,ECB 不需要。iv定长所以不需要长度(8字节)。
  • dataIn:加密/解密的数据
  • dataInLength:加密/解密的数据长度
  • dataOut:缓冲区(地址),存放密文/明文
  • dataOutAvailable:缓冲区大小
  • dataOutMoved:加密/解密结果大小

4.2CCCrypt安全隐患

直接在CCCrypt函数上打符号断点:

image.png

直接读取x6x7的值就直接拿到了明文数据HotpotCat和对应的长度:

image.png

4.3问题处理

4.3.1不使用CCCrypt函数

自己写一个函数加密

4.3.2使用CCCrypt函数

如果还要使用CCCrypt函数呢?
1.在调用CCCrypt之前对数据做一层加密/转换。比如:可以对明文数据进行按位异或再加密,解密先解密再按位异或还原。
2.对OC方法名称进行混淆。(脚本混淆)。

总结

  • 对称加密:AES
    • ECB:电子密码本模式。每一块数据独立加密。
    • CBC:链式加密,每一块数据的加密都依赖上一块数据。有效的保证了数据的完整性
      • 多一个参数:iv
    • CCCrypt函数:直接使用会有安全隐患。
      按位异或&代码混淆
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容