据说今天520是个好日子,为什么我想起的是502、500、404这些?还好服务器没事!

一、Base64编码

Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式,这样每一个字节的有效位为6位,则取值范围0~630 ~ (2^6 - 1)。如果最后剩下的字符不到3个字节,则用0填充,输出字符使用'=',因此我们看到Base64末尾会有1到2个'='。另外标准还要求每76个字符要插入换行(不过,这个视具体情况定)。

iOS7之后苹果有自己的Base64编码解码API,NSData的扩展:NSData (NSDataBase64Encoding)

两种存储方式

  • 可见字符串形式

为了保证所输出的每一个编码字节都是可读字符,而不是0~63这些数字,Base64制作了一个码表,就像ASCII码表一样,每一个Base64码值都有对应的字符。64个可读字符从0到63非别是A-Z、a-z、0-9、+、/,这也是Base64名字的由来。

  • 以16进制形式

即NSData形式保存,Base64编码结果为字符,而这些字符又对应ASCII码表的码值,NSData就是存储ASCII码表的码值。

下面举个例子,并以苹果提供的API来详细介绍Base64编码解码过程:

假设我们对字符串"123"进行Base64编码,"123"对应的16进制是313233,二进制为00110001、00110010、00110011,将其变为4*6结果即下表中的第一行。然后根据Base64的码表,它们分别对应表中的第二行。那么"123"编码的最终结果即为MTIz,以字符串的形式保存。然后根据MTIz对应ASCII码值,以NSData形式存储,如表中的第三行。

转换为4*6结果 00001100 00010011 00001000 00110011
Base64对应字符 M T I z
对应ASCII码值(16进制) 4d 54 49 7a

上面的过程通过代码实现如下:

// 1 待编码的原始字符串
NSString *plainStr = @"123";
// 2 将其转换成NSData保存,那么"123"对应的ASCII码表码值是31、32、33(16进制)
NSData *plainData = [plainStr dataUsingEncoding:NSUTF8StringEncoding];
// 3.1 将其进行Base64编码,且结果以字符串形式保存,对应表中的第二行
NSString *baseStr = [plainData base64EncodedStringWithOptions:0];
// 3.2 将其进行Base64编码,且结果以NSData形式保存
NSData *base64Data = [plainData base64EncodedDataWithOptions:0];

另外对于参数NSDataBase64EncodingOptions选项,有多种取值

  • NSDataBase64Encoding64CharacterLineLength:每64个字符插入\r或\n
  • NSDataBase64Encoding76CharacterLineLength:每76个字符插入\r或\n,标准中有要求是76个字符要换行,不过具体还是自己定
  • NSDataBase64EncodingEndLineWithCarriageReturn:插入字符为\r
  • NSDataBase64EncodingEndLineWithLineFeed:插入字符为\n

前两个选项为是否允许插入字符,以及多少个字符长度插入,两个可以选其一或者都不选。后两个选项代表要插入的具体字符。比如我们想76个字符后插入一个\r则可以NSDataBase64Encoding76CharacterLineLength | NSDataBase64EncodingEndLineWithCarriageReturn。而在上面举的例子中选项为0,则代表不插入字符。

第三方框架

在iOS7之前我们一般用的都是第三方框架,比如nicklockwood写的https://github.com/nicklockwood/Base64还有Google的GTMBase64,虽然苹果有了自己的实现,但是许多其它的加密框架都用到了它,所以还是要了解一下,另外它还提供任意长度字符插入\r\n,而苹果只能是64或76长度。

二、MD5、SHA1、SHA256、SHA512、HMAC实现

主要用于验证,防止信息被修改。介绍请参照http://www.jianshu.com/p/003b85fd3e36

具体的实现参考第三方框架:https://github.com/kelp404/CocoaSecurity。非常全面,不过不是太方便,比如想要获得MD5结果

NSString *plainStr = @"123";
CocoaSecurityResult *md5 = [CocoaSecurity md5:plainStr];
// 获取md5结果
NSString *md5Str = md5.hexLower;

不能直接plainStr.MD5Hash就获得字符串形式的结果,这里我封装了一个,可以参见工程中的NSString+Hash类https://github.com/mddios/EncryptionTools,可以直接对字符串进行操作,类似plainStr.MD5Hash、plainStr.sha1Hash···plainStr.sha256Hash···,非常方便。

