51

このphp呼び出しに相当するJavaを探しています:

hash_hmac('sha1', "test", "secret")

java.crypto.Macを使用してこれを試しましたが、2つが一致しません。

String mykey = "secret";
String test = "test";
try {
    Mac mac = Mac.getInstance("HmacSHA1");
    SecretKeySpec secret = new SecretKeySpec(mykey.getBytes(),"HmacSHA1");
    mac.init(secret);
    byte[] digest = mac.doFinal(test.getBytes());
    String enc = new String(digest);
    System.out.println(enc);  
} catch (Exception e) {
    System.out.println(e.getMessage());
}

key = "secret" と test = "test" の出力が一致していないようです。

4

7 に答える 7

41

実際、彼らは同意します。
Hans Doggen が既に述べたように、raw 出力パラメーターを true に設定しない限り、PHP は 16 進数表記を使用してメッセージ ダイジェストを出力します。
Javaで同じ表記法を使用したい場合は、次のようなものを使用できます

for (byte b : digest) {
    System.out.format("%02x", b);
}
System.out.println();

それに応じて出力をフォーマットします。

于 2009-10-22T22:28:15.637 に答える
20

これはJavaで試すことができます。

private static String computeSignature(String baseString, String keyString) throws GeneralSecurityException, UnsupportedEncodingException {

    SecretKey secretKey = null;

    byte[] keyBytes = keyString.getBytes();
    secretKey = new SecretKeySpec(keyBytes, "HmacSHA1");

    Mac mac = Mac.getInstance("HmacSHA1");

    mac.init(secretKey);

    byte[] text = baseString.getBytes();

    return new String(Base64.encodeBase64(mac.doFinal(text))).trim();
}
于 2011-05-25T12:04:26.700 に答える
5

これは私の実装です:

        String hmac = "";

    Mac mac = Mac.getInstance("HmacSHA1");
    SecretKeySpec secret = new SecretKeySpec(llave.getBytes(), "HmacSHA1");
    mac.init(secret);
    byte[] digest = mac.doFinal(cadena.getBytes());
    BigInteger hash = new BigInteger(1, digest);
    hmac = hash.toString(16);

    if (hmac.length() % 2 != 0) {
        hmac = "0" + hmac;
    }

    return hmac;
于 2011-05-11T18:40:21.527 に答える
3

PHPはJavaが生成するバイト(1a = 26)にHEX表記を使用しているように見えますが、式全体をチェックしていません。

このページのメソッドでバイト配列を実行するとどうなりますか?

于 2009-10-22T21:18:00.070 に答える
3

このようにして、php で hash_hmac を使用して取得したのとまったく同じ文字列を取得できました。

String result;

try {
        String data = "mydata";
        String key = "myKey";
        // Get an hmac_sha1 key from the raw key bytes
        byte[] keyBytes = key.getBytes();
        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(data.getBytes());

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

        //  Covert array of Hex bytes to a String
        result = new String(hexBytes, "ISO-8859-1");
        out.println("MAC : " + result);
}
catch (Exception e) {

}
于 2014-10-10T10:06:26.380 に答える
1

テストしていませんが、これを試してください:

        BigInteger hash = new BigInteger(1, digest);
        String enc = hash.toString(16);
        if ((enc.length() % 2) != 0) {
            enc = "0" + enc;
        }

これは、Java の md5 と sha1 を php に一致させる私の方法のスナップショットです。

于 2009-10-22T21:22:39.007 に答える