2011-07-13 45 views
3

我在Java中执行以下操作时遇到问题。以下是我正在使用的工具的文档中的Fantom代码。Java相当于使用SHA1的Fantom HMAC

// compute salted hmac 
hmac := Buf().print("$username:$userSalt").hmac("SHA-1", password.toBuf).toBase64 

// now compute login digest using nonce 
digest := "${hmac}:${nonce}".toBuf.toDigest("SHA-1").toBase64 

// our example variables 
username: "jack" 
password: "pass" 
userSalt: "6s6Q5Rn0xZP0LPf89bNdv+65EmMUrTsey2fIhim/wKU=" 
nonce: "3da210bdb1163d0d41d3c516314cbd6e" 
hmac:  "IjJOApgvDoVDk9J6NiyWdktItl0=" 
digest: "t/nzXF3n0zzH4JhXtihT8FC1N3s=" 

我一直在通过Google搜索各种示例,但没有一个产生结果文档声明应该返回。

Fantom知识的人可以验证文档中的示例是否正确?

至于Java方面,这是我最近尝试

public static String hmacSha1(String value, String key) { 
    try { 
     // Get an hmac_sha1 key from the raw key bytes 
     byte[] keyBytes = key.getBytes("UTF-8");   
     SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1"); 

     // Get an hmac_sha1 Mac instance and initialize with the signing key 
     Mac mac = Mac.getInstance("HmacSHA1"); 
     mac.init(signingKey); 

     // Compute the hmac on input data bytes 
     byte[] rawHmac = mac.doFinal(value.getBytes("UTF-8")); 

     // Convert raw bytes to Hex 
     byte[] hexBytes = new Hex().encode(rawHmac); 

     // Covert array of Hex bytes to a String 
     return new String(hexBytes, "UTF-8"); 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
} 

然而,当我调用该方法具有以下参数

jack:6s6Q5Rn0xZP0LPf89bNdv+65EmMUrTsey2fIhim/wKU= 
pass 

我得到

22324e02982f0e854393d27a362c96764b48b65d 

回答

1

原来这只是我自己的知识的缺乏,并有足够的试验和错误,我能够做弄明白如下:

//username: "jack" 
//password: "pass" 
//userSalt: "6s6Q5Rn0xZP0LPf89bNdv+65EmMUrTsey2fIhim/wKU=" 
//nonce: "3da210bdb1163d0d41d3c516314cbd6e" 
//hmac:  "IjJOApgvDoVDk9J6NiyWdktItl0=" 
//digest: "t/nzXF3n0zzH4JhXtihT8FC1N3s=" 

... 
// initialize a Mac instance using a signing key from the password 
SecretKeySpec signingKey = new SecretKeySpec(password.getBytes(), "HmacSHA1"); 
Mac mac = Mac.getInstance("HmacSHA1"); 
mac.init(signingKey); 

// compute salted hmac 
byte[] hmacByteArray = mac.doFinal((username + ':' + userSalt).getBytes()); 
String hmacString = new String(Base64.encodeBase64(hmacByteArray)); 
// hmacString == hmac 

// now compute login digest using nonce 
MessageDigest md = MessageDigest.getInstance("SHA-1"); 
md.update((hmacString + ':' + nonce).getBytes()); 
byte[] digestByteArray = md.digest(); 
String digestString = new String(Base64.encodeBase64(digestByteArray)); 
// digestString == digest 

使用org.apache.commons.codec.binary。 Base64来编码字节数组。

2

不知道文档来自哪里 - 但它们可能已过时 - 或错误。我会实际运行魅影代码中使用作为您的参考,以确保您正在测试正确的东西;)

你可以看看Java源代码的SYS :: Buf.hmac:MemBuf.java

我也建议分离出3个转换。确保您的原始字节数组在Fantom和Java中都匹配,然后验证摘要匹配,最后进行Base64编码。更容易验证代码中的每个阶段。