hmac



算法:

HMAC 需要一个加密用散列函数(表示为 H)和一个密钥 K。我们假设 H 是 一个将数据块用一个基本的迭代压缩函数来加密的散列函数。我们用 B 来表示数据块的字长。(以上提到的散列函数的分割数据块字长 B = 64),用 L 来表示散列函数的输出数据字长(MD5中 L = 16 , SHA-1 中 L = 20)。鉴别密钥的长度可以是小于等于数据块字长的任何正整数值。应用程序中使用的密钥长度若是比 B 大,则首先用使用散列函数 H 作用于它,然后用 H 输出的 L 长度字符串作为在 HMAC 中实际使用的密钥。一般情况下,推荐的最小密钥 K 长度是 L 个字长。(与 H 的输出数据长度相等)。

我们将定义两个固定且不同的字符串 ipad,opad:(‘i’,‘o’表示内部与外部) 

ipad = the byte 0x36 repeated B times
opad = the byte 0x5C repeated B times

计算‘text’的 HMAC:

H (K XOR opad, H (K XOR ipad, text))

计算步骤:

在密钥 K 后面添加 0 来创建一个子长为 B 的字符串。(例如,如果 K 的字长是 20 字节,B=60 字节,则 K 后会加入 44 个零字节0x00)
将上一步生成的 B 字长的字符串与 ipad 做异或运算
将数据流 text 填充至第二步的结果字符串中
用 H 作用于第三步生成的数据流
将第一步生成的 B 字长字符串与 opad 做异或运算
再将第四步的结果填充进第五步的结果中
用 H 作用于第六步生成的数据流,输出最终结果

实现:基于MD5散列函数的hamc

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class HMac {
    private static int B = 64;
    static {
        try {
            B = MessageDigest.getInstance("md5").getDigestLength();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static byte[] HmacMD5(byte[] data, byte[] key) {
        if (key.length > B) {
            key = md5(key);
        }
        if (key.length < B) {
            byte[] newKey = new byte[64];
            for (int i = 0; i < B; i++) {
                if (i < key.length) {
                    newKey[i] = key[i];
                } else {
                    newKey[i] = 0x00;
                }
            }
            key = newKey;
        }
        byte[] ipad = new byte[B];
        byte[] opad = new byte[B];
        for (int i = 0; i < B; i++) {
            ipad[i] = 0x36;
            opad[i] = 0x5C;
        }
        // H (K XOR opad, H (K XOR ipad, text))
        byte[] K = new byte[B + data.length];
        for (int i = 0; i < B; i++) {
            K[i] = (byte) (key[i] ^ ipad[i]);
        }
        System.arraycopy(data, 0, K, B, data.length);//K = concat(k,data)
        data = md5(K);
        K = new byte[B + data.length];
        for (int i = 0; i < B; i++) {
            K[i] = (byte) (key[i] ^ opad[i]);
        }
        System.arraycopy(data, 0, K, B, data.length);//K = concat(k,data)
        return md5(K);
    }

    public static byte[] md5(byte[] data) {
        try {
            return MessageDigest.getInstance("md5").digest(data);
        } catch (final NoSuchAlgorithmException e) {
            throw new IllegalArgumentException(e);
        }
    }

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值