前段时间有个网友问是否有Swift的HMAC_SHA1算法。这次就专门写篇相关文章进行介绍。要说明HMAC-SHA1,首先要先了解什么是HMAC,什么是SHA。

1,HMAC(散列消息身份验证码:Hashed Message Authentication Code)
它不是散列函数,而是采用了将MD5或SHA1散列函数与共享机密密钥(与公钥/私钥对不同)一起使用的消息身份验证机制。基本来说,消息与密钥组合并运行散列函数。然后运行结果与密钥组合并再次运行散列函数。这个128位的结果被截断成96位,成为MAC。
hmac主要应用在身份验证中,它的使用方法是这样的:
1. 客户端发出登录请求(假设是浏览器的GET请求)
2. 服务器返回一个随机值,并在会话中记录这个随机值
3. 客户端将该随机值作为密钥,用户密码进行hmac运算,然后提交给服务器
4. 服务器读取用户数据库中的用户密码和步骤2中发送的随机值做与客户端一样的hmac运算,然后与用户发送的结果比较,如果结果一致则验证用户合法
在这个过程中,可能遭到安全攻击的是服务器发送的随机值和用户发送的hmac结果,而对于截获了这两个值的黑客而言这两个值是没有意义的,绝无
获取用户密码的可能性,随机值的引入使hmac只在当前会话中有效,大大增强了安全性和实用性。大多数的语言都实现了hmac算法,比如php的
mhash、python的hmac.py、java的MessageDigest类,在web验证中使用hmac也是可行的,用js进行md5运算的速
度也是比较快的。
2,SHA(安全散列算法:Secure Hash Algorithm)
这个是美国国家标准和技术局发布的国家标准FIPS PUB 180-1,一般称为SHA-1。其对长度不超过264二进制位的消息产生160位的消息摘要输出,按512比特块处理其输入。
SHA是一种数据加密算法,该算法经过加密专家多年来的发展和改进已日益完善,现在已成为公认的最安全的散列算法之一,并被广泛使用。该算法的
思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度
较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说时对明文的一种“指纹”或是“摘要”所以对散列值的数字签名
就可以视为对此明文的数字签名。
3,HMAC_SHA1(Hashed Message Authentication Code, Secure Hash Algorithm)
这是一种安全的基于加密hash函数和共享密钥的消息认证协议。它可以有效地防止数据在传输过程中被截获和篡改,维护了数据的完整性、可靠性和安全性。HMAC_SHA1消息认证机制的成功在于一个加密的hash函数、一个加密的随机密钥和一个安全的密钥交换机制。
HMAC_SHA1算法在身份验证和数据完整性方面可以得到很好的应用,在目前网络安全也得到较好的实现。
4,下面演示如何使用Swift进行HMAC_SHA1计算
(1)首先创建桥接头文件bridge.h来包含需要引用的Objective-C头文件,并在项目中配置
1
#import <CommonCrypto/CommonHMAC.h>

(2)下面是一个封装类,同时对String进行HMAC扩展。(除了SHA1,还可以使用其它算法比如MD5,SHA224等)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//HMAC.swift
import Foundation
enum CryptoAlgorithm {
    case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
     
    var HMACAlgorithm: CCHmacAlgorithm {
        var result: Int = 0
        switch self {
        case .MD5:      result = kCCHmacAlgMD5
        case .SHA1:     result = kCCHmacAlgSHA1
        case .SHA224:   result = kCCHmacAlgSHA224
        case .SHA256:   result = kCCHmacAlgSHA256
        case .SHA384:   result = kCCHmacAlgSHA384
        case .SHA512:   result = kCCHmacAlgSHA512
        }
        return CCHmacAlgorithm(result)
    }
     
    var digestLength: Int {
        var result: Int32 = 0
        switch self {
        case .MD5:      result = CC_MD5_DIGEST_LENGTH
        case .SHA1:     result = CC_SHA1_DIGEST_LENGTH
        case .SHA224:   result = CC_SHA224_DIGEST_LENGTH
        case .SHA256:   result = CC_SHA256_DIGEST_LENGTH
        case .SHA384:   result = CC_SHA384_DIGEST_LENGTH
        case .SHA512:   result = CC_SHA512_DIGEST_LENGTH
        }
        return Int(result)
    }
}
 
extension String {
    func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
        let str = self.cStringUsingEncoding(NSUTF8StringEncoding)
        let strLen = Int(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
        let digestLen = algorithm.digestLength
        let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
        let keyStr = key.cStringUsingEncoding(NSUTF8StringEncoding)
        let keyLen = Int(key.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
         
        CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)
         
        let digest = stringFromResult(result, length: digestLen)
         
        result.dealloc(digestLen)
         
        return digest
    }
     
