Проверка подписи полезной нагрузки в Go
Я проверяю личность отправителя части данных. Мне предоставлен открытый ключ RSA в формате PEM, и я знаю, что данные передаются через функцию хэширования SHA256. Эквивалентная проверка на платформе node.js:
Ticket.prototype.verify = function (ticket) {
if (!ticket) return null;
var pubkey = fs.readFileSync('/etc/SCAMP/auth/ticket_verify_public_key.pem');
var parts = ticket.split(',');
if (parts[0] != '1') return null;
var sig = new Buffer(parts.pop().replace(/-/g,'+').replace(/_/g,'/'), 'base64');
var valid = crypto.createVerify('sha256').update( new Buffer(parts.join(',')) ).verify( pubkey, sig )
Который может проверить:
1,3063,21,1438783424,660,1+20+31+32+34+35+36+37+38+39+40+41+42+43+44+46+47+48+50+53+56+59+60+61+62+67+68+69+70+71+75+76+80+81+82+86+87+88+102+104+105+107+109+110+122+124,PcFNyWjoz_iiVMgEe8I3IBfzSlUcqUGtsuN7536PTiBW7KDovIqCaSi_8nZWcj-j1dfbQRA8mftwYUWMhhZ4DD78-BH8MovNVucbmTmf2Wzbx9bsI-dmUADY5Q2ol4qDXG4YQJeyZ6f6F9s_1uxHTH456QcsfNxFWh18ygo5_DVmQQSXCHN7EXM5M-u2DSol9MSROeBolYnHZyE093LgQ2veWQREbrwg5Fcp2VZ6VqIC7yu6f_xYHEvU0-ZsSSRMAMUmhLNhmFM4KDjl8blVgC134z7XfCTDDjCDiynSL6b-D-
разделив на последний ,
, Левая сторона раскола - это данные о билетах, которые мне нужны, а справа - подпись, которую мне нужно проверить, прежде чем я смогу использовать данные о билетах.
Я попытался портировать логику, чтобы пойти:
func TestSigVerification(t *testing.T) {
block, _ := pem.Decode(signingPubKey)
if block == nil {
t.Errorf("expected to block to be non-nil CERTIFICATE", block)
}
key, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
t.Errorf("could not parse PKIXPublicKey: `%s`", key)
}
rsaPubKey, ok := key.(*rsa.PublicKey)
if !ok {
t.Errorf("couldn't cast to rsa.PublicKey!")
}
ticket,_ := ParseTicketBytes(fullTicketBytes)
h := sha256.New()
h.Write(ticketBytes)
digest := h.Sum(nil)
err = rsa.VerifyPKCS1v15(rsaPubKey, crypto.SHA256, digest, ticket.Signature)
if err != nil {
t.Errorf("could not verify ticket: `%s` (digest: `%v`)", err, digest )
}
}
Но я уверен VerifyPKCS1v15
не эквивалентен узлу crypto.createVerify
и этот тест не пройден. Что я должен использовать? Как я могу использовать открытый ключ, чтобы расшифровать подпись и получить sha256? как только я получу расшифрованное значение sha256, я смогу просто выполнить базовое сравнение с сгенерированным sha256.
Вот пример работающей детской площадки: http://play.golang.org/p/COx2OG-AiA
2 ответа
Я попытался запустить ваш код, и он не выглядит, как будто ваш билет правильно сформирован. Это не достаточно долго. Откуда вы взяли ценность?
Дважды проверьте этот билет - этого может быть достаточно, чтобы вы пошли.
Хотя я не мог заставить его работать, я подозреваю, что проблема в том, что вам нужно будет преобразовать sig из base64 в байты с помощью кодировки base64. Посмотрите этот пример здесь:
http://play.golang.org/p/bzpD7Pa9mr (особенно строки с 23 по 28, где они должны кодировать sig из байтов в строку base64, чтобы распечатать его, а затем передать версию байта в проверку sig, указывая, что у вас есть использовать байтовую версию, а не строку base64)
На что я наткнулся в этом посте: подписывание и декодирование с помощью RSA-SHA в GO
Я обнаружил, что golang обычно ожидает байты везде в байтовой кодировке. Я попытался декодировать вашу строку sig из base64 в байты, однако, даже после замены '-' на '+' и '_' на '/' он все равно не будет работать по неизвестным мне причинам:
http://play.golang.org/p/71IiV2z_t8
По крайней мере, это, кажется, указывает на то, что, возможно, ваш сигнал плохой? Если это не правильно base64? Я думаю, если вы можете найти способ решить эту проблему, все остальное должно работать!