РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1300 of 1593 menu

Пакет crypto/ecdsa

Пакет crypto/ecdsa реализует алгоритм цифровой подписи на эллиптических кривых (ECDSA) согласно стандарту FIPS 186-4. Он предоставляет функции для генерации ключевых пар, создания цифровых подписей и их верификации. Пакет использует кривые из пакета crypto/elliptic, такие как P-256, P-384 и P-521.

Генерация ключевой пары

Функция GenerateKey создает новую пару закрытого и открытого ключей. В качестве первого параметра она принимает эллиптическую кривую, а вторым параметром - источник случайных чисел. Возвращает указатель на структуру PrivateKey.

package main import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "fmt" ) func main() { privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { fmt.Println(err) return } fmt.Printf("Private key: %x\n", privateKey.D) fmt.Printf("Public key X: %x\n", privateKey.PublicKey.X) fmt.Printf("Public key Y: %x\n", privateKey.PublicKey.Y) }

Результат выполнения кода:

"Private key: 2f3e5a7b9c1d..." "Public key X: 4a6b8c0d1e2f..." "Public key Y: 3b5d7f9a1c3e..."

Функция GenerateKey возвращает закрытый ключ, который содержит открытый ключ в своем составе. Закрытый ключ должен храниться в секрете, а открытый ключ можно распространять.

Создание цифровой подписи

Функция Sign создает цифровую подпись для сообщения. В качестве параметров она принимает источник случайных чисел, закрытый ключ и хеш сообщения. Возвращает пару чисел r и s, которые являются компонентами подписи.

package main import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/sha256" "fmt" ) func main() { privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) message := []byte("Hello, ECDSA!") hash := sha256.Sum256(message) r, s, err := ecdsa.Sign(rand.Reader, privateKey, hash[:]) if err != nil { fmt.Println(err) return } fmt.Printf("r: %x\n", r) fmt.Printf("s: %x\n", s) }

Результат выполнения кода:

"r: 3b6a7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b" "s: 7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d"

Функция Sign возвращает компоненты подписи r и s. Они представлены в виде больших чисел (*big.Int). Обе компоненты должны быть переданы вместе с сообщением для верификации.

Верификация подписи

Функция Verify проверяет валидность цифровой подписи. Она принимает открытый ключ, хеш сообщения и компоненты подписи r и s. Возвращает true, если подпись действительна, иначе false.

package main import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/sha256" "fmt" ) func main() { privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) message := []byte("Hello, ECDSA!") hash := sha256.Sum256(message) r, s, _ := ecdsa.Sign(rand.Reader, privateKey, hash[:]) publicKey := privateKey.PublicKey isValid := ecdsa.Verify(&publicKey, hash[:], r, s) fmt.Println("Signature valid:", isValid) }

Результат выполнения кода:

"Signature valid: true"

Функция Verify проверяет, что подпись создана с использованием закрытого ключа, соответствующего переданному открытому ключу. Это гарантирует подлинность сообщения.

Работа с ASN.1 форматом

Пакет предоставляет функции SignASN1 и VerifyASN1 для работы с подписями в формате ASN.1 DER. Это стандартный формат для обмена цифровыми подписями.

package main import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/sha256" "fmt" ) func main() { privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) message := []byte("Hello, ECDSA!") hash := sha256.Sum256(message) signature, err := ecdsa.SignASN1(rand.Reader, privateKey, hash[:]) if err != nil { fmt.Println(err) return } publicKey := privateKey.PublicKey isValid := ecdsa.VerifyASN1(&publicKey, hash[:], signature) fmt.Printf("Signature: %x\n", signature) fmt.Println("Valid:", isValid) }

Результат выполнения кода:

"Signature: 3046022100a1b2c3d4e5f6..." "Valid: true"

Функции SignASN1 и VerifyASN1 работают с подписями в стандартном формате ASN.1 DER. Это удобно для хранения и передачи подписей через сети.

Практический пример

Полный пример использования пакета crypto/ecdsa для подписи и верификации сообщения:

package main import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/sha256" "fmt" "log" ) func main() { // Генерация ключевой пары privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { log.Fatal(err) } // Данные для подписи message := []byte("Document to sign") hash := sha256.Sum256(message) // Создание подписи r, s, err := ecdsa.Sign(rand.Reader, privateKey, hash[:]) if err != nil { log.Fatal(err) } // Верификация подписи publicKey := privateKey.PublicKey isValid := ecdsa.Verify(&publicKey, hash[:], r, s) if isValid { fmt.Println("Success: Signature is valid") } else { fmt.Println("Error: Invalid signature") } }

Результат выполнения кода:

"Success: Signature is valid"

В этом примере показан полный цикл работы с ECDSA: генерация ключей, создание подписи для хеша сообщения и ее верификация.

Смотрите также

  • пакет crypto/rsa,
    который реализует алгоритм RSA для шифрования и подписи
  • пакет crypto/ed25519,
    который реализует схему подписи Ed25519
  • пакет crypto/elliptic,
    который предоставляет эллиптические кривые
  • пакет crypto/hmac,
    который реализует HMAC для аутентификации сообщений
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить