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