博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 密码学一
阅读量:3729 次
发布时间:2019-05-22

本文共 9062 字,大约阅读时间需要 30 分钟。

文章目录

MD5加盐和HMAC

123+一堆乱七八糟的东西,前后中间随便加,让别人无法直接破解123

盐的不足之处:1.这个盐是固定的,只要是开发者都得知道这个盐(iOS端,Android端,服务器端)如果泄漏出去就能破戒掉。
2.盐写死了,1.0写入已经对密码加密了,2.0版本如果要改,就不能改了。

HMAC:使用广泛,给定一个密钥,做明文和密钥的拼接,然后做2次MD5的计算。

加密部分

加密算法

—Hash 散列函数。是不可逆的
加密算法不应该都是不可逆的。

  • 以下两种算法是可逆的
    1.对称加密 传统的加密算法
    加密和解密都使用一个密钥。密钥的保密工作非常重要。
    2.非对称加密RSA(现代加密算法)
    有公钥和私钥:1.用公钥加密,私钥解密。2.用私钥加密,公钥解密
    明文>加密-密文
    密文>解密-明文

一个故事讲完https

A和B网络聊天,相隔很远,有一天他们突然发现,他们一直是在明文聊天,相当于在网上裸奔,如果任何一个不怀好意的人,都可以监听他们的聊天内容,打开他们传输的数据包,窥探他们的隐私。

A和B就商量做一个数据加密!
逻辑是:发送信息之前,加密;B收到的时候进行解密。
这时对称加密。问题就来了,他们需要先约定一个密钥,约定密钥的过程也会被监听。
所以之后就出现了非对称的加密。A有一个公钥和私钥,B也有一个公钥和私钥。监听者拿到我的私钥不知道公钥是多少,拿到公钥不知道私钥是多少。如下:

在这里插入图片描述

实现几次后,发现RSA有点慢。所以约定,非对称+对称加密。第一次非对称方式把密钥发送过去,其他消息用对称加密方式发过去。
优点:既解决了密钥的传送问题,又解决了RSA传输速度慢的问题。
疑问:如果A发送公钥给B的时候,有个中间人C截获了这个公钥,然后冒充A将一个伪装的假的公钥发给B。这时候B就会把中间人C当成A。
在这里插入图片描述
这时候就约定,需要一个数字证书,即把公钥和个人信息用Hash算法生成(不可逆)

对称加密

加密和解密使用同一个"密钥"!

密钥的保密工作就非常的重要!! 密钥会定期更换!密钥的管理很重要!!

对称加密的经典算法

  • DES数据加密标准
  • 3DES(使用3个密钥,对相同的数据加密3次,争强加密强度)
  • AES 高级加密标准(美国国家安全局就用的这个,苹果的钥匙串访问也是使用的AES)

2种加密的方式

ECB:将每一个数据块单独加密,最后再拼接。解密也是同样的道理,先拆分数据块,独立解密。但是只要截获了其中某一块如果解密成功,那么整个信息就会暴露。

CBC:加密每一个数据块,都会与上一个数据块之间有联系;密码块链,使用密钥和一个向量对数据执行加密转换,能够保证密文的完整性,如果一个数据改变了,后面的数据都会造成破坏。

终端操作加密的命令

cd Desktop

cd Desktop
显示该目录下的内容:

ls

创建名为加密的文件夹

mkdir 加密

编辑abc.txt,没有则创建

vim abc.txt

显示abc.txt的内容

more abc.txt

des加密,ECB方式。K:密钥 nosalt:不加盐

xiexin$ openssl enc -des-ecb -K 616263 -nosalt -in abc.txt -out msg1.bin

显示加密后的msg1.bin内容

xxd msg1.bin

des加密,CBC方式。iv:向量

