84

HMAC-SHA256 アルゴリズムを使用して署名を作成しようとしていますが、これが私のコードです。US ASCII エンコーディングを使用しています。

final Charset asciiCs = Charset.forName("US-ASCII");
final Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
final SecretKeySpec secret_key = new javax.crypto.spec.SecretKeySpec(asciiCs.encode("key").array(), "HmacSHA256");
sha256_HMAC.init(secret_key);
final byte[] mac_data = sha256_HMAC.doFinal(asciiCs.encode("The quick brown fox jumps over the lazy dog").array());
String result = "";
for (final byte element : mac_data)
{
    result += Integer.toString((element & 0xff) + 0x100, 16).substring(1);
}
System.out.println("Result:[" + result + "]");

上記のコードから得られる結果は次のとおりです。

f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

これは、wikiに表示されているものと同じです

HMAC_SHA256("key", "The quick brown fox jumps over the lazy dog") = 0x f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

を除い0x

すべてを正しく行っているか、コードを改善できるかどうか、アイデア/コメントを探しています。

4

9 に答える 9

92

これが私の解決策です:

public static String encode(String key, String data) throws Exception {
  Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
  SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
  sha256_HMAC.init(secret_key);

  return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes("UTF-8")));
}

public static void main(String [] args) throws Exception {
  System.out.println(encode("key", "The quick brown fox jumps over the lazy dog"));
}

または、Base64でエンコードされたハッシュを返すことができます。

Base64.encodeBase64String(sha256_HMAC.doFinal(data.getBytes("UTF-8")));

16進数の出力は期待どおりです。

f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
于 2012-08-04T00:09:35.980 に答える
43

0xは、それ以降の文字が16進文字列を表すことを示しています。

0x1A == 1Ah == 26 == 1A

したがって、0xは、出力がどの形式であるかを明確にするためのものであり、心配する必要はありません。

于 2011-08-19T16:46:31.613 に答える
24

Guava を使用している場合は、その最新リリースで使用できるようになりました

 Hashing.hmacSha256()

これを使用する一例:

String hash = Hashing.hmacSha256("mykey".getBytes(StandardCharsets.UTF_8)).hashString("my_message", StandardCharsets.UTF_8).toString()

詳細なドキュメントはこちら: https://guava.dev/releases/23.0/api/docs/com/google/common/hash/Hashing.html#hmacSha256-byte:A-

于 2017-01-12T23:44:47.540 に答える
14

そこで出た答えが正解です。上記のコードの小さな点として、doFinal() を呼び出す前に init(key) が必要です。

    final Charset charSet = Charset.forName("US-ASCII");
    final Mac sha256_HMAC = Mac.getInstance("HmacSHA256");

    final SecretKeySpec secret_key = new javax.crypto.spec.SecretKeySpec(charSet.encode("key").array(), "HmacSHA256");
    try {
        sha256_HMAC.init(secret_key);
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    ...
于 2012-02-06T22:31:20.870 に答える
12

これは私にとってはうまくいっています

依存関係を追加しました

compile 'commons-codec:commons-codec:1.9'

参照: http://mvnrepository.com/artifact/commons-codec/commons-codec/1.9

私の機能

public String encode(String key, String data) {
    try {

        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        sha256_HMAC.init(secret_key);

        return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8)));

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    
    return null;
}
于 2016-03-14T07:54:07.203 に答える