一、base64

注意:准确来说一种编码方式,编码算法完全公开,可以逆向解码

1、简介:

Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节数组。以3个字节为一组。按顺序排列24位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所要编码的数据的字节数不是3的整倍数,也就是说在分组时最后一组不够3个字节。这时在最后一组填充1到2个0字节。并在最后编码完成后在结尾添加1到2个“=”。例:将对ABC进行BASE64编码首先取ABC对应的ASCII码值。A(65)B(66)C(67)。再取二进制值A(01000001)B(01000010)C(01000011),然后把这三个字节的二进制码接起来(010000010100001001000011),再以6位为单位分成4个数据块并在最高位填充两个0后形成4个字节的编码后的值(00010000)(00010100)(00001001)(00000011)。蓝色部分为真实数据。再把这四个字节数据转化成10进制数得(16)(20)(19)(3)。最后根据BASE64给出的64个基本字符表,查出对应的ASCII码字符(Q)(U)(J)(D)。这里的值实际就是数据在字符表中的索引。

注:BASE64字符表:包括大写 A-Z 小写 a-z 数字 0-9 和+ /

解码过程就是把4个字节再还原成3个字节再根据不同的数据形式把字节数组重新整理成数据.

2、加密原则:

6 bit(8bit) 一个字节. 不足的位数 用0 补齐.两个0 用一个 = 表示.

3加密特点

数据加密之后,数据量会变大,变大 1/3 左右.

4、示例代码:

UIImage *image = [UIImage imageNamed:@"0.jpeg"];

NSData *data = UIImageJPEGRepresentation(image, 1.0);

NSData *base64Data = [data base64EncodedDataWithOptions:NSDataBase64Encoding64CharacterLineLength];

[base64Data writeToFile:@"/Users/chh/Desktop/123" atomically:YES];

//    NSString *encodeStr = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

NSData *base64Data2 = [NSData dataWithContentsOfFile:@"/Users/chh/Desktop/123"];

NSData *baseData2 = [[NSData alloc] initWithBase64EncodedData:base64Data2 options:NSDataBase64DecodingIgnoreUnknownCharacters];

[baseData2 writeToFile:@"/Users/chh/Desktop/IMG_5551.jpeg" atomically:YES];

5、三方框架

GTMBase64pod 'GTMBase64', '~> 1.0.0'(和系统的base64有区别)

二、MD5

1、简介

MD5的全称是Message-DigestAlgorithm 5Message-Digest泛指字节串(Message)Hash变换,就是把一个任意长度的字节串变换成一定长的大整数。请注意我使用了"字节串"而不是"字符串"这个词,是因为这种变换只与字节的值有关,与字符集或编码方式无关。 MD5将任意长度的"字节串"变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。

MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被"篡改"。举个例子,你将一段话写在一个叫readme.txt文件中,并对这个readme.txt产生一个MD5的值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的"抵赖",这就是所谓的数字签名应用。

MD5还广泛用于加密和解密技术上,在很多操作系统中,用户的密码是以MD5值(或类似的其它算法)的方式保存的,用户Login的时候,系统是把用户输入的密码计算成MD5值,然后再去和系统中保存的MD5值进行比较,而系统并不"知道"用户的密码是什么。

: MD5加密是不可逆的,也就是说, MD5加密后是不能解密的,所谓的解密只是用大数据的试用”,来测出结果的.

2加密方式

NSString *password = @"zhang";

password = [password MD5];

备注:单纯的 MD5加密是不安全的,因此要用到 MD5加盐的方式

3MD5加盐

盐值:MD5加盐的值,加的盐值越高越好.(盐值可以随意添加)

// 生成盐值

NSString *salt = @"盐值";

// 拼接盐值

password = [password stringByAppendingString:salt];

// 加密

password = password.md5String;

4、第三方框架:

NSString+Hash

三、AES加密

AES加密解密需要专属的key值,如下面的password一般都是与Base64结合起来一起使用。

NSString *message = @"top secret message"; // message 为加密字符串 与密码混合加密

NSString *password = @"p4ssw0rd"; // passwprd 为用户输入的密码

NSString *encryptedData = [AESCrypt encrypt:message password:password]; //加密

NSString *message = [AESCrypt decrypt:encryptedData password:password]; //解密

第三方框架:

AESCryptpod 'AESCrypt', '~> 0.0.1'

四、DES

DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位(实际用到了56位,第816243240485664位是校验位, 使得每个密钥都有奇数个1),其算法主要分为两步:

a初始置换

其功能是把输入的64位数据块按位重新组合,并把输出分为L0R0两部分,每部分各长32,其置换规则为将输入的第58位换到第一位,50位换到第2……依此类推,最后一位是原来的第7位。L0R0则是换位输出后的两部分,L0是输出的左32,R0是右32,:设置换前的输入值为D1D2D3……D64,则经过初始置换后的结果为:L0=D58D50……D8;R0=D57D49……D7

