iOS网络安全相关&加密

base64编码解码原理

base64简介

  • 是网络上使用最广泛的编码系统,能够将任何二进制数据,转换成只有 65 个字符组成的文本文件.
  • 编码后的数据由 a-z A-Z 0-9 + / = 表示.
  • base64 编码后的结果能够反算,不够安全.
  • base64 是所有现代加密算法的基础算法.

Base64编码演示 = 终端命令

  • 编码文件
# 将 10.jpg 进行 base64 编码,生成 10.txt 文件
$ base64 10.jpg -o 10.txt

# 将 10.txt 解码生成 10.jpg 文件
$ base64 10.txt -o 10.jpg -D

  • 编码字符串
# 将字符串 Man 进行 base64 编码
$ echo -n "Man" | base64

# 将字符串 TWFu 解码
$ echo -n "TWFu" | base64 -D

base64编码的原理

  • 把一个字符转换成二进制取出前6位查表.
  • 不够6位的时候补0,如果是8位,则补4个0,编码后连接两个==.
  • 如果最后是4位,补2个0,编码后连接一个=.
  • 编码之后文件会变大,因为有补0.

图解base64编码原理



base64编码解码模拟加密解密

  • 提示 : 此处使用base64编码解码模拟数据的加密和解密.

加密和解密

  • 发送隐私信息时需要加密

  • 提示 : 服务器上保存的私密信息是机密之后的数据

  • 保存隐私信息时也需要加密

  • 读取保存的隐私信息时需要解密

  • 网络应用程序的数据安全

    • 网络上不允许传输用户隐私数据的"明文".
    • 在本地不允许保存用户隐私数据的"明文".

base64编码解码模拟加密解密代码实现

  • 提示 : base64编码的本质是编码不是加密.此处只是一个模拟加密

  • base64编码 ===> 模拟加密

/// base64编码---加密 : 传入需要"加密"的字符串,返回"加密"之后的字符串
- (NSString *)base64Encode:(NSString *)str
{
    // 1.将需要加密的数据转成二进制,因为Base64的编码和解码都是针对二进制的
    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    // 2.把二进制数据编码之后,直接转成字符串
    NSString *encodeStr = [data base64EncodedStringWithOptions:0];
    // 3.返回结果
    return encodeStr;
}

  • base64解码 ===> 模拟解密
/// base64解码---解密
- (NSString *)base64Decode:(NSString *)encodeStr
{
    if (encodeStr.length == 0) {
        return nil;
    }

    // 1.把编码之后的字符串解码成二进制
    NSData *data = [[NSData alloc] initWithBase64EncodedString:encodeStr options:0];
    // 2.把解码之后的二进制转换成字符串
    NSString *decodeStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    // 3. 返回结果
    return decodeStr;
}

  • 发送用户信息时先"加密".
NSString *psd = self.psdTextField.text;

// 密码加密之后再发送出去
psd = [self base64Encode:psd];

  • 保存用户信息之前"加密"处理.
/// 保存"加密"后的用户信息到偏好设置
- (void)saveUserInfo
{
    [[NSUserDefaults standardUserDefaults] setObject:self.userNameTextField.text forKey:userNameKey];

    // 保存之前先加密
    NSString *userName = [self base64Encode:self.psdTextField.text];
    [[NSUserDefaults standardUserDefaults] setObject:userName forKey:psdKey];
}

  • 读取本地"加密"的用户信息时需要"解密".
/// 读取保存到本地的"加密"的用户信息
- (void)readUserInfo
{
    self.userNameTextField.text = [[NSUserDefaults standardUserDefaults] objectForKey:userNameKey];

    // 读取时先解密
    NSString *psd = [self base64Decode:[[NSUserDefaults standardUserDefaults] objectForKey:psdKey]];
    self.psdTextField.text = psd;
}

base64编码的好处

  • 使用Base64编码之后,不能直接看到用户密码的明文.

存在的问题

  • 但是Base64编码解码的算法是公开的,并且算法可逆,安全性并不好.


MD5

MD5简介

  • 对任意的数据进行计算,生成固定长度的字符串.32个字符.
  • 一般用来加密密码.
  • 有时候也用来验证文件下载时,是否被篡改过.
    • 文件下载完成之后计算文件的md5值,与服务器计算的MD5值比较,如果不一样那么这个文件在下载的过程中被篡改了.

MD5终端命令

# 得到文件的MD5值
$ md5 文件名

# 得到字符串的MD5值
md5 -s "string"

MD5加密方案

  • 先导入分类 #import "NSString+Hash.h"

方案一 : 直接MD5计算

psd = [psd md5String];

  • Base64与MD5对比
    • Base64编码 : "加密"简单,算法可逆.毫无安全性可言.不能用来加密密码.
    • MD5 : 加密过程复杂,算法不可逆,安全性高,常用来加密密码等用户的敏感信息.但是简单的密码MD5加密之后可以暴力破解.
    • 暴力破解网站 : http://www.cmd5.com/

方案二 : 密码加盐

  • 如果原始密码过于简单,直接进行MD5加密是很容易被暴力破解的.
  • 为了增强密码的安全性,防止加密的密码被暴力破解,可以向原始密码中加盐.
  • 盐 : 服务器端和客户端约定的一个字符串.
  • MD5+盐 : 原始密码+盐拼接出新的密码字符串,再进行MD加密.
  • 以上为加一勺盐,比单纯的直接MD5加密安全性要高.
  • 盐要足够的咸,越咸越安全.
// 盐
NSString *salt = @"123zxcASD!@#";
psd = [[psd stringByAppendingString:salt] md5String];

方案三 : HMAC

  • HMAC : 加两勺盐.加两勺盐的密码加密强度比加一勺盐要高.
  • 原理 : 原始密码+盐进行MD5计算,结算的结果+原始密码再进行MD5计算.
// 盐
NSString *salt = @"123zxcASD!@#";
psd = [psd hmacMD5StringWithKey:salt];

注意

  • 不能用不可逆的加密算法加密密码并保存到本地.因为不可逆的加密算法加密的数据几乎不能还原回来.
  • 苹果提供了钥匙串专门保存用户的私密信息到本地.

钥匙串

  • safari 偏好设置里面可以读取到保存到钥匙串中的密码.
  • 使用 AES 256 加密算法,能够保证用户密码的安全.
  • 钥匙串访问SDK,是苹果在 iOS 7.0.3 版本以后公布的.钥匙串访问的SDK是纯 C 语言的.
  • 钥匙串访问的密码保存在哪里?
    • 只有苹果知道!是为了进一步保障用户的密码安全!
  • 钥匙串访问的第三方框架,是对 C 框架的封装,可以不用看源代码.
  • 框架地址 : https://github.com/soffes/sskeychain

sskeychain提供的常用的方法

/// 所有账户
+ (NSArray *)allAccounts;
/// 获取所有账户信息
+ (NSArray *)accountsForService:(NSString *)serviceName;
/// 获取账号密码
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account;
/// 删除账号密码
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account;
/// 将账号密码保存在钥匙串
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account;

密码保存到钥匙串

  • 先导入头文件 : #import "SSKeychain.h"
/*
参数1 : 要保存到钥匙串的密码
参数2 : 保存哪个应用的密码
参数3 : 保存哪个账号的密码
*/
[SSKeychain setPassword:self.psdTextField.text forService:[NSBundle mainBundle].bundleIdentifier account:self.userNameTextField.text];

从钥匙串读取密码

self.psdTextField.text = [SSKeychain passwordForService:[NSBundle mainBundle].bundleIdentifier account:self.userNameTextField.text];


















你可能感兴趣的:(iOS网络安全相关&加密)