iOS 编码(Base64) + 哈希摘要(MD5+SHA)

12 篇文章 0 订阅
12 篇文章 1 订阅

一、编码算法

(1)Base64编码

        在MIME格式的电子邮件中,base64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本。使用时,在传输编码方式中指定base64。使用的字符包括大小写字母各26个,加上10个数字,和加号“+”,斜杠“/”,一共64个字符,等号“=”用来作为后缀用途。
        完整的base64定义可见 RFC1421和 RFC2045。编码后的数据比原始数据略长,为原来的4/3。在电子邮件中,根据RFC822规定,每76个字符,还需要加上一个回车换行。可以估算编码后数据长度大约为原长的135.1%。
        转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的Bit用0补足。然后,每次取出6个bit,按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。
如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。

(2)UrlEncode编码

       百分号编码(Percent-encoding), 也称作URL编码(URL encoding), 是特定上下文的统一资源定位符 (URI)的编码机制. 实际上也适用于统一资源标志符(URI)的编码. 也用于为"application/x-www-form-urlencoded" MIME准备数据, 因为它用于通过HTTP的请求操作(request)提交HTML表单数据。
       URI所允许的字符分作保留与未保留. 保留字符是那些具有特殊含义的字符. 例如, 斜线字符用于URL (或者更一般的, URI)不同部分的分界符. 未保留字符没有这些特殊含义. 百分号编码把保留字符表示为特殊字符序列. 上述情形随URI与URI的不同版本规格会有轻微的变化。
部分转换规则如下:

空格 ! # $ % + @ : = ?
%20 %21 %23 %24 %25 %2B %40 %3A %3D %3F

(3)BCD码

       8421码是BCD代码中最常用的一种。在这种编码方式中每一位二值代码的1都是代表一个固定数值,把每一位的1代表的十进制数加起来,得到的结果就是它所代表的十进制数码。由于代码中从左到右每一位的1分别表示8,4,2,1,所以把这种代码叫做8421代码。每一位的1代表的十进制数称为这一位的权。8421码中的每一位的权是固定不变的,它属于恒权代码。

二、哈希摘要(Hash)

(1)MD5

       Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。
       MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。
       MD5算法具有以下特点:
       1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
       2、容易计算:从原数据计算出MD5值很容易。
       3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
       4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
       MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。

(2)SHA

       安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。该算法经过加密专家多年来的发展和改进已日益完善,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说是对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名。

(3)MD5与SHA1的区别

       因为二者均由MD4导出,SHA-1和MD5彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:
       1、对强行攻击的安全性:最显著和最重要的区别是SHA-1摘要比MD5摘要长32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD5是2^128数量级的操作,而对SHA-1则是2^160数量级的操作。这样,SHA-1对强行攻击有更大的强度。
       2、对密码分析的安全性:由于MD5的设计,易受密码分析的攻击,SHA-1显得不易受这样的攻击。
       3、速度:在相同的硬件上,SHA-1的运行速度比MD5慢。

(4)SHA-1停止计划

  2005年,密码学家就证明SHA-1的破解速度比预期提高了2000倍,虽然破解仍然是极其困难和昂贵的,但随着计算机变得越来越快和越来越廉价,SHA-1算法的安全性也逐年降低,已被密码学家严重质疑,希望由安全强度更高的SHA-2替代它。
微软第一个宣布了SHA-1弃用计划,对于SSL证书和代码签名证书,微软设定了不同的替换时间表:
  1、所有Windows受信任的根证书颁发机构(CA)从2016年1月1日起必须停止签发新的SHA-1签名算法SSL证书和代码签名证书;
  2、对于SSL证书,Windows将于2017年1月1日起停止支持SHA1证书。也就是说:任何在之前签发的SHA-1证书必须替换成SHA-2证书;
  3、对于代码签名证书,Windows将于2016年1月1日停止接受没有时间戳的SHA-1签名的代码和SHA-1证书。也就是说,Windows仍然接受在2016年1月1日之前使用SAH-1签名的已经加上RFC3161时间戳的代码,直到微软认为有可能出现SHA-1攻击时。
  Google官方博客宣布,将在Chrome浏览器中逐渐降低SHA-1证书的安全指示,逐步停止对使用SHA-1散列算法证书的支持。近日,Chrome 39新版本 PC 端发布,在部分操作系统下,该版本浏览器中已开始出现“该网站使用的安全设置已过期” 提示,在接下来的6个月内会变得越来越严格。最终,使用了有效期至2016年的SHA-1证书的站点可能会被给予黄色警告。
  Mozilla也做了同样的决定,在其对外公布近期更新计划中表示:“现在依然有不少网站使用基于 SHA-1签名的 SSL证书,所以我们决定加入微软和谷歌的阵营,认为应在 2016 年 1 月 1 日前停止发放 SHA-1 证书,在 2017 年 1 月1 日后不再信任此证书。”

三、代码实现(Base64 + MD5 + SHA)

//
//  main.m
//  CryptoDemo
//
//  Created by 555chy on 6/17/16.
//  Copyright © 2016 555chy. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
//#import <CommonCrypto/CommonCrypto.h>

#define G_KEY               @""
#define G_IV                @""
#define G_SECRET_KEY_LENGTH 24