    private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String {
        let hash = NSMutableString()
        for i in 0..<length {
            hash.appendFormat("%02x", result[i])
        }
        return String(hash)
    }
}

(3)测试样例

1
2
3
4
5
6
7
8
9
10
11
12
13
let str = "welcome to hangge.com"
let key = "67FG"
let hmacStr = str.hmac(.SHA1, key: key)
         
print("原始字符串:\(str)")
print("key:\(key)")
print("HMAC运算结果:\(hmacStr)")
         
/**** 输出 ******
原始字符串:welcome to hangge.com
key:67FG
HMAC运算结果:79a5f5b138b5646289a9648de035c80e9c5c14c7
*****/

原文出自:www.hangge.com  转载请保留原文链接:http://www.hangge.com/blog/cache/detail_851.html

Swift - 如何实现字符串的HMAC_SHA1加密的更多相关文章

  1. Swift字符与字符串

    学习来自<极客学院:Swift中的字符串和集合> 工具:Xcode6.4 直接上基础的示例代码,多敲多体会就会有收获:百看不如一敲,一敲就会 import Foundation /**** ...

  2. WP开发笔记——字符串 转 MD5 加密

    将字符串进行MD5加密,返回加密后的字符串. 从这里下载Md5.cs文件:http://pan.baidu.com/s/1hq3gpnu. 添加到Windows Phone 7项目中,在代码里面这样调 ...

  3. 李洪强iOS开发Swift篇—03_字符串和数据类型

    李洪强iOS开发Swift篇—03_字符串和数据类型 一.字符串 字符串是String类型的数据,用双引号""包住文字内容  let website = "http:// ...

  4. Linux下对字符串进行MD5加密

    Linux下对字符串进行MD5加密 比如要用MD5在linux下加密字符串“test",可以使用命令:$ echo -n test|md5sum098f6bcd4621d373cade4e8 ...

  5. Android初级教程:对文件和字符串进行MD5加密工具类

    转载请注明出处:http://blog.csdn.net/qq_32059827/article/details/52200008   点击打开链接 之前写过一篇博文,是针对字符串进行md5加密的.今 ...

  6. 在loadrunner中用头文件的形式对字符串进行MD5加密操作

    1.首先要有md5.h的头文件 2.然后在global.h中加入#include "md5.h" 3.在action中调用md5.h中的Change_to_Md5(const ch ...

  7. 将字符串进行md5加密

    import java.security.MessageDigest; public class MD5Tools { /** * 将字符串进行md5加密 */ public static Strin ...

  8. 把字典的key value 拼接成字符串加上签名加密

    - (NSString *)getSianKeyWithDic:(NSDictionary *)dic { //按字典排序 NSArray* arr = [dic allKeys]; arr = [a ...

  9. Swift入门篇-字符串和字符

    今天主要是介绍一下字符串的用法 ,字符串的语法和object-c语法不太一样,但是思想是一样,就是写法不太一样.如果您对.net和java语法比较熟悉的话,那您几乎没有深压力.如果您对swift 基本 ...

随机推荐

  1. Spring配置文件模板

    模板: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://ww ...

  2. 我的Python成长之路---第六天---Python基础(20)---2016年2月20日(晴)

    一.面向对象基础 面向对象名词解释: 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公 ...

  3. 转: css实现垂直居中的方法

    利用 CSS 来实现对象的垂直居中有许多不同的方法,比较难的是选择那个正确的方法.我下面说明一下我看到的好的方法和怎么来创建一个好的居中网站. 用 CSS 实现垂直居中并不容易.有些方法在一些浏览器中 ...

  4. STL string 模拟

    下面的代码来自c++ primer plus第5版第12章,书中代码写的非常好: // string1.h -- fixed and augmented string class definition ...

  5. 17.2?Replication Implementation 复制实施:

    17.2?Replication Implementation 复制实施: 17.2.1 Replication Implementation Details 17.2.2 Replication R ...

  6. 九、cocos2dx之Actions

    本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=86 Action是CCNode对象的一种顺序.这些动作经常改变对象的一些属性,比如位置,旋转,缩放等 ...

  7. BNU Invading system

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=29364 这个题被坑了. 题意:密码就是那些数字里面的数,转换成二进制后1最少的那个数,当1的个数相同 ...

  8. JSON XML IO数据操作

    一.XML解析 通过继承org.xml.sax.helpers.DefaultHandler类,覆写characters(),startDocument(),startElement(),endEle ...

  9. if语句求三个数中最大的

    Console.WriteLine("请输入第一个数:"); int a = Convert.ToInt32( Console.ReadLine()); Console.Write ...

  10. java字符串输出

    package mytest; public class Mycode { public static void main(String[] args){ String[]seasons = {&qu ...