Не сходится ответ эквивалентного кода на JavaScript и на Java

let data = {
  "apikey": "thisisyourapikey",
  "channel": "bibox_sub_spot_ALL_ALL_login",
  "event": "addChannel"
};
let secret = "thisisyourapisecret";
let sign = CryptoJS.HmacMD5(JSON.stringify(data), secret).toString();

console.log(sign)
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

Чем отличается этот код на JS от этого на Java? Почему я получаю разный хеш?

public class Test  {
    public static void main(String[] args) {
        System.out.println(sStringToHMACMD5(
            "{\n" +
            "  \"apikey\": \"thisisyourapikey\",\n" +
            "  \"channel\": \"bibox_sub_spot_ALL_ALL_login\",\n" +
            "  \"event\": \"addChannel\"\n" +
            "}",
            "thisisyourapisecret"));
    }

    public static String sStringToHMACMD5(String s, String keyString)
    {
        String sEncodedString = null;
        try
        {
            SecretKeySpec key = new SecretKeySpec((keyString).getBytes("UTF-8"), "HmacMD5");
            Mac mac = Mac.getInstance("HmacMD5");
            mac.init(key);

            byte[] bytes = mac.doFinal(s.getBytes("ASCII"));

            StringBuffer hash = new StringBuffer();

            for (int i=0; i<bytes.length; i++) {
                String hex = Integer.toHexString(0xFF &  bytes[i]);
                if (hex.length() == 1) {
                    hash.append('0');
                }
                hash.append(hex);
            }
            sEncodedString = hash.toString();
        }
        catch (UnsupportedEncodingException e) {}
        catch(InvalidKeyException e){}
        catch (NoSuchAlgorithmException e) {}
        return sEncodedString ;
    }
}

Правильный вариант ответа в случае с JS. Что не так с кодом на Java?


Ответы (1 шт):

Автор решения: Денис Степанов

Потому что вы в этом кусочке добавили несколько лишних символов в строку)
Вот у вас и получается результат разный.

"{\n" +
            "  \"apikey\": \"thisisyourapikey\",\n" +
              ^           ^                     ^^
            "  \"channel\": \"bibox_sub_spot_ALL_ALL_login\",\n" +
             ^             ^                                 ^^
            "  \"event\": \"addChannel\"\n" +
             ^          ^               ^^
            "}"

Вот так будет одинаковый.

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class Test  {
    public static void main(String[] args) {
        System.out.println(sStringToHMACMD5(
                "{\"apikey\":\"thisisyourapikey\"," +
                "\"channel\":\"bibox_sub_spot_ALL_ALL_login\"," +
                "\"event\":\"addChannel\"}",
                "thisisyourapisecret"));
    }

    public static String sStringToHMACMD5(String s, String keyString)
    {
        String sEncodedString = null;
        try
        {
            SecretKeySpec key = new SecretKeySpec((keyString).getBytes(StandardCharsets.UTF_8), "HmacMD5");
            Mac mac = Mac.getInstance("HmacMD5");
            mac.init(key);

            byte[] bytes = mac.doFinal(s.getBytes(StandardCharsets.US_ASCII));

            StringBuilder hash = new StringBuilder();

            for (byte aByte : bytes) {
                String hex = Integer.toHexString(0xFF & aByte);
                if (hex.length() == 1) {
                    hash.append('0');
                }
                hash.append(hex);
            }
            sEncodedString = hash.toString();
        }

        catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        }
        return sEncodedString ;
    }
}
→ Ссылка