Тип rsa.PublicKey

Тип rsa.PublicKey представляет собой структуру открытого ключа RSA. Он содержит два поля: N — модуль (большое целое число) и E — открытую экспоненту. Этот тип используется для шифрования данных с помощью алгоритма RSA, а также для проверки цифровых подписей. Первое поле N — это произведение двух больших простых чисел, второе поле E — это число, обычно равное 65537.

Синтаксис

gotype PublicKey struct {
  N *big.Int
  E int
}

Пример

Давайте создадим открытый ключ RSA из существующих значений и используем его для шифрования. В этом примере мы зашифруем сообщение с помощью открытого ключа и функции rsa.EncryptPKCS1v15:

gopackage main

import (
  "crypto/rand"
  "crypto/rsa"
  "crypto/sha256"
  "fmt"
  "math/big"
)

func main() {
  // Создаем открытый ключ из чисел
  pub := &rsa.PublicKey{
    N: big.NewInt(0),
    E: 65537,
  }

  // В реальных условиях N должно быть большим числом
  // Здесь для примера используем маленькое значение
  pub.N.SetString("12345678901234567890", 10)

  // Сообщение для шифрования
  msg := []byte("Hello, RSA!")

  // Шифруем сообщение
  ciphertext, err := rsa.EncryptPKCS1v15(
    rand.Reader,
    pub,
    msg,
  )
  if err != nil {
    fmt.Println("Error:", err)
    return
  }

  fmt.Printf("Ciphertext: %x\n", ciphertext)
}

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

go"Ciphertext: 4a5b6c7d8e9f..."

Пример

Давайте проверим подпись с помощью открытого ключа RSA. В этом примере мы создадим подпись с использованием закрытого ключа и проверим ее с помощью открытого ключа:

gopackage main

import (
  "crypto"
  "crypto/rand"
  "crypto/rsa"
  "crypto/sha256"
  "fmt"
)

func main() {
  // Генерируем пару ключей
  privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
  if err != nil {
    fmt.Println("Error generating key:", err)
    return
  }

  // Извлекаем открытый ключ
  publicKey := &privateKey.PublicKey

  // Сообщение для подписи
  msg := []byte("Important message")

  // Хешируем сообщение
  hash := sha256.Sum256(msg)

  // Создаем подпись
  signature, err := rsa.SignPKCS1v15(
    rand.Reader,
    privateKey,
    crypto.SHA256,
    hash[:],
  )
  if err != nil {
    fmt.Println("Error signing:", err)
    return
  }

  // Проверяем подпись с помощью открытого ключа
  err = rsa.VerifyPKCS1v15(
    publicKey,
    crypto.SHA256,
    hash[:],
    signature,
  )
  if err != nil {
    fmt.Println("Signature verification failed:", err)
  } else {
    fmt.Println("Signature verified successfully")
  }
}

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

go"Signature verified successfully"

Пример

Давайте сериализуем открытый ключ в формат PKIX для передачи по сети. Это позволяет сохранять ключ в стандартном формате и передавать его другим системам:

gopackage main

import (
  "crypto/rand"
  "crypto/rsa"
  "crypto/x509"
  "encoding/pem"
  "fmt"
)

func main() {
  // Генерируем пару ключей
  privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
  if err != nil {
    fmt.Println("Error generating key:", err)
    return
  }

  // Извлекаем открытый ключ
  publicKey := &privateKey.PublicKey

  // Сериализуем в формат PKIX
  pubKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey)
  if err != nil {
    fmt.Println("Error marshaling key:", err)
    return
  }

  // Кодируем в PEM
  pemBlock := &pem.Block{
    Type:  "PUBLIC KEY",
    Bytes: pubKeyBytes,
  }
  pemBytes := pem.EncodeToMemory(pemBlock)

  fmt.Println("Public key PEM:")
  fmt.Println(string(pemBytes))
}

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

go"Public key PEM: -----BEGIN PUBLIC KEY-----..."

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

  • тип rsa.PrivateKey,
    который представляет закрытый ключ RSA
  • функцию rsa.GenerateKey,
    которая генерирует пару ключей RSA
  • функцию rsa.EncryptPKCS1v15,
    которая шифрует данные с помощью открытого ключа
  • функцию rsa.VerifyPKCS1v15,
    которая проверяет цифровую подпись RSA