Функция ecdsa.Verify
Функция ecdsa.Verify проверяет, является ли цифровая
подпись действительной для указанного хеша с использованием
открытого ключа. В первый параметр передается указатель на
структуру ecdsa.PublicKey, содержащую открытый ключ.
Во второй параметр передается хеш сообщения в виде среза байт.
В третий и четвертый параметры передаются компоненты подписи
r и s в виде срезов байт. Функция возвращает
true, если подпись действительна, и false
в противном случае.
Синтаксис
ecdsa.Verify(pub *ecdsa.PublicKey, hash []byte, r []byte, s []byte) bool
Пример
Создадим пару ключей ECDSA на кривой P-256 и проверим подпись для сообщения:
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"fmt"
"math/big"
)
func main() {
// Генерируем ключи
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(err)
}
publicKey := &privateKey.PublicKey
// Сообщение и хеш
msg := []byte("hello")
hash := sha256.Sum256(msg)
// Подписываем сообщение
r, s, err := ecdsa.Sign(rand.Reader, privateKey, hash[:])
if err != nil {
panic(err)
}
// Проверяем подпись
res := ecdsa.Verify(publicKey, hash[:], r.Bytes(), s.Bytes())
fmt.Println(res)
}
Результат выполнения кода:
true
Пример
Проверим подпись с измененными данными. Подпись становится недействительной, если изменить хотя бы один байт сообщения:
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"fmt"
)
func main() {
// Генерируем ключи
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(err)
}
publicKey := &privateKey.PublicKey
// Оригинальное сообщение
msg := []byte("hello")
hash := sha256.Sum256(msg)
// Подписываем оригинальное сообщение
r, s, err := ecdsa.Sign(rand.Reader, privateKey, hash[:])
if err != nil {
panic(err)
}
// Изменяем сообщение
msg2 := []byte("hellox")
hash2 := sha256.Sum256(msg2)
// Проверяем подпись с измененным хешем
res := ecdsa.Verify(publicKey, hash2[:], r.Bytes(), s.Bytes())
fmt.Println(res)
}
Результат выполнения кода:
false
Пример
Верификация подписи с использованием компонент r и
s в формате ASN.1. Функция ecdsa.Verify
работает с байтовыми срезами, а не со структурами:
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"encoding/asn1"
"fmt"
)
type Signature struct {
R, S *big.Int
}
func main() {
// Генерируем ключи
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(err)
}
publicKey := &privateKey.PublicKey
// Сообщение и хеш
msg := []byte("hello")
hash := sha256.Sum256(msg)
// Подписываем и получаем ASN.1 подпись
signatureASN1, err := ecdsa.SignASN1(rand.Reader, privateKey, hash[:])
if err != nil {
panic(err)
}
// Декодируем ASN.1 для получения r и s
var sig Signature
_, err = asn1.Unmarshal(signatureASN1, &sig)
if err != nil {
panic(err)
}
// Проверяем подпись
res := ecdsa.Verify(publicKey, hash[:], sig.R.Bytes(), sig.S.Bytes())
fmt.Println(res)
}
Результат выполнения кода:
true
Смотрите также
-
функцию
ecdsa.Sign,
которая создает цифровую подпись ECDSA -
функцию
ecdsa.GenerateKey,
которая генерирует пару ключей ECDSA -
функцию
ecdsa.VerifyASN1,
которая проверяет подпись в формате ASN.1 -
пакет
crypto/elliptic,
который предоставляет кривые для ECDSA