RSA & HASH
从苹果生成csr文件的步骤
- iOS 没有办法使用pem进行加密解密的,使用的话需要在钥匙串访问中创建
- 创建CSR文件 请求文件
通过openssl生成证书的步骤
-
请求csr文件
- 会填写一些组织的信息
- 通过自己创建的私钥(private.pem)生成请求文件,在到签名机构去签名
- 像https的证书也是一样的
- 签名就是证明这个证书是合法的
- 创建rsa的三个人创建了一个公司,成立了一个专门签名的机构,通过签名赚钱
- 自己也可以签名 就是没有认证
请求csr文件的命令
openssl req -new -key private.pem -out rsacert.csr
-
签名
-
签名命令
openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt -
签名的结果
- crt的最大用途。比如做https的请求,放到公司的服务器,需要别人接收
- crt的内容
-
-
将crt转换为可以使用的 我们从苹果哪里拿到的就是这个
-
crt 转der命令
openssl x509 -outform der -in rsacert.crt -out rsacert.der -
转换的结果
-
拿到der之后,就可以在钥匙串访问中绑定一个密钥
-
-
转换为p12文件
-
命令
openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt -
转换的结果 需要输入密码
-
p12文件和der文件是一对的 有了这两个文件之后,在代码里面就可以做加密解密了
-
总结 * private.pem是私钥 * public.pem 是公钥 * rsacert.csr 是请求文件 * rsacert.crt 是认证的证书 * rsacert.der 也是证书,只是转换了一下格式 * p12是私钥 * 最终通过rsacert.der 和 p12做加密和解密 代码里面只能用der和p12 * 加密和解密之后的文件都是二进制文件,iOS中就是NSData * 二进制文件没有办法去看加密之后的信息,为了展示二进制文件,会将二进制文件转码为base64
base64编码
-
上面通过cat命令看到的就是base64编码的结果
-
验证
-
创建message.txt文件
-
对文件进行编码 并查看内容
-
base64解码
-
-
原理 0~9 a~z A~Z + / = 65个字符组成的文本 维基百科Base64
-
文本Man的base64编码
-
通过上面的索引可以查表
-
如果只有两个字符,只有16个二进制位。16除以6除不尽,通过在空位补0,而且只在后面补0
-
iOS中使用base64编码解码
总结 * base64就是对二进制以查表方式编码解码 * 只适用于表示二进制文件 比如hash值 加密的结果 * 编码之后文件会变大 所以不适合对大型的数据编码解码
RSA加密
- 加载公钥私钥和加密解密
- (void)viewDidLoad {
[super viewDidLoad];
// 1 加载公钥
[[RSACryptor sharedRSACryptor] loadPublicKey:[[NSBundle mainBundle] pathForResource:@"rsacert" ofType:@"der"]];
// 2 加载私钥
[[RSACryptor sharedRSACryptor] loadPrivateKey:[[NSBundle mainBundle] pathForResource:@"p" ofType:@"p12"] password:@"123456"];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 加密
NSData *result = [[RSACryptor sharedRSACryptor] encryptData:[@"hello" dataUsingEncoding:NSUTF8StringEncoding]];
NSString *base64 = [result base64EncodedStringWithOptions:0];
NSLog(@"加密的结果 %@", base64);
// 解密
NSData *jiemi = [[RSACryptor sharedRSACryptor] decryptData:result];
NSLog(@"解密: %@", [[NSString alloc] initWithData:jiemi encoding:NSUTF8StringEncoding]);
}
- 结果不一样是应为rsa中有一个填充模式
/*!
@typedef SecPadding
@abstract Supported padding types.
*/
typedef CF_OPTIONS(uint32_t, SecPadding)
{
kSecPaddingNone = 0,
kSecPaddingPKCS1 = 1,
kSecPaddingOAEP = 2, // __OSX_UNAVAILABLE __IOS_AVAILABLE(2.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0),
/* For SecKeyRawSign/SecKeyRawVerify only,
ECDSA signature is raw byte format {r,s}, big endian.
First half is r, second half is s */
kSecPaddingSigRaw = 0x4000,
/* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is an MD2
hash; standard ASN.1 padding will be done, as well as PKCS1 padding
of the underlying RSA operation. */
kSecPaddingPKCS1MD2 = 0x8000, // __OSX_DEPRECATED(10.0, 10.12, "MD2 is deprecated") __IOS_DEPRECATED(2.0, 5.0, "MD2 is deprecated") __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE,
/* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is an MD5
hash; standard ASN.1 padding will be done, as well as PKCS1 padding
of the underlying RSA operation. */
kSecPaddingPKCS1MD5 = 0x8001, // __OSX_DEPRECATED(10.0, 10.12, "MD5 is deprecated") __IOS_DEPRECATED(2.0, 5.0, "MD5 is deprecated") __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE,
/* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is a SHA1
hash; standard ASN.1 padding will be done, as well as PKCS1 padding
of the underlying RSA operation. */
kSecPaddingPKCS1SHA1 = 0x8002,
/* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is a SHA224
hash; standard ASN.1 padding will be done, as well as PKCS1 padding
of the underlying RSA operation. */
kSecPaddingPKCS1SHA224 = 0x8003, // __OSX_UNAVAILABLE __IOS_AVAILABLE(2.0),
/* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is a SHA256
hash; standard ASN.1 padding will be done, as well as PKCS1 padding
of the underlying RSA operation. */
kSecPaddingPKCS1SHA256 = 0x8004, // __OSX_UNAVAILABLE __IOS_AVAILABLE(2.0),
/* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is a SHA384
hash; standard ASN.1 padding will be done, as well as PKCS1 padding
of the underlying RSA operation. */
kSecPaddingPKCS1SHA384 = 0x8005, // __OSX_UNAVAILABLE __IOS_AVAILABLE(2.0),
/* For SecKeyRawSign/SecKeyRawVerify only, data to be signed is a SHA512
hash; standard ASN.1 padding will be done, as well as PKCS1 padding
of the underlying RSA operation. */
kSecPaddingPKCS1SHA512 = 0x8006, // __OSX_UNAVAILABLE __IOS_AVAILABLE(2.0),
};
kSecPaddingNone 不填充 秘文不变 其他的会变化
RSA的应用场景之一
- 服务端(公钥) 客户端(私钥)
- 手机安装app的时候,自带公钥
- 服务端会定期更新下发到客户端的对称加密的密钥(key)
- 公钥和私钥对密钥进行解密和加密
- 密钥对传输的数据进行加密解密
- 公钥也可以下发更新
RSA的应用场景之二 签名
Hash
常见的Hash算法
- md5
- sha1 sha256 sha512
常见的对称加密
- DES
- 3DES
- AES 苹果用的就是这个 也叫做高级密码标准 美国安全局也是用这个
Hash的特点
- 算法是公开的
- 对相同数据运算,得到的结果是一样的
- 对不同数据运算,如MD5得到结果默认是128位,32个字符(16进制标识)
- 没法逆运算
- hash的结果是有限的,但是数据是无限的,必然有两个或者多个数据有相同的hash值,也就是散列碰撞
- 信息摘要,信息"指纹",是用来做数据识别的
Hash的用途
- 用户密码的加密
- 搜索引擎
- 版权
- 数字签名
用户密码的加密
- 原则
- 网络传输数据/本地保存数据(隐私数据) 不能明文
- 服务端也不能保存明文密码
PS 公司的秘密泄露,都会承担相应的法律责任
-
密码加密方式
- RSA加密密码
- 优点: 网络上泄露的可能低
- 缺点
- 服务端保存的是用户的真实密码(明文密码) 服务端的数据泄露了,存在安全隐患 (开发者最好不知道密码,最好使用hash)
- 私钥和公钥对开发人员是开放的,开放人员可能会携带离开公司,存在隐患,而且更换用户的公钥成本比较大
- Hash加密
- 客户端 传输 和 服务端都不知道明文密码 更安全
- RSA加密密码
-
Hash使用
- md5
- hash的结果值可以查询 md5查询网站
- 加盐
- md5(密码 + salt) salt就是一段固定的复杂的字符串
- 逻辑设计 客户端/服务端配置,在注册的时候,将加密后的hash发给服务端,服务端将hash值保存在服务端,和账号保存在一起。再次登陆的时候,就将hash发给服务器,验证用户
- 盐可能被开发者带走,不能用固定盐
- HMAC加密
-
服务端下发key, 客户端hmac做两次散列,一个账号一个key
-
特点
- 服务端下发key key就是不固定的salt
- 客户端hmac做两次散列
- 一个账号一个key
-
注册流程
- 发送账号到服务端,检测是否有用户注册 比如账号hankv587
- 没有注册,服务端下发key和hankv587绑定在一起,将key下发给客户端
- 客户端拿到key之后,输入密码,进行hmac加密
- 将加密之后得到的hash值发送给服务端,服务端进行保存
- 每次登陆的时候,都会将key下发
- key比较小,可以使用RSA加密
- 换手机之后,key重新下发。没有key说明不是授权登陆
- 很多的app,授权登陆
- 本地保存key最好使用钥匙串访问 钥匙串访问既可以是明文也可以加密
- 更换密码的时候,再次输入密码,可以更换key
- 钥匙串访问存入是加密,取出是解密
- 更换key时,先输入密码,拿到原始的key做验证,验证通过更新key,客户端收到key,服务端更新key
-
密码安全了,但是黑客可以模拟用户拿到hash值,再进行登陆
-
hash + 时间戳
- 原始的登陆方式不变
- 验证的方式变了 ((HMAC哈希值)+202006052134).md5 时间精确到分钟 是服务端下发的
- 服务端((HMAC哈希值)+202006052135自己的时间).md5 验证没有通过
- 服务端再验证上一分钟((HMAC哈希值)+202006052134自己的时间).md5 通过了
- 黑客破解必须在59秒 登陆和授权都相对安全
- 时间戳自定义 时间戳也可以RSA加密
-
- md5
搜索引擎
- 比如 搜索 词库 iOS 长沙 Hank/长沙 iOS Hank
- 计算每个词的hash值
- MD5 ("iOS") = 1bdf605991920db11cbdf8508204c4eb
- MD5 ("长沙") = 6b357589b12f6141fc48c4b0375ef2f9
- MD5 ("Hank") = ba02b1e3410f72ad50c76f9c144d6b3
- 将hash相加
- 1bdf605991920db11cbdf8508204c4eb + 6b357589b12f6141fc48c4b0375ef2f9 + ba02b1e3410f72ad50c76f9c144d6b3
- 次的顺序变化 结果值不变
- 计算每个词的hash值
- 版权
- 任意一个文件都能生成一个hash 上传一个愿文件,都会生成一个hash值
- 但是用户下载,比如图片、视频,里面会加一些东西,内容是一样的,但是和原始文件不一样
- 网盘 数据识别用的就是hash
数字签名
为什么用签名这个词.因为老外喜欢用支票,支票上面的签名能够证明这玩意是你的.那么数字签名顾名思义,就是用于鉴别数字信息的方法
- 目的是验证这个二进制数据是不是原始的,是不是颁发机构颁发的
- 用什么样的技术识别数据的真假?
- Hash
- 数据 + 数据的hash值
- 收到数据的一方,会通过同样的算法,计算数据的hash值,并和收到的hash比较,如果不相同,说明数据被更改了
- 但是hash值也一起被修改,验证就会通过
- 数据 + RSA(数据的hash值)
- 收到数据的一方,通过RSA解密,拿到数据的hash值
- 通过相同的hash算法,计算数据的hash值
- 比较两个hash值,如果不相同,说明数据被修改了 验证不通过
- 传输的时候,hash不会被修改
- 通过RSA加密数据,叫做数据签名
- RSA(数据的hash值)成为原始数据的数据签名
- 数字签名用途非常广泛 支付宝 各大银行 支付平台,iOS的签名验证
- iOS的签名验证是代码签名
- 数字签名签名的是数据
- 本质上是一样的
总结
- RSA终端的代码、RSA代码演示。
- RSA的特点
- RSA安全系数非常高 (因为整个业务逻辑非常安全 )
- 加密效率非常低 (不能做大数据加密)
- 用来加密关键数据! 例如加密hash值、hmac的key
- Hash
- 算法公开
- 不可逆运算
- 相同的数据结果相同
- 不同的数据长度相同
- 一般用户数据的识别 (密码、版权、百度云数据的识别)
- Hash用途
- 密码加密
- MD5直接加密
- 可以被反查询
- 加盐 固定的盐有安全隐患
- HMAC 通过动态的key来加密数据
- HMAC(比较好的方案)
- HASH + 时间戳 这样的方式 每次加密结果不一样 受时间的影响比较大
- MD5直接加密
- 密码加密
- 数字签名
- 算法: RSA + HASH
- 目的:验证数据的完整性 不被篡改
- 逻辑:
- 1 数据报文 原始数据
- 2 原始数据的HASH值
- 3 原始数据的HASH值通过RSA得到结果 (数据签名)