学习一下iOS常用的数据编码方案和加密方案
我们平时所接触的大多数是base64编码、UTF-8和一些加密算法(md5等),下面就聊聊这几种东西到底都是什么?
base64
base64是一种编码方案,不能用来加密。 base64后的结果由64种字符组成,对编码的结果可以反解码。
对文件base64编码的终端命令:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="shell" cid="n7" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">base64 文件路径</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="objective-c" cid="n11" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">#import <Foundation/NSData.h>
- (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options;//输出形式文本
- (NSData *)base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)options//输出形式Data</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n13" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">- (nullable instancetype)initWithBase64EncodedString:(NSString *)base64String options:(NSDataBase64DecodingOptions)options;
- (nullable instancetype)initWithBase64EncodedData:(NSData *)base64Data options:(NSDataBase64DecodingOptions)options;</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="shell" cid="n62" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">md5 -s “字符串” </pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="objective-c" cid="n97" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">#import <CommonCrypto/CommonCrypto.h>
extern unsigned char *CC_MD5(const void *data, CC_LONG len, unsigned char *md)</pre>
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n69" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; background-position: inherit inherit; background-repeat: inherit inherit;">$ md5 -s "217923012"
MD5 ("217923012") = c95d97ed441401a575e0ff0f70eb1de8</pre>
这就需要app安全方面的知识,反调试、加固(代码混淆)、反重签、越狱检测等等。
如果对方逆向Hook到系统的加密函数,直接获取到你的加密前的参数这不就知道原始数据了,这如何防护??
方向是增加复杂度。比如:也可以用一些有规律的202008021211时间年月日时分)和 密码HMAC后的一起拼接再次Hash,服务器校验时也拼接上时间,然后比对,考虑到请求延迟,服务器收到后也获取当前服务器时间,可以做向前一分钟容错。
还是有的,如果有人通过wifi路由器等方式拿到你的hash值,直接模拟账号发起请求怎么办?
HMAC了还有破绽吗?
换了设备也是这个流程,不过像QQ、微信、apple登录,并不是你向服务器要salt,它就会给,它会先向其他设备发起征求同意的请求,这也就是设备锁。
客户端登录时没有salt,就先向服务器请求,获得salt后,进行盐加密,登录。
客户端到服务器的交互流程:
HMAC 简单来说就是动态盐,一个用户一个盐
”HMAC加密方案“为此诞生
而且这个盐如果在客户端写死的话,逆向是很容易拿到的,就会变的非常不安全
比如选项 md5(salt);Joomla 。其中的 pass就是密码, salt就是盐, 你只要给他盐,他就能帮你解密!
image-20200811204446772肯定不安全。再看下网站的可选选项,发现人家也有加盐的匹配方案
加盐(salt)安全吗?
加盐什么意思呢?维基百科。简单来说,就是把密码217923012用一些鬼画符&……%¥##……**……%,穿插拼接一下,然后再去做md5,这样会极大降低Hash数据库的海量数据匹配度。
加盐(salt)方案为此诞生
其他加密算法,也都雷同于此。
把得到的md5打开网址https://www.cmd5.com/ 解密一下,发现可以解密。我又拿了我多年使用的字母加数字组合的密码,竟然也可以,细思极恐。
随便搞一串数字217923012 假设这就是密码
md5没有解密,那它就绝对安全吗?
以前大多软件还支持找回密码,现在几乎见不到了,都是重置密码。
一般来说服务器并不存储登录密码而是存储md5,但是也有直接存密码的,就会出现传说中,服务器数据泄露,密码泄露。
一般的登录流程:客户端输入密码->对密码md5->提交md5登录。
我所接触到的应用场景:密码加密、数据完整性校验。
OC代码框架
终端测试命令:
一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。
MD5举例应用
在项目中Hash用到的非常多, 拿最常用的MD5来详细说明使用场景
-
对强行攻击的安全性:最显著和最重要的区别是SHA-1摘要比MD5摘要长32 位,产生具有相同摘要的两个报文的难度MD5是2128数量级的操作,而对SHA-1则是2160数量级的操作,因而,SHA-1对强行攻击的强度更大。
-
对密码分析的安全性:由于MD5的设计,易受密码分析的攻击,SHA-1显得不易受这样的攻击。
-
速度:在相同的硬件上,SHA-1 的运行速度比 MD5 慢。
因为二者均由MD4改进得来,主要增加了算法的复杂度和不可逆性,他们很相似。
SHA-1 与 MD5区别
这些Hash算法都略有不同,MD5 和SHA-1 是单项散列函数的典型代表,拿SHA-1 与 MD5 来比较一下
-
这些算法都是算法公开
-
对相同的数据加密得到的结果是一样的
-
对不同的数据(文本、图片、电影等)加密,得到的结果是定长的,比如MD5就是32个字符
-
只能加密、不可逆,不能解密
Hash有几个显著特点:
Hash算法也叫散列函数,它分多种:MD5、SHA1/256/512
Hash也叫散列函数,其实严格来说,并不属于加密算法,因为它不可以解密
RSA之后延伸出来了很多加密算法,就比如Hash
Hash
DES、3DES、AES(高级密码标准)
对称加密
可以通过对其他加密算法加密出来的较短的加密结果进行二次RSA加密,配合使用
一般来说用于少量数据的加密。可是哪里这么巧都是少量数据啊?
它的秘钥很长,加密的计算量比较大,安全性较高,但是加密速度比较慢。
优缺点:
公钥可以有多个,可以多方持有,但私钥只有一个。
-
常见公钥加密,私钥解密
-
但私钥也可以加密 ,公钥也可以解密
两种使用方式:
RSA 是由三个提出者 Ron Rivest、Adi Shamir 和 Leonard Adleman 的姓氏首字母组成的。
常见的非对称算法主要有RSA、DSA等。
非对称加密
常见加密算法
先聊一聊UTF-8的由来
UTF-8:
一般加密过后的数据(NSData)会用base64来编码传输, 因为一般不直接用二进制来传输。
使用场景:
把base64编码后的NSData/NSString还原
把数据流进行base64编码
OC示例:
文件越大,输出的字符越长,由64种字符组成。
网友评论