android 加密:Hmac消息认证作用

1 使用hash算法,能够保证消息没有内容的完整性,但是不能防止伪装者

例如:Alice给bob发送一个数据:希望bob想自己的合同中打款100万,hash值是100,但是中间窃听者窃听到了alic和bob的通信,得到了该hash值100,虽然窃听者虽然不能修改内容,因为修改了内容对应的hash值会发送变化。

但是窃听者存在伪造出一模一样的内容和hash值,例如窃听者可以伪造出一个数据内容 叫bob给窃听者的某个账号打款1000万,该内容的hash也是100,

窃听者将该数据发送给bob,bob收到数据之后计算hash值一计算hash值是正确的,就向窃听者的账号打款1000万人民币。


使用hmac消息认证能够避免上面的问题:

就是在Alice和bob之间首先共享一个key,使用key来计算出hash值,美元key是无法计算出hash值的,因为key只有在alic和bob之间拥有,而窃听者无法得到该key,就能够保证消息内容的本意没有被修改,就是发送者的本意,消息必须来自正确的发送者。








窃听者是因为没有知道alice和bob之间的共享密钥的,所以无法就算出hash值,并且哪怕消息中的任何一点内容发送了变化,hash值也会发送变化。


所以使用hmac算法。保证了消息来自正确的发送者,消息的内容的本意没有被修改,窃听者无法伪造出叫bob银行给自己打卡1000万的内容,因为窃听者没有共享的key。


但是hmac算法存在一个问题,无法防止重放攻击,虽然窃听者没有key修改内容一次性叫bob打款1000万人民币,但是可以采用下面的方式获得1000万:

alice和bob拥有贡献的key,窃听者窃听alice和bob的通信

第一步:窃听者是一个用户,到alice银行填写一个转账申请,要求bob银行转账到100万到窃听者的账户。

第二步:窃听者将窃取到的消息保存起来。

第三步: BOB收到消息之后使用共享的key进行验证发现内容没有发生变化,向窃听者打款100万。

第四步:窃听者可以继续将窃听到的内容发送给bob,bob收到内容之后使用key验证消息的内容,内容正确,又给窃听者打款100万,窃听者这样就会使用这种方法能够不断的收到钱

无法抵制重放攻击

所以hmac算法无法证明消息的内容一定来自alice,该消息有可能来自窃听者。

即使没有窃听者,也不能一定说明该消息是alice发出的,alice可以说:bob收到的消息可能是bob自己伪造的,因为共享的key除了alice知道,bob也知道bob可以利用key自己给自己发数据,无法保证消息一定来自alice,要解决这个情况,可以使用数字签名,使用了数字签名就一定能够证明消息来自alice。


hmac在java中的代码如下:

1、代码类型

It is mostly Java code but there are some slight differences. Adapted from Dev Takeout - Groovy HMAC/SHA256 representation.

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;

def hmac_sha256(String secretKey, String data) {
 try {
    Mac mac = Mac.getInstance("HmacSHA256")
    SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256")
    mac.init(secretKeySpec)
    byte[] digest = mac.doFinal(data.getBytes())
    return digest
   } catch (InvalidKeyException e) {
    throw new RuntimeException("Invalid key exception while converting to HMac SHA256")
  }
}

def hash = hmac_sha256("secret", "Message")
encodedData = hash.encodeBase64().toString()
log.info(encodedData)


上面的secretKey就是客户端和发送端都知道的。下面这种是自己产生一个sercreKey



3、hmac和普通散列函数sha1、md5的区别

“HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。”

可以看出,HMAC是需要一个密钥的。所以,HMAC_SHA1也是需要一个密钥的,而SHA1不需要。

以下是两种算法在Java中的实现:

如下方法是使用sha1计算一个文件的摘要,不需要密钥,有点类似于md5,注意这句:

下面是对一个文件进行sha1摘要的计算

	public static String sha1Digest(String filename) {
		InputStream fis = null;
		byte[] buffer = new byte[Constants.BUFFER_SIZE];
		int numRead = 0;
		MessageDigest sha1;
		try {
			fis = new FileInputStream(filename);
			sha1 = MessageDigest.getInstance("SHA-1");
			while ((numRead = fis.read(buffer)) > 0) {
				sha1.update(buffer, 0, numRead);
			}
			return toHexString(sha1.digest());
		} catch (Exception e) {
			System.out.println("error");
			return null;
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
4、使用场景

摘要算法的使用场景:常用于下载文件完整性的认证

Hmac算法的场景:常用于客户端和服务器身份的认证

HMAC的一个典型应用是用在“挑战/响应”(Challenge/Response)身份认证中,认证流程如下:

(1) 先由客户端向服务器发出一个验证请求。 

(2) 服务器接到此请求后生成一个随机数并通过网络传输给客户端(此为挑战)。 

(3) 客户端将收到的随机数提供给ePass,由ePass使用该随机数与存储在ePass中的密钥进行HMAC-MD5运算并得到一个结果作为认证证据传给服务器(此为响应)。 

(4) 与此同时,服务器也使用该随机数与存储在服务器数据库中的该客户密钥进行HMAC-MD5运算,如果服务器的运算结果与客户端传回的响应结果相同,则认为客户端是一个合法用户 。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值