HMAC-SHA256签名计算algorithm

我正在尝试使用HMAC-SHA256algorithm创build签名,这是我的代码。 我正在使用美国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"); 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 

这与维基中显示的相同

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

除了 0x

我正在寻找想法/评论,如果我做的一切正确或可能是我可以提高我的代码。

0x只是表示它后面的字符表示一个hexstring。

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

所以0x只是为了说明输出的格式,不用担心。

这是我的解决scheme:

 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"))); 

hex的输出如预期的那样:

 f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8 

你到那里的答案是正确的。 在上面的代码中的一个小问题,你需要先调用(key),然后才能调用doFinal()

  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(); } ... 

这对我来说工作得很好

我有添加依赖项

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

ref: http : //mvnrepository.com/artifact/commons-codec/commons-codec/1.9

我的function

 public String encode(String key, String data) { try { Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256"); sha256_HMAC.init(secret_key); return new String(Hex.encodeHex(sha256_HMAC.doFinal(data.getBytes("UTF-8")))); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } 

如果您正在使用Guava,现在可以使用它的最新版本

  Hashing.hmacSha256() 

这是我的解决scheme:

 public String HMAC_SHA256(String secret, String message) { String hash=""; try{ Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); hash = Base64.encodeToString(sha256_HMAC.doFinal(message.getBytes()), Base64.DEFAULT); }catch (Exception e) { } return hash.trim(); } 

如果可能的话,你find一个解决scheme如何在这里计算HMAC-SHA256,但你会得到这样一个例外:

java.lang.NoSuchMethodError:没有静态方法encodeHexString([B] Ljava / lang / String; 在类Lorg / apache / commons / codec / binary / Hex中; 或者它的超类(“org.apache.commons.codec.binary.Hex”声明出现在/system/framework/org.apache.http.legacy.boot.jar中)

然后使用:

 public static String encode(String key, String data) { try { Mac hmac = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256"); hmac.init(secret_key); return new String(Hex.encodeHex(hmac.doFinal(data.getBytes("UTF-8")))); } catch (Exception e) { throw new RuntimeException(e); } }