449,散列、对称加密和非对称加密(面试点:)
一、散列(哈希)
1.简介
散列函数,又称散列算法、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做散列值(hash values,hash codes,hash sums,或hashes)的指纹。散列值通常用一个短的随机字母和数字组成的字符串来代表。
将数据(如一段文字)运算变为另一固定长度值,是散列算法的基础原理。
2.特点
- 对相同数据运算,结果相同
- 对不同数据运算,结果长度相同
- 运算单向不可逆
3.常用算法
MD5
MD5消息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节,32个字符)的散列值(hash value),用于确保信息传输完整一致。
SHA家族
安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。
MD5使用比较频繁,但是如果只是简单使用MD5安全性较低,目前已有网站提供部分MD5破解,如https://www.cmd5.com。为了增加安全性,使用MD5时一般会在加密数据后加上某个随机值(就是所谓的加盐),然后再进行MD5运算。
HMAC,全称为“Hash Message Authentication Code”,中文名“散列消息鉴别码”,主要是利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。秘钥就是我们上述所说的‘盐’,使用HMAC会加大安全性,同时HMAC对所有散列算法都有效。
4.实际应用
哈希算法用途很多,比如用户密码加密
、文件校验
、数字签名和数据检索
。
用户密码加密
这里提供一个用户密码加密的方案:采用HMAC+MD5的方式进行加密,每个用户对应一个KEY作为HMAC的秘钥,HMAC运算结果再加上服务器返回的时间戳进行MD5,最终得到的值在网络上进行传输。为了进一步提高安全性KEY可以每过一段时间更换一次。
image.png获取KEY的时机:
- 注册时
- 登陆时本地没有KEY
- 登陆时本地有KEY,但是检测该账号更换了设备
服务器和客户端加密数据对比:
-
首先服务器存储的是HMAC(密码+KEY) = password,返回客户端的时间戳是timeInterval
-
服务器会计算2个值:MD5(password + timeInterval) = password_s1;MD5(password + (timeInterval - 60s)) = password_s2
-
客户端请求的密码数据是MD5( HMAC(密码 + KEY) + 时间戳) = password_app
-
服务器会对比password_app是否是password_s1和password_s2中的一个值,如果匹配到则密码校验成功
文件校验
MD5和SHA1都具有高度的离散性,哪怕是只修改一个字节值都会导致MD5或SHA1值“巨大”变化,从实践角度,不同信息具有相同MD5或SHA1码 的可能性非常低,通常认为是不可能的。
MD5 Hash算法的"数字指纹"特性,使它成为目前应用最广泛的一种文件完整性校验和(Checksum)算法。
注:秒传就是利用文件校验原理,哈希值相同代表改文件已经存在服务器,造成一种秒传的假象。
数字签名
由于哈希算法的唯一性,可以利用数据的哈希值判断数据是否被篡改,以此实现数字签名。通常传递给服务器的哈希值是经过RSA加密的。
数据检索
对搜索关键字进行哈希,通过哈希值匹配文件的关键字哈希值,以此实现检索。
二、对称加密
1.简介
对称密钥加密(英语:Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。
2.特点
- 计算量小
- 加密速度快、机密效率高
- 加密和解密使用相同秘钥,安全隐患大
3.常用算法
-
DES
数据加密标准(英语:Data Encryption Standard,缩写为 DES)是一种对称密钥加密算法。
DES现在已经不是一种安全的加密方法,主要因为它使用的56位密钥过短。 -
3DES
三重数据加密算法(英语:Triple Data Encryption Algorithm,缩写为TDEA,Triple DEA),或称3DES(Triple DES),是一种对称密钥加密块密码,相当于是对每个数据块应用三次数据加密标准(DES)算法。
由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。 -
AES
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),是美国联邦政府采用的一种区块加密标准。
密码学中,分组(block)密码的工作模式(mode of operation)允许使用同一个分组密码密钥对多于一块的数据进行加密,并保证其安全性。分组密码自身只能加密长度等于密码分组长度的单块数据,若要加密变长数据,则数据必须先被划分为一些单独的密码块。通常而言,最后一块数据也需要使用合适填充方式将数据扩展到匹配密码块大小的长度。
工作模式通常应用于对称加密,这里主要介绍一下ECB和CBC两种工作模式。
- (NSString *)aesCBCEncryptWithKey:(NSString *)key iv:(NSString *)iv {
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
NSData *result = [data aesCBCEncrypt:key iv:iv];
return [result base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
}
- (NSString *)aesCBCDecryptWithKey:(NSString *)key iv:(NSString *)iv {
NSData *data = [[NSData alloc] initWithBase64EncodedString:self options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSData *result = [data aesCBCDecrypt:key iv:iv];
return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
}
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
@implementation NSData (FNCBCAEScryption)
- (NSData *)aesCBCEncrypt:(NSString *)key iv:(NSString*)iv {
return [self aesEncrypt:key alg:kCCAlgorithmAES options:kCCOptionPKCS7Padding iv:iv];
}
- (NSData *)aesCBCDecrypt:(NSString *)key iv:(NSString*)iv {
return [self aesDecrypt:key alg:kCCAlgorithmAES options:kCCOptionPKCS7Padding iv:iv];
}
- (NSData *)aesEncrypt:(NSString *)key alg:(CCAlgorithm)alg options:(CCOptions)options iv:(NSString*)iv {
return [self aes:key alg:alg options:options iv:iv isEncrypt:YES];
}
- (NSData *)aesDecrypt:(NSString *)key alg:(CCAlgorithm)alg options:(CCOptions)options iv:(NSString*)iv {
return [self aes:key alg:alg options:options iv:iv isEncrypt:NO];
}
- (NSData *)aes:(NSString *)key alg:(CCAlgorithm)alg options:(CCOptions)options iv:(NSString*)iv isEncrypt:(BOOL)isEncrypt {
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(isEncrypt ? kCCEncrypt:kCCDecrypt, alg,
options,
keyPtr, kCCKeySizeAES256,
[iv UTF8String],
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
@end
电子密码本(ECB)
最简单的加密模式即为电子密码本(Electronic codebook,ECB)模式。需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密。
image.png image.pngECB模式的缺点在于同样的明文块会被加密成相同的密文块;因此,它不能很好的隐藏数据模式。
下面的例子显示了ECB在密文中显示明文的模式的程度:该图像的一个位图版本(左图)通过ECB模式可能会被加密成中图,而非ECB模式通常会将其加密成右图。