У меня возникли проблемы с успешной проверкой запроса на webhook от Trello. Вот что я знаю.Подтверждение подписки Trello Webhook
webhook документация Trello в here состояния:
Каждый триггер webhook содержит заголовок HTTP X-Trello-Webhook. Заголовок представляет собой дайджест base64 хеша HMAC-SHA1. Хешированный контент является конкатенацией тела полного запроса и callbackURL точно так же, как он был предоставлен во время создания веб-камеры. Ключ, используемый для подписи этого текста, является секретом вашего приложения.
Это понятно. Далее они говорят:
Из-за определенных значений по умолчанию в криптовых утилях в узле полезные значения, которые мы подписываем, рассматриваются как двоичные строки, а не utf-8. Например, если вы берете символ en-dash (U + 2013 или 8211 в десятичной форме) и создаете из него двоичный буфер в узле, он будет отображаться в виде буфера [19], которые являются 8 наименее значимыми бит 8211. Это значение, которое используется в дайджесте для вычисления SHA-1.
Это менее понятно для меня. Я понимаю, что каждый символ полезной нагрузки (body + callbackURL) был помещен в 8-битное целое число с игнорированием переполнения. (Потому что 8211 == 0b10000000010011 и 0b00010011 == 19) Вот где я думаю, что моя проблема.
Функции Я использую для размещения узла вопроса полезной нагрузки Trello является:
func bitShift(s string) []byte {
var byteString []byte
// For each rune in the string
for _, c := range s {
// Create a byte slice
b := []byte(string(c))
// Take the sign off the least significant byte
tmp := b[len(b)-1] << 1
tmp = tmp >> 1
// Append it to the byte string
byteString = append(byteString, tmp)
}
return byteString
}
Кроме того, очень возможно, что я делаю что-то неправильно с основной стадией проверки. Мне все хорошо, хотя я немного новичок в этом.
// VerifyNotificationHeader ...
func VerifyNotificationHeader(signedHeader, trelloAPISecret string, requestURL *url.URL, body []byte) bool {
// Put callbackURL and body into byte slice
urlBytes := bitShift(requestURL.String())
bitBody := bitShift(string(body))
// Sign, hash, and encode the payload
secret := []byte(trelloAPISecret)
keyHMAC := hmac.New(sha1.New, secret)
keyHMAC.Write(append(bitBody, urlBytes...))
signedHMAC := keyHMAC.Sum(nil)
base64signedHMAC := base64.StdEncoding.EncodeToString(signedHMAC)
if comp := strings.EqualFold(base64signedHMAC, signedHeader); !comp {
return false
}
return true
}
Сообщите мне, если вам нужна дополнительная информация. Спасибо!
Обновление: Это решение, ознакомьтесь с ответами.
У вас есть пример запроса и подписи, которые мы могли бы сопоставить? – JimB
Спасибо за интерес! Если я не получу эту работу на следующий день или два, я добавлю всю информацию, необходимую для проверки этих функций. На данный момент я неохотно создаю новую учетную запись Trello с единственной целью разделить секрет здесь. – doykle