سؤال

وأنا أبحث عن ما يعادل جافا لهذه الدعوة فب:

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

وحاولت هذه، وذلك باستخدام java.crypto.Mac ، ولكن اثنين لا توافق:

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 = "سرية" واختبار = "اختبار" لا يبدو أن المباراة.

هل كانت مفيدة؟

المحلول

في الحقيقة هم لا نوافق على ذلك.
كما أشار هانز Doggen بالفعل PHP النواتج خلاصة الرسالة باستخدام تدوين عشري إلا إذا قمت بتعيين معلمة إخراج الخام إلى true.
إذا كنت ترغب في استخدام نفس الرموز في جاوة يمكنك استخدام شيء من هذا القبيل

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

ولتنسيق الإخراج وفقا لذلك.

نصائح أخرى

ويمكنك أن تجرب هذا في جاوة:

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

وهذا هو تنفيذ بلدي:

        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;

ويبدو لي أن PHP يستخدم HEX تدوين لالبايتات التي تنتج جافا (1A = 26) - لكني لم تحقق التعبير كله

.

وماذا يحدث إذا قمت بتشغيل مجموعة بايت من خلال الأسلوب على هذا الصفحة؟

وتنفيذ بلادي HmacMD5 - مجرد تغيير خوارزمية لHmacSHA1:

SecretKeySpec keySpec = new SecretKeySpec("secretkey".getBytes(), "HmacMD5");
Mac mac = Mac.getInstance("HmacMD5");
mac.init(keySpec);
byte[] hashBytes = mac.doFinal("text2crypt".getBytes());
return Hex.encodeHexString(hashBytes);

ولم نجرب ذلك، ولكن حاول هذا:

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

وهذا هو لقطة من طريقتي التي تجعل جافا في MD5 و SHA1 مباراة بي.

وبهذه الطريقة أتمكن من الحصول على نفس السلسلة بالضبط كما كنت تحصل مع 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) {

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top