Разница в подписи HMAC между python и java

Я пытаюсь взять некоторый рабочий код Python и преобразовать его в java для своего использования. Приведенный ниже код Python создает правильную подпись. Код Java, использующий тот же ключ, соль, создает что-то другое, и я не понимаю, почему. В коде Java я использую ключ, сгенерированный в python (_key), для создания подписи.

Чего я не понимаю, так это того, что если я напечатаю значение _key в python, я получу «34ee7983-5ee6-4147-aa86-443ea062abf774493d6a-2a15-43fe-aace-e78566927585». Теперь, если я возьму это и помещу прямо в вызов hmac(new), я получу другой результат, чем если бы я просто оставил переменную _key. Я предполагаю, что это как-то связано с кодированием какого-то типа, но я в недоумении.

_s1 = base64.b64decode('VzeC4H4h+T2f0VI180nVX8x+Mb5HiTtGnKgH52Otj8ZCGDz9jRW'
                       'yHb6QXK0JskSiOgzQfwTY5xgLLSdUSreaLVMsVVWfxfa8Rw==')
_s2 = base64.b64decode('ZAPnhUkYwQ6y5DdQxWThbvhJHN8msQ1rqJw0ggKdufQjelrKuiG'
                       'GJI30aswkgCWTDyHkTGK9ynlqTkJ5L4CiGGUabGeo8M6JTQ==')

# bitwise and of _s1 and _s2 ascii, converted to string
_key = ''.join([chr(ord(c1) ^ ord(c2)) for (c1, c2) in zip(_s1, _s2)])

@classmethod
def get_signature(cls, song_id, salt=None):
    """Return a (sig, salt) pair for url signing."""

    if salt is None:
        salt = str(int(time.time() * 1000))

    mac = hmac.new(cls._key, song_id, sha1)
    mac.update(salt)
    sig = base64.urlsafe_b64encode(mac.digest())[:-1]

    return sig, salt

Это мой Java-код. Я думаю, что в конечном итоге моя проблема заключается в том, как я обрабатываю или кодирую AA_KEY, но я не могу понять это.

private static final String AA_KEY = "34ee7983-5ee6-4147-aa86-443ea062abf774493d6a-2a15-43fe-aace-e78566927585";

public void someFunc(String songId) {

  salt = "1431875768596"
  String sig = hmacSha1(songId + salt, AA_KEY);
  sig =  StringUtils.replaceChars(sig, "+/=", "-_.");
}

static String hmacSha1(String value, String key) {
    try {
        // 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(value.getBytes());

        return Base64.encodeBytes(rawHmac);

    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

Я нашел пару похожих вопросов, но они не помогли мне понять это, к сожалению. Спасибо!

Подпись Python HMAC-SHA256 отличается от подписи PHP

Python HMAC-SHA1 и Java HMAC-SHA1 отличаются результаты


person Nate Schwartz    schedule 18.05.2015    source источник
comment
Так что я действительно понял это, наконец. Я действительно этого не понимаю, но я заметил, что когда я печатал ключ в python, он всегда добавлял новую строку. Поэтому я просто добавил \n в конце ключа в Java, и вдруг все заработало. Не знаю, почему появился этот новый символ строки, но рад, что он наконец-то работает!   -  person Nate Schwartz    schedule 18.05.2015