openssl enc -des-cbc -iv 01020304050607080 -K 616263 -nosalt -in abc.txt -out msg4.bin
/** *  终端测试指令 * *  DES(ECB)加密 *  $ echo -n 加密的内容如:(hello) | openssl enc -des-ecb -K Key的ASCII码如:(abc=616263) -nosalt | base64 * * DES(CBC)加密 *  $ echo -n 加密的内容如:(hello) | openssl enc -des-cbc -iv 初始化向量(8个字节)如:0102030405060708 -K Key的ASCII码如:(abc=616263) -nosalt | base64 * *  AES(ECB)加密 *  $ echo -n 加密的内容如:(hello) | openssl enc -aes-128-ecb -K Key的ASCII码如:(abc=616263) -nosalt | base64 * *  AES(CBC)加密 *  $ echo -n 加密的内容如:(hello) | openssl enc -aes-128-cbc -iv 初始化向量(8个字节)如:0102030405060708 -K Key的ASCII码如:(abc=616263) -nosalt | base64 * *  DES(ECB)解密 *  $ echo -n 解密的内容如:(HQr0Oij2kbo=) | base64 -D | openssl enc -des-ecb -K Key的ASCII码如:(abc=616263) -nosalt -d * *  DES(CBC)解密 *  $ echo -n 解密的内容如:(alvrvb3Gz88=) | base64 -D | openssl enc -des-cbc -iv 初始化向量(8个字节)如:0102030405060708 -K Key的ASCII码如:(abc=616263) -nosalt -d * *  AES(ECB)解密 *  $ echo -n 解密的内容如:(d1QG4T2tivoi0Kiu3NEmZQ==) | base64 -D | openssl enc -aes-128-ecb -K Key的ASCII码如:(abc=616263) -nosalt -d * *  AES(CBC)解密 *  $ echo -n 解密的内容如:(u3W/N816uzFpcg6pZ+kbdg==) | base64 -D | openssl enc -aes-128-cbc -iv 初始化向量(8个字节)如:0102030405060708 -K Key的ASCII码如:(abc=616263) -nosalt -d * *  提示: *      1> 加密过程是先加密,再base64编码 *      2> 解密过程是先base64解码,再解密 */

如:AES(ECB)加密

xiexin$ echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64

在这里插入图片描述

如:AES(ECB)解密

echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d

在这里插入图片描述

AES(CBC)加密

echo -n CCSmile | openssl enc -aes-128-cbc -iv 0102030405060708 -K 6363 -nosalt | base64

AES(CBC)解密

echo -n O2GPaaMh3FMmX7PSLpmwkw== | base64 -D |openssl enc -aes-128-cbc -K 6363 -iv 0102030405060708 -nosalt -d

在这里插入图片描述

密文区别大小写,只要一样,终端和代码生成的密文是一样的.
终端的密钥-K需要是16进制的,可以通过以下形式知道密钥字符串的16进制是什么。
vim ab
在这里插入图片描述
xxd ab
在这里插入图片描述
OC中具体的代码实现
首先新建一个工具类 (EncryptionTools)

EncryptionTools.h

#import 
#import
@interface EncryptionTools : NSObject+ (instancetype)sharedEncryptionTools;/** @constant kCCAlgorithmAES 高级加密标准,128位(默认) @constant kCCAlgorithmDES 数据加密标准 */@property (nonatomic, assign) uint32_t algorithm;/** * 加密字符串并返回base64编码字符串 * * @param string 要加密的字符串 * @param keyString 加密密钥 * @param iv 初始化向量(8个字节) * * @return 返回加密后的base64编码字符串 */- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;/** * 解密字符串 * * @param string 加密并base64编码后的字符串 * @param keyString 解密密钥 * @param iv 初始化向量(8个字节) * * @return 返回解密后的字符串 */- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;@end

EncryptionTools.m

