Функция ecdsa.SignASN1
Функция ecdsa.SignASN1 создает цифровую подпись для указанного хеша с использованием алгоритма ECDSA (Elliptic Curve Digital Signature Algorithm). В первый параметр передается приватный ключ *ecdsa.PrivateKey, во второй параметр передается хеш сообщения в виде среза байтов, который должен быть подписан. Функция возвращает два значения: сигнатуру в формате ASN.1 DER (срез байтов) и ошибку, если она возникла.
В отличие от функции ecdsa.Sign, которая возвращает пару r и s как отдельные большие числа, функция SignASN1 сразу возвращает готовую сигнатуру в стандартизированном формате ASN.1, который удобен для хранения, передачи и проверки с помощью функции ecdsa.VerifyASN1.
Синтаксис
ecdsa.SignASN1(priv *ecdsa.PrivateKey, hash []byte) (signature []byte, err error)
Пример
Давайте создадим приватный ключ и подпишем хеш сообщения с использованием алгоритма SHA-256:
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"fmt"
)
func main() {
// Генерируем приватный ключ на эллиптической кривой P-256
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
fmt.Println("Error generating key:", err)
return
}
// Сообщение, которое нужно подписать
message := []byte("Hello, ECDSA!")
// Вычисляем хеш сообщения SHA-256
hash := sha256.Sum256(message)
// Подписываем хеш
signature, err := ecdsa.SignASN1(privateKey, hash[:])
if err != nil {
fmt.Println("Error signing:", err)
return
}
fmt.Printf("Signature: %x\n", signature)
}
Результат выполнения кода:
"Signature: 3044022020c0d4d0a3b1c2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f800220361e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3"
Пример
Давайте подпишем хеш сообщения и проверим подпись с помощью функции ecdsa.VerifyASN1:
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"fmt"
)
func main() {
// Генерируем приватный и публичный ключи
privateKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
if err != nil {
fmt.Println("Error generating key:", err)
return
}
publicKey := &privateKey.PublicKey
// Сообщение и его хеш
message := []byte("Important data to sign")
hash := sha256.Sum256(message)
// Создаем подпись
signature, err := ecdsa.SignASN1(privateKey, hash[:])
if err != nil {
fmt.Println("Error signing:", err)
return
}
// Проверяем подпись
valid := ecdsa.VerifyASN1(publicKey, hash[:], signature)
if valid {
fmt.Println("Signature is valid")
} else {
fmt.Println("Signature is invalid")
}
}
Результат выполнения кода:
"Signature is valid"
Пример
Давайте обработаем ошибку, которая возникает при передаче некорректного приватного ключа:
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 {
fmt.Println("Error generating key:", err)
return
}
// Создаем некорректный хеш (слишком короткий)
hash := []byte("short")
// Пытаемся подписать с некорректным хешем
_, err = ecdsa.SignASN1(privateKey, hash)
if err != nil {
fmt.Println("Error occurred:", err)
return
}
}
Результат выполнения кода:
"Error occurred: crypto/ecdsa: invalid hash length"
Смотрите также
-
функцию
ecdsa.VerifyASN1,
которая проверяет подпись в формате ASN.1 -
функцию
ecdsa.GenerateKey,
которая генерирует пару приватного и публичного ключей ECDSA -
функцию
ecdsa.Sign,
которая возвращает подпись в виде двух больших чиселrиs -
функцию
ecdsa.Verify,
которая проверяет подпись, переданную как два больших числа