前段时间开发中用到了加密,就趁这个机会查阅了一些相关的资料,对解密加深了一些印象,以下是我的一些总结。
消息摘要算法、对称加密算法、非对称加密算法
首先来了解当前的几种主流的加密方式,这几种加密方式有各自不同的特点,对应着数据安全的不同需求,通过灵活使用这几种加密方式能大大提高数据的安全性。
消息摘要算法
数据摘要算法也被称为哈希(Hash)算法、散列算法。摘要算法通过对所有数据提取指纹信息以实现数据签名,数据完整性校验等功能由于其不可逆性,有时候会被用做敏感信息的加密。消息摘要算法的特点是将需要加密的数据进行一系列的处理最终输出一个128的密文,一般这个密文以32个16进制的字符存储。常见的摘要算法有CRC系列,MD系列,SHA系列以及以及PRIPEMD、PANAMA、TIGER等。
在以上的摘要算法中,MD5是比较常用的。在iOS的开发中,目前我使用到MD5的两个场景,一个是将用户的密码直接MD5加密,传输和存储都使用这个MD5值,保证用户的密码不会泄露。再一种是后台和客户端通信时,通过对指定的数据进行MD5加密进行身份验证。使用MD5做以上两种情况的加密主要是因为MD5具有以下特性:
1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
根据MD5的特点,MD5一般用于一致性验证,数字签名,安全访问限制,安全访问认证。一般的开发平台中都会集成MD5加密,在iOS的开发中,导入CommonCrypto/CommonDigest.h头文件即可进行MD5加密的操作,具体代码如下:
- (NSString *)getMd5_32Bit
{
const char *cStr = [self UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), digest );
NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[result appendFormat:@"%02x", digest[i]];
return result;
}
对称加密算法
对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,同时解密密钥也可以从加密密钥中推算出来。而在大多数的对称算法中,加密密钥和解密密钥是相同的,所以也称这种加密算法为秘密密钥算法或单密钥算法。它要求发送方和接收方在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信的安全性至关重要。
对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高。不足之处是,交易双方都使用同样钥匙,安全性得不到保证。此外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。常见的对称加密算法有:DES算法,3DES算法,TDEA算法,Blowfish算法,RC5算法,IDEA算法以及正在普及的AES算法。
在以上对称算法中使用较多的DES正在被安全性更高的AES算法所替代,一般的开发平台会集成AES加密,不过AES加解密的代码较复杂,一般使用第三方工具类进行加解密,这里就不进行代码展示了。
在使用AES进行加解密时,可能会遇到客户端与后台不能正常加解密的情况,比如客户端对数据加密之后,可以成功解密,但是将加密过后的数据传输到后台之后,就不能正常解密了。产生这种情况的原因是因为在加解密时不同平台的配置不同,所以需要注意将以下的设置在各个平台设置一致:
1、模式 模式有ECB/CBC等,iOS默认的是CBC;
2、Padding iOS默认的是PKCS7 等价于PKCS5;
3、初始向量 iv(下图中的NULL) iOS默认是00000000000;
4、keySize 有 128/192/256等。
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
非对称加密算法
非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。非对称加密的公钥和私钥都可以进行加解密,也就是说,公钥可以用来加密,此时只有对应的私钥能够对密文进行解密;私钥也可以进行加密,此时只有对应的公钥可以对密文进行解密。
优点:非对称加密与对称加密相比,其安全性更好:对称加密的通信双方使用相同的秘钥,如果一方的秘钥遭泄露,那么整个通信就会被破解。而非对称加密使用一对秘钥,一个用来加密,一个用来解密,而且公钥是公开的,秘钥是自己保存的,不需要像对称加密那样在通信之前要先同步秘钥;
缺点:非对称加密的缺点是加密和解密花费时间长、速度慢,只适合对少量数据进行加密。
在非对称加密算法中,RSA是比较常用的一个。RSA算法基于一个数论事实:将两个大质数相乘后很难通过结果推算出原来的两个质数,所有可以将乘积公开作为公开密钥。需要注意的是,各个平台需要的密钥的编码格式是不一样的,在生成密钥的时候,应该注意这一点。其中:
Java和Andriod:私钥—PKCS8编码、公钥—Base64编码;
iOS 和PHP :私钥—Base64编码、公钥—Base64编码;
此外,iOS可以使用p12格式和der格式的数字证书来进行加解密。
以下是生成各种编码格式密钥的openssl语句(Mac自带openssl,在终端执行即可,Windows系统的电脑可以下载openssl生成RSA密钥和数字证书),如有额外的需求,可以查阅资料进行编码格式转换:
1、生成ASCLL(Base64)编码的私钥
genrsa -out atrsa_private_key.pem 1024
2、生成ASCLL(Base64)编码的公钥
rsa -in atrsa_private_key.pem -pubout -out atrsa_public_key.pem
3、对私钥进行PKCS#8编码
pkcs8 -topk8 -in atrsa_private_key.pem -out pkcs8_atrsa_private_key.pem -nocrypt
4、创建证书请求
req -new -out atrsacert.csr -key atrsa_private_key.pem
5、生成证书并且签名
x509 -req -days 3650 -in atrsacert.csr -signkey atrsa_private_key.pem -out atrsacert.crt
6、转换格式,将PEM 格式文件转换成 DER 格式
x509 -outform der -in atrsacert.crt -out atrsacert.der
7、导出P12文件
pkcs12 -export -out atrsa_private_key.p12 -inkey atrsa_private_key.pem -in atrsacert.crt
</code></pre>
在生成密钥之后,按平台需求分配对应编码格式的密钥即可。RSA的加解密一般也集成在各个平台中,需要的话可以自己封装一个关于RSA加解密的工具类,也可以使用第三方的工具类,这个视情况而定。
总结
以上简单介绍了消息摘要算法、对称加密算法、非对称加密算法。数据摘要算法不可逆主要用于验证,对称算法和非对称算法可逆,但因他们各自的特性也有不同的用途,具体在什么场景应用这些算法,会在下一篇文章介绍。