#import "EncryptionTools.h"@interface EncryptionTools()@property (nonatomic, assign) int keySize;@property (nonatomic, assign) int blockSize;@end@implementation EncryptionTools+ (instancetype)sharedEncryptionTools {    static EncryptionTools *instance;        static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        instance = [[self alloc] init];        instance.algorithm = kCCAlgorithmAES;    });        return instance;}- (void)setAlgorithm:(uint32_t)algorithm {    _algorithm = algorithm;    switch (algorithm) {        case kCCAlgorithmAES:            self.keySize = kCCKeySizeAES128;            self.blockSize = kCCBlockSizeAES128;            break;        case kCCAlgorithmDES:            self.keySize = kCCKeySizeDES;            self.blockSize = kCCBlockSizeDES;            break;        default:            break;    }}- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {        // 设置秘钥    NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];    uint8_t cKey[self.keySize];    bzero(cKey, sizeof(cKey));    [keyData getBytes:cKey length:self.keySize];        // 设置iv    /*     kCCOptionPKCS7Padding                      CBC 的加密方式     kCCOptionPKCS7Padding | kCCOptionECBMode   ECB 的加密方式     */    uint8_t cIv[self.blockSize];    bzero(cIv, self.blockSize);    int option = 0;    if (iv) {        [iv getBytes:cIv length:self.blockSize];        option = kCCOptionPKCS7Padding;    } else {        option = kCCOptionPKCS7Padding | kCCOptionECBMode;    }        // 设置输出缓冲区    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];    size_t bufferSize = [data length] + self.blockSize;    void *buffer = malloc(bufferSize);        // 开始加密    size_t encryptedSize = 0;    /***     CCCrypt 对称加密算法的核心函数(加密/解密)     参数:     1.kCCEncrypt  加密/kCCDecrypt 解密     2.加密算法,默认使用的是  AES/DES     3.加密选项  ECB/CBC          kCCOptionPKCS7Padding                      CBC 的加密方式         kCCOptionPKCS7Padding | kCCOptionECBMode   ECB 的加密方式     4.加密密钥     5.密钥长度     6.iv 初始化向量,ECB 不需要指定     7.加密的数据     8.加密的数据的长度     9.密文的内存地址     10.密文缓冲区的大小     11.加密结果大小     */    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,                                          self.algorithm,                                          option,                                          cKey,                                          self.keySize,                                          cIv,                                          [data bytes],                                          [data length],                                          buffer,                                          bufferSize,                                          &encryptedSize);        NSData *result = nil;    if (cryptStatus == kCCSuccess) {        result = [NSData dataWithBytesNoCopy:buffer length:encryptedSize];    } else {            free(buffer);        NSLog(@"[错误] 加密失败|状态编码: %d", cryptStatus);    }        return [result base64EncodedStringWithOptions:0];}- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {        // 设置秘钥    NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];    uint8_t cKey[self.keySize];    bzero(cKey, sizeof(cKey));    [keyData getBytes:cKey length:self.keySize];        // 设置iv    uint8_t cIv[self.blockSize];    bzero(cIv, self.blockSize);    int option = 0;    if (iv) {        [iv getBytes:cIv length:self.blockSize];        option = kCCOptionPKCS7Padding;    } else {        option = kCCOptionPKCS7Padding | kCCOptionECBMode;    }        // 设置输出缓冲区    NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0];    size_t bufferSize = [data length] + self.blockSize;    void *buffer = malloc(bufferSize);        // 开始解密    size_t decryptedSize = 0;    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,                                          self.algorithm,                                          option,                                          cKey,                                          self.keySize,                                          cIv,                                          [data bytes],                                          [data length],                                          buffer,                                          bufferSize,                                          &decryptedSize);        NSData *result = nil;    if (cryptStatus == kCCSuccess) {        result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];    } else {        free(buffer);        NSLog(@"[错误] 解密失败|状态编码: %d", cryptStatus);    }        return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];}@end

代码:稍后给链接

RSA非对称加密

终端生成公钥和私钥

生成私钥

openssl genrsa -out private.pem 512

在这里插入图片描述

生成公钥

openssl rsa -in private.pem -out public.pem -pubout

在这里插入图片描述

生成私钥的txt文本

openssl rsa in private.pem -text -out private.txt

在这里插入图片描述

终端查看文件信息

cat private.pem

在这里插入图片描述

open private.txt

PKCS

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

对称加密代码

https://github.com/ShaeZhuJiu/ios-SymmetricEncryption.git

非对称加密代码可参考

https://github.com/ideawu/Objective-C-RSA.git

通过文件获取私钥公钥:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

转载地址:http://biwin.baihongyu.com/

你可能感兴趣的文章
Java Set接口
查看>>
汇编语言 实现一个数字的平方
查看>>
Java 类反射
查看>>
汇编 SHL指令和SHR指令
查看>>
汇编 输入输出指令
查看>>
汇编语言 外部中断
查看>>
汇编语言 判断学生成绩是否及格
查看>>
汇编语言 ORG伪指令
查看>>
Xshell 连接 Ubuntu
查看>>
智能指针学习笔记
查看>>
MySQL8.0.19 Windows10安装
查看>>
Centos7 Docker安装
查看>>
SpringBoot2.x整合MyBatis
查看>>
Linux安装JDK1.8
查看>>
SpringBoot-Package打包
查看>>
Redis常用基础指令
查看>>
MySQL使用insert语句时查询最大值作为ID插入!
查看>>
解决MySQL8.0X中函数过程未能正常创建报错 1418等
查看>>
IDEA启动Java项目GC异常处理
查看>>
获取MySQL中所有的数据列类
查看>>