HMAC 是在MD5、SHA1、SHA256等的基础上发展,加入key进行计算摘要。摘要的算法是散列
摘要的长度对于一个算法来说是固定的
对于我们平常编程来说,摘要是唯一的,只要数据不一样摘要就会不一样
理论上摘要的散列算法会发生散列碰撞,即两个数据的摘要是一样的,可以想一下,既然摘要有一个固定长度,那么它就会有一个表示的最大数据量,但是数据是无限的(比如数字1到∞)。所以摘要一定会发生散列碰撞。(在我们应用摘要的时候,散列碰撞忽略就可以)
我们的应用中用到的摘要是用于验签,即验证服务器返回的数据是否被修改,当然我们加入了RSA和AES加密保证数据不会轻易被解开
之前的摘要有用于登录的过程,HAMC也有用于该过程的,HMAC用于登录可以实现类似设备锁的功能。
之前说过HMAC需要一个KEY,这个KEY在注册的时候分配给用户,用户存储到本地(当然需要本地做一些处理,防止被其他人获取到),以后无特殊情况不会变动。
当用户登录的时候,检查本地是否存在KEY,如果存在直接发起登录,否则向服务器请求KEY。
PS:用户向服务器请求KEY,服务器不一定就要给,服务器要先确定该账号是否开启设备锁,如果开启,向原始设备发送授权请求,否则直接返回KEY。
当拿到KEY的时候登录
这是设备锁的简单流程,当然还需要做一些其他的操作来保证安全问题。例如本地存储的加密、传输通道的加密等。
好了,大体介绍就完成了,现在来看一下HMAC的代码
HMAC使用iOS系统提供的HMAC算法
void CCHmac(
CCHmacAlgorithm algorithm, /* kCCHmacAlgSHA1, kCCHmacAlgMD5 */
const void *key,
size_t keyLength, /* length of key in bytes */
const void *data,
size_t dataLength, /* length of data in bytes */
void *macOut) /* MAC written here */
__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);
几种不同的HMAC算法只有参数 algorithm 不同,其它都差不多
例如HMACMD5的
+ (NSString *)LJHMACMD5:(NSString *)data key:(NSString *)key { NSData *datas = [data dataUsingEncoding:NSUTF8StringEncoding]; size_t dataLength = datas.length; NSData *keys = [key dataUsingEncoding:NSUTF8StringEncoding]; size_t keyLength = keys.length; unsigned char result[CC_MD5_DIGEST_LENGTH]; CCHmac(kCCHmacAlgMD5, [keys bytes], keyLength, [datas bytes], dataLength, result); for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i ++) { printf("%d ",result[i]); } printf("\n-------%s-------\n",result); //这里需要将result 转base64编码,再传回去 //为了简单这里没有做 NSString *base64 = [NSString stringWithUTF8String:result]; //因为没做base64编码,所以result转NSString 转换失败,是NULL return base64; }
HMACSHA1的
+ (NSString *)LJHMACSHA1:(NSString *)data key:(NSString *)key { NSData *datas = [data dataUsingEncoding:NSUTF8StringEncoding]; size_t dataLength = datas.length; NSData *keys = [key dataUsingEncoding:NSUTF8StringEncoding]; size_t keyLength = keys.length; unsigned char result[CC_SHA1_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA1, [keys bytes], keyLength, [datas bytes], dataLength, result); for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i ++) { printf("%d ",result[i]); } printf("\n-------%s-------\n",result); //这里需要将result 转base64编码,再传回去 //为了简单这里没有做 NSString *base64 = [NSString stringWithUTF8String:result]; //因为没做base64编码,所以result转NSString 转换失败,是NULL return base64; }
都差不多,系统帮我们实现了内部的算法,系统的算法还有很多,如DES、AES等。
最后附上一个demo,demo地址
http://download.csdn.net/download/u0/
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225016.html原文链接:https://javaforall.net
