一、网络安全
1.安全的原则
- 在网络上不允许传输用户隐私数据的明文。
- 在本地不允许保存用户隐私数据的明文。
2.数据安全
- 仅仅用POST请求提交用户的隐私数据,还是不能完全解决安全问题。
- 可以利用软件(比如Charles)设置代理服务器,拦截查看手机的请求数据。
- 因此:提交用户的隐私数据时,一定不要明文提交,要加密处理后再提交。
3.常用的加密算法及加密算法的选择
MD5 \ SHA \ DES \ 3DES \ RC2和RC4 \ RSA \ IDEA \ DSA \ AES
4.常见的安全处理机制
- 单向散列函数:MD5、SHA1、SHA256、SHA512等。
- 消息认证码:HMAC-MD5、HMAC-SHA1。
- 对称加密: DES、3DES、AES(高级加密标准)。
- 非对称加密:RSA。
- 数字签名
- 证书
二、Base64编码
1.说明
HTTP将Base64编码用于基本的认证和摘要认证。
其可以方便的将用户的任何输入转换成只包含特定字符的安全格式,服务于网络通信过程。
2.特点
(1)可以将任意的二进制数据进行Base64编码。
(2)所有的数据都能被编码为并只用65个字符就能表示的文本文件。
(3)编码后的65个字符包括A~Z,a~z,0~9,+,/,=。
(4)对文件或字符串进行Base64编码后将比原始大小增加33%。
(5)能够逆运算。
(6)不够安全,但却被很多加密算法作为编码方式。
3.Base64编码原理
(1)将所有字符转化为ASCII码;
(2)将ASCII码转化为8位二进制;
(3)将二进制3个归成一组(不足3个在后边补0)共24位,再拆分成4组,每组6位;
(4)统一在6位二进制前补两个0凑足8位;
(5)将补0`后的二进制转为十进制;
(6)从Base64编码表获取十进制对应的Base64编码。
4.实现步骤
(1)转换的时候,将3个byte的数据
,先后放入1个24bit的缓冲区中
,先来的byte
占高位。
(1)数据不足3byte
的话,于缓冲区中剩下的bit用0
补足。然后,每次
取出6个bit
,按照其值选择查表选择对应的字符作为编码后的输出。
(2)不断进行,直到全部输入数据转换完成。
(3)如果最后剩下两个输入数据,在编码结果后加1
个“=”;
(4)如果最后剩下一个输入数据,编码结果后加2
个“=”;
(5)如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。
//给定一个字符串,对该字符串进行Base64编码,然后返回编码后的结果
-(NSString *)base64EncodeString:(NSString *)string{
//1.先把字符串转换为二进制数据
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
//2.对二进制数据进行base64编码,返回编码后的字符串
return [data base64EncodedStringWithOptions:0];
}
//对base64编码后的字符串进行解码
-(NSString *)base64DecodeString:(NSString *)string{
//1.将base64编码后的字符串『解码』为二进制数据
NSData *data = [[NSData alloc]initWithBase64EncodedString:string options:0];
//2.把二进制数据转换为字符串返回
return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}
三、单向散列函数
单向散列函数也称为消息摘要函数、哈希函数。单向散列函数输出的散列值又称为消息摘要或者指纹。
1.性质
(1)对任意长度的消息散列得到散列值是定长的。
(2)散列计算速度快,非常高效。
(3)消息不同,则散列值一定不同。
(4)消息相同,则散列值一定相同。
(5)具备单向性,无法逆推计算。

2.MD5
MD5是由Rivest于1991年设计的单向散列函数。全称是Message Digest Algorithm 5,译为“消息摘要算法第5版”。
MD5的特点
(1)对输入信息生成唯一的128位散列值(32个字符)。
(2)明文不同,则散列值一定不同。
(3)明文相同,则散列值一定相同。
(4)根据输出值,不能得到原始的明文,即其过程不可逆。
MD5的应用
- 加密
- 搜索:多个关键字,先对每个关键字进行散列,然后多个关键字进行或运算,如果值一致则搜索结果一致。
- 文件完整性验证: 对整个文件进行散列,比较散列值判断文件是否完整或被篡改。
安全性
MD5解密网站:http://www.cmd5.com
MD5的强抗碰撞性已经被证实攻破,即对于重要数据不应该再继续使用MD5加密。
MD5改进
现在的MD5已不再是绝对安全,对此,可以对MD5稍作改进,以增加解密的难度:
- 加盐(Salt):在明文的固定位置插入随机串,然后再进行MD5。
- 先加密,后乱序:先对明文进行MD5,然后对加密得到的MD5串的字符进行乱序。
- 先乱序,后加密:先对明文字符串进行乱序处理,然后对得到的串进行加密。
- 先乱序,再加盐,再MD5等。
- 总之宗旨就是:黑客就算攻破了数据库,也无法解密出正确的明文。
// MD5加密算法
-(NSString *)stringToMD5:(NSString *)str{
// 1.首先将字符串转换成UTF-8编码, 因为MD5加密是基于C语言的,所以要先把字符串转化成C语言的字符串
const char *fooData = [str UTF8String];
// 2.然后创建一个字符串数组,接收MD5的值
unsigned char result[CC_MD5_DIGEST_LENGTH];
// 3.计算MD5的值, 这是官方封装好的加密方法:把我们输入的字符串转换成16进制的32位数,然后存储到result中
/*第一个参数:要加密的字符串
第二个参数: 获取要加密字符串的长度
第三个参数: 接收结果的数组
*/
CC_MD5(fooData, (CC_LONG)strlen(fooData), result);
// 4.创建一个字符串保存加密结果
NSMutableString *saveResult = [NSMutableString string];
// 5.从result 数组中获取加密结果并放到 saveResult中
for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[saveResult appendFormat:@"%02x", result[I]];
}
// x表示十六进制,%02X 意思是不足两位将用0补齐,如果多余两位则不影响
return saveResult;
/*
这里返回的是32位的加密字符串,有时我们需要的是16位的加密字符串,其实仔细观察即可发现,16位的加密字符串就是这个字符串中见的部分。我们只需要截取字符串即可([saveResult substringWithRange:NSMakeRange(7, 16)])
*/
}
四、对称加密
1.对称加密的特点
加密、解密使用相同的密钥。加密和解密的过程是可逆的(明文->密文->明文)。

2.经典算法
(1)DES 数据加密标准
(2)3DES 使用3个密钥,对消息进行(密钥1·加密)+(密钥2·解密)+(密钥3·加密)
(3)AES 高级加密标准
3.密码算法
密码算法可以分为分组密码和流密码两种
(1)分组密码:每次只能处理特定长度的一组数据的一类密码算法。一个分组的比特数量就称之为分组长度。
例如:DES和3DES的分组长度都是64比特。即每次只能加密64比特的明文,并生成64比特的密文。AES的分组长度有128比特、192比特和256比特可以选择。
(2)流密码:对数据流进行连续处理的一类算法。流密码中一般以1比特、8比特或者是32比特等作为单位俩进行加密和解密。
4.ECB分组模式
ECB模式的全称为Electronic CodeBook模式。又成为电子密码本模式。
特点:
(1)使用ECB模式加密的时候,相同的明文分组会被转换为相同的密文分组。
(2)类似于一个巨大的明文分组->密文分组的对照表。

5.CBC分组模式
iOS默认的是CBC模式,一般都是CBC模式。
CBC模式全称为Cipher Block Chainning模式(密文分组链接模式|电子密码链条)。
特点:在CBC模式中,首先将明文分组与前一个密文分组进行异或(XOR)运算,然后再进行加密。

6.AES加密CBC模式128加密
#import "DJViewController.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
#define gIv @"0123456789abcdef" //可以自行定义16位,向量,
@interface DJViewController ()<NSURLSessionDataDelegate>
@property(nonatomic,assign)CFSocketRef socketRef;
@end
@implementation DJViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *key = @"AAA";
NSString *testStr = @"testStr测试123";
NSData *testData =[testStr dataUsingEncoding:NSUTF8StringEncoding];
//加密
NSDate *encryptData = [self AES128_Encrypt:key encryptData:testData];
//解密
NSDate *decryptData = [self AES128_Decrypt:key encryptData:encryptData];
NSString *decryptStr = [[NSString alloc]initWithData:decryptData encoding:NSUTF8StringEncoding];
NSLog(@"%@",decryptStr);
}
- (NSData *)AES128_Encrypt:(NSString *)key encryptData:(NSData *)data{
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCKeySizeAES128+1];
memset(ivPtr, 0, sizeof(ivPtr));
[gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
kCCBlockSizeAES128,
ivPtr,
[data bytes],
dataLength,
buffer,
bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData *)AES128_Decrypt:(NSString *)key encryptData:(NSData *)data{
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCKeySizeAES128+1];
memset(ivPtr, 0, sizeof(ivPtr));
[gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr,
kCCBlockSizeAES128,
ivPtr,
[data bytes],
dataLength,
buffer,
bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
@end
五、非对称加密
非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。
公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。
特点:
(1)非对称密码体制的特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。
(2)对称密码体制中只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。所以保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,其中一个是公开的,这样就可以不需要像对称密码那样传输对方的密钥了。

1.经典算法——RSA
RSA 原理:
(1)求N,准备两个质数p和q,N = p x q;
(2)求L,L是p-1和q-1的最小公倍数。L = lcm(p-1,q-1);
(3)求E,E和L的最大公约数为1(E和L互质);
(4)求D,E x D mode L = 1。
RSA加密小实践
(1)p = 17,q = 19 =>N = 323;
(2)lcm(p-1,q-1)=>lcm(16,18)=>L= 144;
(3)gcd(E,L)=1 =>E=5;
(4)E乘以几可以mode L =1? D=29可以满足;
(5)得到公钥为:E=5,N=323;
(6)得到私钥为:D=29,N=323;
(7)加密 明文的E次方 mod N = 123的5次方 mod 323 = 225(密文);
(8)解密 密文的D次方mod N = 225的29次方 mod 323 = 123(明文)。
六、数字证书
数字证书的包含公钥和认证机构的数字签名。
网友评论