//ios的base64编码有两种方式(使用ios7系统自带的编码库和GMTBase64两种方式),这里是用的是系统自带的方法
NSString* base64Encode(const char* originalCStr, NSInteger len) {
    NSData *originalData = [NSData dataWithBytes:originalCStr length:len];
    /*
     typedef NS_OPTIONS(NSUInteger, NSDataBase64EncodingOptions) {
     // Use zero or one of the following to control the maximum line length after which a line ending is inserted. No line endings are inserted by default.
     NSDataBase64Encoding64CharacterLineLength = 1UL << 0,
     NSDataBase64Encoding76CharacterLineLength = 1UL << 1,
     
     // Use zero or more of the following to specify which kind of line ending is inserted. The default line ending is CR LF.
     NSDataBase64EncodingEndLineWithCarriageReturn = 1UL << 4,
     NSDataBase64EncodingEndLineWithLineFeed = 1UL << 5,
     
     } NS_ENUM_AVAILABLE(10_9, 7_0);
     */
    NSData *base64Data = base64Data = [originalData base64EncodedDataWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    return [[NSString alloc] initWithData:base64Data encoding:NSUTF8StringEncoding];
}

NSString* base64Decode(NSString* encodedBase64Str) {
    NSData *base64Data = [[NSData alloc] initWithBase64EncodedString:encodedBase64Str options:NSDataBase64DecodingIgnoreUnknownCharacters];
    return [[NSString alloc] initWithData:base64Data encoding:NSUTF8StringEncoding];
}

//加密出啦的是一个32位的16进制序列
NSString* md5Hash(NSString* originalStr, BOOL is16Or32) {
    unsigned char md5CStr[CC_MD5_DIGEST_LENGTH];
    //const char *cOriginalStr = [originalStr cStringUsingEncoding:NSUTF8StringEncoding];
    const char *cOriginalStr = [originalStr UTF8String];
    CC_MD5(cOriginalStr, (CC_LONG)strlen(cOriginalStr), md5CStr);
    //NSMutableString *md5Str = [[NSMutableString alloc] init];
    NSMutableString *md5Str = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
    for(int i=0;i<CC_MD5_DIGEST_LENGTH;i++) {
        [md5Str appendFormat:@"%02x", md5CStr[i]];
    }
    if(is16Or32) {
        //return [[md5Str substringToIndex:24] substringFromIndex:8];
        return [[md5Str substringFromIndex:8] substringToIndex:16];
    }
    return md5Str;
}

//SHA
/*
 16进制序列位数    字节数       比特数
 CC_SHA1     40             20          160
 CC_SHA256   64             32          256
 CC_SHA384   96             48          384
 CC_SHA512  128             64          512
 */
NSString* shaHash(NSString* originalStr, unsigned char* (*CC_SHAX)(const void *data, CC_LONG len, unsigned char *md), unsigned int shaDigestLength) {
    unsigned char sha1CStr[shaDigestLength];
    //const char *cOriginalStr = [originalStr cStringUsingEncoding:NSUTF8StringEncoding];
    const char *cOriginalStr = [originalStr UTF8String];
    CC_SHAX(cOriginalStr, (CC_LONG)strlen(cOriginalStr), sha1CStr);
    //NSMutableString *sha1Str = [[NSMutableString alloc] init];
    NSMutableString *sha1Str = [NSMutableString stringWithCapacity:shaDigestLength*2];
    for(int i=0;i<shaDigestLength;i++) {
        [sha1Str appendFormat:@"%02x", sha1CStr[i]];
    }
    return sha1Str;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...

        NSString *originalStr = @"welcome to chy龙神的博客";
        //NSString *originalStr = @"欢迎光临JerryVon的博客";
        // const char* originalCstr = [originalStr cStringUsingEncoding:NSUTF8StringEncoding];
        const char *originalCstr = [originalStr UTF8String];
        NSString *base64EncodeStr = base64Encode(originalCstr, strlen(originalCstr));
        NSString *base64DecodeStr = base64Decode(base64EncodeStr);
        NSLog(@"originalStr = %@", originalStr);
        NSLog(@"base64EncodeStr = %@", base64EncodeStr);
        NSLog(@"base64DecodeStr = %@", base64DecodeStr);
        
        NSString *md5Hash16Str = md5Hash(originalStr, YES);
        NSString *md5Hash32Str = md5Hash(originalStr, NO);
        NSLog(@"md5Hash16Str = %@", md5Hash16Str);
        NSLog(@"md5Hash32Str = %@", md5Hash32Str);
        
        NSString *sha1HashStr = shaHash(originalStr, CC_SHA1, CC_SHA1_DIGEST_LENGTH);
        NSString *sha256HashStr = shaHash(originalStr, CC_SHA256, CC_SHA256_DIGEST_LENGTH);
        NSString *sha384HashStr = shaHash(originalStr, CC_SHA384, CC_SHA384_DIGEST_LENGTH);
        NSString *sha512HashStr = shaHash(originalStr, CC_SHA512, CC_SHA512_DIGEST_LENGTH);
        NSLog(@"sha1HashStr = %@", sha1HashStr);
        NSLog(@"sha25HashStr = %@", sha256HashStr);
        NSLog(@"sha384HashStr = %@", sha384HashStr);
        NSLog(@"sha512HashStr = %@", sha512HashStr);
    }
    return 0;
}

四、执行结果


五、第三方验证

(1)Base64在线验证的网站 http://www1.tc711.com/tool/BASE64.htm


(2)MD5在线验证网站 http://md5jiami.51240.com/


(3)Hash在线计算、md5计算、sha1计算、sha256计算、sha512计算


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值