【问题标题】:Java equivalent of Fantom HMAC using SHA1Java 等效于使用 SHA1 的 Fantom HMAC
【发布时间】:2011-07-13 21:11:22
【问题描述】:

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

// 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

【问题讨论】:

    标签: java hmac fantom


    【解决方案1】:

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

    您可以查看 sys::Buf.hmac 的 Java 源代码:MemBuf.java

    我还建议将这 3 个转换分开。确保您的原始字节数组在 Fantom 和 Java 中都匹配,然后验证摘要匹配,最后验证 Base64 编码。验证代码中的每个阶段要容易得多。

    【讨论】:

      【解决方案2】:

      事实证明,这只是我自己缺乏知识,经过足够的反复试验,我能够通过以下操作弄清楚:

      //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 对字节数组进行编码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-09
        • 2012-10-12
        • 1970-01-01
        • 2011-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多