代码之家  ›  专栏  ›  技术社区  ›  nathanVegetable

正在获取HmacSHA1 Java哈希以匹配Powershell哈希

  •  0
  • nathanVegetable  · 技术社区  · 6 年前

    $key = 'test'
    $bytes = [Text.Encoding]::UTF8.GetBytes($key)
    WRITE-HOST "bytes: " $bytes
    $hmacsha = new-object system.security.cryptography.HMACSHA1
    $hmacsha.key = $bytes
    $hash = $hmacsha.ComputeHash($bytes)
    WRITE-HOST "hash: " $hash
    

    结果是:

    bytes:  116 101 115 116
    hash:  12 148 81 92 21 229 9 91 138 135 165 11 160 223 59 243 142 208 95 230
    

    在Java中:

    String key = "test";
    byte[] bytes = key.getBytes("UTF-8");
    System.out.println("bytes: " + Arrays.toString(bytes));
    
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    byte[] keyBytes = md.digest(bytes);
    SecretKey sk = new SecretKeySpec(keyBytes, "HmacSHA1");
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(sk);
    byte[] hash = mac.doFinal(keyBytes);
    System.out.println("hash 1: " + Arrays.toString(hash));
    
    sk = new SecretKeySpec(bytes, "HmacSHA1");
    mac = Mac.getInstance("HmacSHA1");
    mac.init(sk);
    hash = mac.doFinal(bytes);
    System.out.println("hash 2: " + Arrays.toString(hash));
    

    输出:

    bytes: [116, 101, 115, 116]
    hash 1: [-112, -37, 64, 65, -91, -97, 36, 60, -80, -110, 62, -105, -63, -69, -79, -18, 29, -95, 23, -116]
    hash 2: [12, -108, 81, 92, 21, -27, 9, 91, -118, -121, -91, 11, -96, -33, 59, -13, -114, -48, 95, -26]
    

    我似乎无法使哈希值与Powershell的输出相匹配。在这两个示例中,我都创建了一个键为“test”的hmacsha1实例,然后得到“test”的散列值,但是这两个实例都有一些微小的差异,导致它们给出不同的结果。

    1 回复  |  直到 6 年前
        1
  •  1
  •   ArcSet    6 年前

    你不会得到两个不同的哈希值。事实上。。。

    12, -108, 81, 92, 21, -27, 9, 91, -118, -121, -91, 11, -96, -33, 59, -13, -114, -48, 95, -26
    

    与相同

    12 148 81 92 21 229 9 91 138 135 165 11 160 223 59 243 142 208 95 230
    

    在java中,当您使用字符串时,它正在对这些值进行签名。

    例如-108和148

    00000000,10010100 = 148
    11111111,10010100 = -108
    

    如果要使字节看起来无符号,可以将0xFF与字节结合使用。

    byte b = (byte) Integer.parseInt("148");
    System.out.println(b);
    

    输出: -108

    byte b = (byte) Integer.parseInt("148");
    System.out.println(b & 0xFF);
    

    148

    所以0xFF=255 aka 11111111并匹配公共位并保留它们。

    00000000,11111111 = 255 aka 0xFF
    11111111,10010100 = -108
    --------
    00000000,10010100 = 148