比如对@"123"哈希,下面用上面提到的两种方法举例:

- (void)hashTest {
NSString *plainStr = @"123";
// md5
CocoaSecurityResult *md5 = [CocoaSecurity md5:plainStr];
NSLog(@"md5:%lu---%@---%@",plainStr.md5Hash.length, plainStr.md5Hash,md5.hex);
// 40
CocoaSecurityResult *sha1 = [CocoaSecurity sha1:plainStr];
NSLog(@"sha1:%lu---%@---%@",plainStr.sha1Hash.length, plainStr.sha1Hash,sha1.hex);
// 56
CocoaSecurityResult *sha224 = [CocoaSecurity sha224:plainStr];
NSLog(@"sha224:%lu---%@---%@",plainStr.sha224Hash.length,plainStr.sha224Hash,sha224.hex);
// 64
CocoaSecurityResult *sha256 = [CocoaSecurity sha256:plainStr];
NSLog(@"sha256:%lu---%@---%@",plainStr.sha256Hash.length,plainStr.sha256Hash,sha256.hex);
// 96
CocoaSecurityResult *sha384 = [CocoaSecurity sha384:plainStr];
NSLog(@"sha384:%lu---%@---%@",plainStr.sha384Hash.length,plainStr.sha384Hash,sha384.hex);
// 128
CocoaSecurityResult *sha512 = [CocoaSecurity sha512:plainStr];
NSLog(@"sha512:%lu---%@---%@",plainStr.sha512Hash.length,plainStr.sha512Hash,sha512.hex); // hmac
CocoaSecurityResult *hmacmd5 = [CocoaSecurity hmacMd5:plainStr hmacKey:plainStr];
NSLog(@"hmacmd5:%lu---%@---%@",[plainStr hmacMD5WithKey:plainStr].length,[plainStr hmacMD5WithKey:plainStr],hmacmd5.hex);
}
  • 在电脑终端来获取结果

封装的代码中NSString+Hash.h头文件,有具体列出终端命令方法,如下:

/// 返回结果:32长度   终端命令:md5 -s "123"
- (NSString *)md5Hash; /// 返回结果:40长度 终端命令:echo -n "123" | openssl sha -sha1
- (NSString *)sha1Hash; /// 返回结果:56长度 终端命令:echo -n "123" | openssl sha -sha224
- (NSString *)sha224Hash; /// 返回结果:64长度 终端命令:echo -n "123" | openssl sha -sha256
- (NSString *)sha256Hash; /// 返回结果:96长度 终端命令:echo -n "123" | openssl sha -sha384
- (NSString *)sha384Hash; /// 返回结果:128长度 终端命令:echo -n "123" | openssl sha -sha512
- (NSString *)sha512Hash; #pragma mark - HMAC /// 返回结果:32长度 终端命令:echo -n "123" | openssl dgst -md5 -hmac "123"
- (NSString *)hmacMD5WithKey:(NSString *)key; /// 返回结果:40长度 echo -n "123" | openssl sha -sha1 -hmac "123"
- (NSString *)hmacSHA1WithKey:(NSString *)key;
- (NSString *)hmacSHA224WithKey:(NSString *)key;
- (NSString *)hmacSHA256WithKey:(NSString *)key;
- (NSString *)hmacSHA384WithKey:(NSString *)key;
- (NSString *)hmacSHA512WithKey:(NSString *)key;
  • 关于MD5加盐,只是多了下面第一行
plainStr = [plainStr stringByAppendingString:salt];
NSString *md5Str = plainStr.md5Hash;

github代码下载地址

https://github.com/mddios/EncryptionTools

