据说今天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. // 1 待编码的原始字符串
  2. NSString *plainStr = @"123";
  3. // 2 将其转换成NSData保存,那么"123"对应的ASCII码表码值是31、32、33(16进制)
  4. NSData *plainData = [plainStr dataUsingEncoding:NSUTF8StringEncoding];
  5. // 3.1 将其进行Base64编码,且结果以字符串形式保存,对应表中的第二行
  6. NSString *baseStr = [plainData base64EncodedStringWithOptions:0];
  7. // 3.2 将其进行Base64编码,且结果以NSData形式保存
  8. 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结果

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

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

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

  1. - (void)hashTest {
  2. NSString *plainStr = @"123";
  3. // md5
  4. CocoaSecurityResult *md5 = [CocoaSecurity md5:plainStr];
  5. NSLog(@"md5:%lu---%@---%@",plainStr.md5Hash.length, plainStr.md5Hash,md5.hex);
  6. // 40
  7. CocoaSecurityResult *sha1 = [CocoaSecurity sha1:plainStr];
  8. NSLog(@"sha1:%lu---%@---%@",plainStr.sha1Hash.length, plainStr.sha1Hash,sha1.hex);
  9. // 56
  10. CocoaSecurityResult *sha224 = [CocoaSecurity sha224:plainStr];
  11. NSLog(@"sha224:%lu---%@---%@",plainStr.sha224Hash.length,plainStr.sha224Hash,sha224.hex);
  12. // 64
  13. CocoaSecurityResult *sha256 = [CocoaSecurity sha256:plainStr];
  14. NSLog(@"sha256:%lu---%@---%@",plainStr.sha256Hash.length,plainStr.sha256Hash,sha256.hex);
  15. // 96
  16. CocoaSecurityResult *sha384 = [CocoaSecurity sha384:plainStr];
  17. NSLog(@"sha384:%lu---%@---%@",plainStr.sha384Hash.length,plainStr.sha384Hash,sha384.hex);
  18. // 128
  19. CocoaSecurityResult *sha512 = [CocoaSecurity sha512:plainStr];
  20. NSLog(@"sha512:%lu---%@---%@",plainStr.sha512Hash.length,plainStr.sha512Hash,sha512.hex);
  21. // hmac
  22. CocoaSecurityResult *hmacmd5 = [CocoaSecurity hmacMd5:plainStr hmacKey:plainStr];
  23. NSLog(@"hmacmd5:%lu---%@---%@",[plainStr hmacMD5WithKey:plainStr].length,[plainStr hmacMD5WithKey:plainStr],hmacmd5.hex);
  24. }
  • 在电脑终端来获取结果

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

  1. /// 返回结果:32长度 终端命令:md5 -s "123"
  2. - (NSString *)md5Hash;
  3. /// 返回结果:40长度 终端命令:echo -n "123" | openssl sha -sha1
  4. - (NSString *)sha1Hash;
  5. /// 返回结果:56长度 终端命令:echo -n "123" | openssl sha -sha224
  6. - (NSString *)sha224Hash;
  7. /// 返回结果:64长度 终端命令:echo -n "123" | openssl sha -sha256
  8. - (NSString *)sha256Hash;
  9. /// 返回结果:96长度 终端命令:echo -n "123" | openssl sha -sha384
  10. - (NSString *)sha384Hash;
  11. /// 返回结果:128长度 终端命令:echo -n "123" | openssl sha -sha512
  12. - (NSString *)sha512Hash;
  13. #pragma mark - HMAC
  14. /// 返回结果:32长度 终端命令:echo -n "123" | openssl dgst -md5 -hmac "123"
  15. - (NSString *)hmacMD5WithKey:(NSString *)key;
  16. /// 返回结果:40长度 echo -n "123" | openssl sha -sha1 -hmac "123"
  17. - (NSString *)hmacSHA1WithKey:(NSString *)key;
  18. - (NSString *)hmacSHA224WithKey:(NSString *)key;
  19. - (NSString *)hmacSHA256WithKey:(NSString *)key;
  20. - (NSString *)hmacSHA384WithKey:(NSString *)key;
  21. - (NSString *)hmacSHA512WithKey:(NSString *)key;
  • 关于MD5加盐,只是多了下面第一行
  1. plainStr = [plainStr stringByAppendingString:salt];
  2. 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. PHP 高级编程(2/5) - 反射API

    PHP 5 具有完整的反射 API,添加了对类.接口.函数.方法和扩展进行反向工程的能力. 此外,反射 API 提供了方法来取出函数.类和方法中的文档注释.通过使用反射API可以分析其他的类.接口.方 ...

  2. ElasticSearch 5学习(3)——单台服务器部署多个节点

    一般情况下单台服务器只会部署一个ElasticSearch node,但是在学习过程中,很多情况下会需要实现ElasticSearch的分布式效果,所以需要启动多个节点,但是学习开发环境(不想开多个虚 ...

  3. SQL Server-聚焦强制索引查询条件和Columnstore Index(九)

    前言 本节我们再来穿插讲讲索引知识,后续再讲数据类型中的日期类型,简短的内容,深入的理解,Always to review the basics. 强制索引查询条件 前面我们也讲了一点强制索引查询的知 ...

  4. 2015游戏蛮牛——蛮牛杯第四届开发者大赛 创见VR未来开启报名

    蛮牛杯启动了,大家开始报名! http://cup.manew.com/ 这不是一篇普通的通稿,别着急忽略它.它是一篇可以让你梦想变现的通稿! 从某一天开始,游戏蛮牛就立志要为开发者服务,我们深知这一 ...

  5. 【干货】用大白话聊聊JavaSE — ArrayList 深入剖析和Java基础知识详解(二)

    在上一节中,我们简单阐述了Java的一些基础知识,比如多态,接口的实现等. 然后,演示了ArrayList的几个基本方法. ArrayList是一个集合框架,它的底层其实就是一个数组,这一点,官方文档 ...

  6. php内核分析(二)-ZTS和zend_try

    这里阅读的php版本为PHP-7.1.0 RC3,阅读代码的平台为linux ZTS 我们会看到文章中有很多地方是: #ifdef ZTS # define CG(v) ZEND_TSRMG(comp ...

  7. STemwin汉字显示

    硬件环境: STM32F429,电容屏800X480 5点触控RGB屏幕 ,SPI flash: 软件环境: UCOSIII,STemwin: 汉字显示方法: 1.在SPIflash中装在字库XBF_ ...

  8. 使用Setup Factory安装包制作工具制作安装包

    在我们开发完软件后,除了极个别案例我们把整个目录复制给客户用外,我们一般都需要做成安装包,方便整个软件的部署操作,以安装包的部署操作可能简单的是复制文件,也可能包括一些注册表.数据库等额外的操作,不过 ...

  9. 混合框架中Oracle数据库的还原处理操作

    在较早期的随笔<Oracle如何实现创建数据库.备份数据库及数据导出导入的一条龙操作>粗略介绍了Oracle数据库的备份还原操作,本文想从开发框架的基础上介绍Oracle数据库的脚本或者还 ...

  10. PHP数组详解

    作为一名C++程序员,在转做PHP开发的过程中,对PHP数组产生了一些混淆,与C++数组有相似的地方,也有一些不同,下面就全面地分析一下PHP的数组及其与C++中相应数据类型的区别和联系. 数组的分类 ...