密码学在上世纪70年代以前,发展比较缓慢,主要以对称加密的方式进行,即加密和解密所用的是同一套规则,加密规则在传递过程中容易泄露,也就很容易被破解;1976年美国两位数学家迪菲、赫尔曼提出“迪菲赫尔曼密钥交换”算法,开启密码学研究的新方向;1977年三位麻省理工学院的数学家就一起设计了一种非对称加密算法,RSA算法加密。
一、 RSA 深入理解
(一)RSA 数学原理
RSA 非对称加密(现代加密算法),需要两个密钥,公开密钥简称公钥(publickey)私有密钥简称私钥(privatekey);公钥加密,私钥解密;私钥加密,公钥解密; 以下是RSA公式推导步骤: 1、欧拉函数 任一正整数n,小于等于n且能与n互质的正整数个数φ(n);
- 欧拉函数特点:
- 1.当n是质数时,φ(n) = n -1;
- 2.如果n可以分解成两个互质的整数之积,如 :n=A*B,则:φ(n) = φ(A)*φ(B);
- 根据以上两点得到:如果N是两个互质的质数P1和P2之,则:φ(N) = φ(P1)φ(P2) = (P1-1)(P2-1);
2、欧拉定理 如果两个正整数m和n互质,那么m的φ(n)次方减去1,可以被n整除,即
- 1.密钥交换场景
- 2.密钥交换原理 结合欧拉定理和模反元素,当同时满足①m<n,且②d是e相对于φ(n)的模反元素时,以下结果成立:
-
- RSA 算法
- RSA 算法
(二)OpenSSL 使用 RSA
OpenSSL 中 RSA常用的指令有以下几种:
| 命令 | 含义 |
|---|---|
| genrsa | 生成并输入一个RSA私钥 |
| rsautl | 使用RSA密钥进行加密,解密、签名和验证等运算 |
| rsa | 处理RSA密钥的格式转换等问题 |
1、生成RSA私钥,密钥长度为1024
二、 HASH算法与对称加密
(一)HASH算法
Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
1、Hash的特点
-
- 无限多的数据加密得到有限数目的表现形式,一定有一个或多个数据有相同的哈希值,叫做散列的碰撞;
2、Hash的用途
- 用户密码的加密
- 1、MD5,sha1,sha256,sha512等等,CMD5可根据存储记录(key-value)解密;
- 2、加盐加密 坏处:盐(是固定的)一旦泄露,一样可以CMD5解密,就不安全了,Hash加密的命令如下:
- md5 -s "string"
- echo -n "string" | openssl sha1 / echo -n "string" | openssl dgst sha1
- echo -n "string" | openssl sha256
- echo -n "string" | openssl sha512
- 3、HMAC 加密方案:a.使用一个密钥加密,并且做了两次散列 b.在实际开发中,密钥来自于服务器
- 1.注册:
- i.用户输入账号或者账户名,服务器对账号进行验证是否可用,可用时随机生成key返回给客户端,客户端存储key;
- ii.客户端拿到“key+用户密码”,进行HMAC拿到哈希值“hmac”,客户端将“账号+hmac”发送给服务器,服务器存储“账号+key+hmac”;
- iii.换设备登录时:
- 输入账号密码登录时,检测本地是否有相应key;
- 向服务器索要key,服务器对当前设备进行权限验证,有权限发送key,无权限,需要原设备授权,授权成功发送key;
- 客户端拿到key,进行登录,登录成功,保存key,登录失败,不保存key;
- 2.登录:防止“账号+hmac”被拦截时,被恶意登录;
- i.注册逻辑不变,服务器仍保存“账号+key+hmac”;
- ii.登录时用“(hmac+时间戳(到分钟)).md5+账号”,进行登录;
- iii.服务器用“hmac+(当前时间(到分钟)?-1)”方式进行验证,有限时间(00:01:00-00:01:59)内有效;
- 3.相应加密命令:
- echo -n "string" | openssl dgst -md5 -hmac "key" --计算HMAC MD5散列结果
- echo -n "string" | openssl sha1 -hmac "key" --计算HMAC SHA1散列结果
- echo -n "string" | openssl sha256 -hmac "key" --计算HMAC SHA256散列结果
- echo -n "string" | openssl sha512 -hmac "key" --计算HMAC SHA512散列结果
- 1.注册:
- 搜索引擎 - 模糊搜索
- 版权
- 相同的二进制文件hash值相同;
- 复制,修改文件格式,不改变文件的二进制,hash值相同;
- 压缩,base64改变文件二进制,所得hash值自然不同;
- 数字签名
- 对传输的明文数据进行Hash得到hash值;
- 利用RSA公钥对hash值进行加密,得到RSA密文,将密文和明文一起传输给服务器;
- 服务器用RSA私钥进行解密,得到hash值,并对传输的明文数据进行相同算法的Hash得到hash1值,并对hash和hash1匹配进行数据识别,相同时,说明数据正常,没有被改动;
(二)对称加密(传统加密算法)
1、常见算法
- DES 数据加密标准(用得少,强度低)
- 3DES 使用3个密钥,对相同的数据执行3次加密(没人用,太麻烦,不容易管理)
- AES 高级加密标准
2、应用模式
- ECB(Electronic Code Book):电子密码本模式。每一块数据,独立加密。
- 最基本的加密模式,也就是通常理解的加密,相同的明文将永远加密成相同的密文,无初始向量,容易受到密码本重放攻击,一般情况下很少用。
- CBC(Cipher Block Chaining):密码分组链接模式。使用一个密钥和一个初始化向量[IV]对数据执行加密。
- 明文被加密前要与前面的密文进行异或运算后再加密,因此只要选择不同的初始向量,相同的密文加密后会形成不同的密文,这是目前应用最广泛的模式。CBC加密后的密文是上下文相关的,但明文的错误不会传递到后续分组,但如果一个分组丢失,后面的分组将全部作废(同步错误)。
- CBC可以有效的保证密文的完整性,如果一个数据块在传递是丢失或改变,后面的数据将无法正常解密。
3、终端测试指令
-
1.DES加解密
- DES(ECB)加密
- $ echo -n hello | openssl enc -des-ecb -K 616263 -nosalt | base64
- DES(ECB)解密
- $ echo -n HQr0Oij2kbo= | base64 -d | openssl enc -des-ecb -K 616263 -nosalt -d
- DES(CBC)加密
- $ echo -n hello | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
- DES(CBC)解密
- $ echo -n alvrvb3Gz88= | base64 -d | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -d
- DES(ECB)加密
-
2.AES加解密
- 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
- 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
- AES(ECB)加密
- 提示:
-
1> 加密过程是先加密,再base64编码 -
2> 解密过程是先base64解码,再解密
-
4、CCCrypt函数分析
-
1.CCCrypt函数的参数意义及调用
/**CCCrypt 对称加密算法的核心函数(加密/解密)
CCCrypt(CCOperation op, CCAlgorithm alg, CCOptions options, const void *key, size_t keyLength, const void *iv, const void *dataIn, size_t dataInLength, void *dataOut, size_t dataOutAvailable, size_t *dataOutMoved);
参数:
1、 op kCCEncrypt 加密/kCCDecrypt 解密
2、 alg 加密算法、默认的 AES/DES
3、options 加密方式的选项
kCCOptionPKCS7Padding | kCCOptionECBMode;//ECB加密!
kCCOptionPKCS7Padding;//CBC 加密!
4、key 加密密钥
5、keyLength 密钥长度
6、iv 初始化向量,ECB 不需要指定
7、dataIn 加密的数据
8、dataInLength 加密的数据长度
9、dataOut 缓冲区(地址),存放密文的
10、dataOutAvailable 缓冲区的大小
11、dataOutMoved 加密结果大小
*/
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
self.algorithm,
option,
cKey,
self.keySize,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&decryptedSize);
-
2.利用CCCrypt函数动态调试获取加密内容
- 下符号断点
- 用寄存器register获取存储在其中的参数地址
register read x6 - 读取地址中数据
p (char *) 0x7fff5103219e
- 下符号断点