其置换规则见下表:

58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,

62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,

57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,

61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,

b逆置换

经过16次迭代运算后,得到L16R16,将此作为输入,进行逆置换,逆置换正好是初始置换的逆运算,由此即得到密文输出。

此算法是对称加密算法体系中的代表,在计算机网络系统中广泛使用.

备注:数据加密标准,速度较快,适用于加密大量数据的场合。

详情见#import "CommonFunc.h"

/******************************************************************************

函数名称: + (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key

函数描述: 文本数据进行DES加密

输入参数: (NSData *)data

(NSString *)key

输出参数: N/A

返回参数: (NSData *)

备注信息: 此函数不可用于过长文本

******************************************************************************/

+ (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key

{

char keyPtr[kCCKeySizeAES256+1];

bzero(keyPtr, sizeof(keyPtr));

[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [data length];

size_t bufferSize = dataLength + kCCBlockSizeAES128;

void *buffer = malloc(bufferSize);

size_t numBytesEncrypted = 0;

CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,

kCCOptionPKCS7Padding | kCCOptionECBMode,

keyPtr, kCCBlockSizeDES,

NULL,

[data bytes], dataLength,

buffer, bufferSize,

&numBytesEncrypted);

if (cryptStatus == kCCSuccess) {

return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];

}

free(buffer);

return nil;

}

/******************************************************************************

函数名称: + (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key

函数描述: 文本数据进行DES解密

输入参数: (NSData *)data

(NSString *)key

输出参数: N/A

返回参数: (NSData *)

备注信息: 此函数不可用于过长文本

******************************************************************************/

+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key

{

char keyPtr[kCCKeySizeAES256+1];

bzero(keyPtr, sizeof(keyPtr));

[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [data length];

size_t bufferSize = dataLength + kCCBlockSizeAES128;

void *buffer = malloc(bufferSize);

size_t numBytesDecrypted = 0;

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,

kCCOptionPKCS7Padding | kCCOptionECBMode,

keyPtr, kCCBlockSizeDES,

NULL,

[data bytes], dataLength,

buffer, bufferSize,

&numBytesDecrypted);

if (cryptStatus == kCCSuccess) {

return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];

}

free(buffer);

return nil;

}

五、钥匙串访问

1苹果在iOS 7.0.3版本以后公布钥匙串访问的SDK.钥匙串访问接口是纯C语言的.

2钥匙串使用AES 256加密算法,能够保证用户密码的安全.

3钥匙串访问的第三方框架SSKeychain,是对C语言框架的封装.注意:不需要看源码.

4钥匙串访问的密码保存在哪里?只有苹果才知道.这样进一步保障了用户的密码安全.

5、使用方法

Password :需要存储的密码信息.

Service :用来标识 app ,app的唯一标识符.

account :账户信息,当前密码所对应的账号.

a利用钥匙串进行加密

// 获取应用程序唯一标识.

NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;

// 利用第三方框架,将用户密码保存在钥匙串

[SSKeychain setPassword:self.pwdText.text forService:bundleId account:@"wpf"];

b从钥匙串加载密码

self.pwdText.text = [SSKeychain passwordForService:bundleId account:@"wpf"];

6、第三方框架

SSKeychainpod 'SSKeychain'

六、Token

1

token : 登录令牌.利用 token 值来判断用户的登录状态.类似于 MD5 加密之后的长字符串.

用户登录成功之后,在后端(服务器端)会根据用户信息生成一个唯一的值.这个值就是 token .

2、基本使用

a在服务器端(数据库)会保存这个 token ,以后利用这个 token 值来检索对应的用户信息,并且判断用户的登录状态.

b用户登录成功之后,服务器会将生成的 token 值返回给 客户端,在客户端也会保存这个 token .(一般可以保存在 cookie ,也可以自己手动确定保存位置(比如偏好设置.)).

c以后客户端在发送新的网络请求的时候,会默认自动附带这个 token (作为一个参数传递给服务器.).服务器拿到客户端传递的 token 值跟保存在 数据库中的 token 值做对比,以此来判断用户身份和登录状态.

3、判断登录状态

如果客户端没有这个token ,意味着没有登录成功过,提示用户登录.

如果客户端有token ,一般会认为登录成功(需要验证是否有效).不需要用户再次登录(输入账号和密码信息).

4、拓展

有效期说明:

一般的app ,token值得失效时间都在 1 年以上.

特殊的app :银行类 app /支付类 app :token值失效时间 15 分钟左右.

一旦用户信息改变(密码改变),会在服务器生成新的 token ,原来的 token值就会失效.需要再次输入账号和密码,以得到生成的新的 token .

唯一性判断: 每次登录,都会生成一个新的token.原来的 token 值就会失效.利用时间来判断登录的差异性。

点赞(1) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部