网络安全——Base64编码、MD5、SHA1-SHA512、HMAC(SHA1-SHA512)哈希的更多相关文章

  1. iOS base64编码 MD5 加密

    //创建一个Base64编码的NSString对象 //字符串 转二进制 NSData *nsdata = [@"iOS Developer Tips encoded in Base64&q ...

  2. 加密原理介绍,代码实现DES、AES、RSA、Base64、MD5

    阅读目录 github下载地址 一.DES对称加密 二.AES对称加密 三.RSA非对称加密 四.实际使用 五.关于Padding 关于电脑终端Openssl加密解密命令 关于网络安全的数据加密部分, ...

  3. When I see you again(加密原理介绍,代码实现DES、AES、RSA、Base64、MD5)

    关于网络安全的数据加密部分,本来打算总结一篇博客搞定,没想到东西太多,这已是第三篇了,而且这篇写了多次,熬了多次夜,真是again and again.起个名字:数据加密三部曲,前两部链接如下: 整体 ...

  4. 利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  5. MD5、SHA1、DES加密和解密,Base64编码解码

    /// <summary> /// EncryptHelper 来自 www.Admin10000.com /// </summary> public class Encryp ...

  6. hashlib加密模块主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法,HMAC消息签名(HMAC-SHA1,....)

    hashlib模块 用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法 MD5 摘要输出 # ...

  7. python 应用 base64、hmac、hashlib包实现:MD5编码 base64编码解码、SHA256编码、urlsafe_b64encode编码等等基本所有的加密签名的方法

    用python做HTTP接口自动化测试的时候,接口的很多参数是经过各种编码加密处理后在传到后台的,这里列举出python实现 应用 base64.hmac.hashlib包实现:md5编码 sha1编 ...

  8. python hashlib模块 md5加密 sha256加密 sha1加密 sha512加密 sha384加密 MD5加盐

      python hashlib模块   hashlib hashlib主要提供字符加密功能,将md5和sha模块整合到了一起,支持md5,sha1, sha224, sha256, sha384, ...

  9. HTML5 加密和摘要算法(base64,md5, sha1,rsa)

    < 一 > BASE64 1,Base64 是网络上最常见的用于传输 8Bit 字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法 2,首先需要一个库 b ...

随机推荐

  1. Xamarin.Android之使用百度地图起始篇

    一.前言 如今跨平台开发层出不穷,而对于.NET而言时下最流行的当然还是Xamarin,不仅仅能够让我们在熟悉的Vs下利用C#开发,在对原生态类库的支持方面也有着非常的好支持,今天我们将会以百度地图类 ...

  2. .NET中使用Redis (二)

    很久以前写了一篇文章 .NET中使用Redis 介绍了如何安装Redis服务端,以及如何在.NET中调用Redis读取数据.本文简单介绍如何设计NoSQL数据库,以及如何使用Redis来存储对象. 和 ...

  3. 如何利用 Visual Studio 自带工具提高开发效率

    Visual Stuido 是一款强大的Windows 平台集成开发工具,你是否好好地利用了它呢? 显示行号 有些时候(比如错误定位)的时候,显示行号将有利于我们进行快速定位. 如何显示 1. 工具 ...

  4. 工欲善其事,必先利其器 之 WPF篇: 随着开发轨迹来看高效WPF开发的工具和技巧

    之前一篇<工欲善其事,必先利其器.VS2013全攻略(安装,技巧,快捷键,插件)!> 看到很多朋友回复和支持,非常感谢,尤其是一些拍砖的喷油,感谢你们的批评,受益良多. 我第一份工作便是W ...

  5. xp搭建IIS出现HTTP 500错误-2147467259 (0x80004005)

    安装IIS后访问localhost页面, 提示The remote procedure call failed and did not execute,再刷新变为:-2147467259 (0x800 ...

  6. Android笔记——Matrix

    转自:http://www.cnblogs.com/qiengo/archive/2012/06/30/2570874.html#translate Matrix的数学原理 在Android中,如果你 ...

  7. Sql Server系列:SQL语句查询数据库中表、视图、存储过程等组成

    1. 查看用户表 select name from sys.tables select name from sys.objects where type='U' select name from sy ...

  8. CSS 定位之绝对与相对

    static,relative,absolute,fixed含义 static(静态定位):元素框正常生成.块级元素生成一个矩形框,作为文档流的 的一部分,行内元素则会常见一个或多个行框,至于其父元素 ...

  9. MVC5 网站开发之七 用户功能 1、角色的后台管理

    角色是网站中都有的一个功能,用来区分用户的类型.划分用户的权限,这次实现角色列表浏览.角色添加.角色修改和角色删除. 目录 奔跑吧,代码小哥! MVC5网站开发之一 总体概述 MVC5 网站开发之二 ...

  10. 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

    图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...