Yandex Cloud
Поиск
Связаться с намиПодключиться
  • Истории успеха
  • Документация
  • Блог
  • Все сервисы
  • Статус работы сервисов
    • Популярные
    • Инфраструктура и сеть
    • Платформа данных
    • Контейнеры
    • Инструменты разработчика
    • Бессерверные вычисления
    • Безопасность
    • Мониторинг и управление ресурсами
    • AI Studio
    • Бизнес-инструменты
  • Все решения
    • По отраслям
    • По типу задач
    • Экономика платформы
    • Безопасность
    • Техническая поддержка
    • Каталог партнёров
    • Обучение и сертификация
    • Облако для стартапов
    • Облако для крупного бизнеса
    • Центр технологий для общества
    • Облако для интеграторов
    • Поддержка IT-бизнеса
    • Облако для фрилансеров
    • Обучение и сертификация
    • Блог
    • Документация
    • Контент-программа
    • Мероприятия и вебинары
    • Контакты, чаты и сообщества
    • Идеи
    • Тарифы Yandex Cloud
    • Промоакции и free tier
    • Правила тарификации
  • Истории успеха
  • Документация
  • Блог
Проект Яндекса
© 2025 ООО «Яндекс.Облако»
Yandex Key Management Service
  • Начало работы
    • Все инструкции
      • Ключевая пара электронной подписи
      • Права доступа к ключевой паре электронной подписи
      • Электронная подпись и проверка подписи
      • Электронная подпись файлов и артефактов с помощью Cosign
    • Посмотреть операции с ресурсами сервиса
  • Управление доступом
  • Правила тарификации
  • Справочник Terraform
  • Метрики Monitoring
  • Аудитные логи Audit Trails
  • Вопросы и ответы
  • Обучающие курсы

В этой статье:

  • Перед началом работы
  • Создайте электронную подпись
  • Подпись сообщения на приватном ключе
  • Подпись файла по хэшу данных
  • Проверьте электронную подпись
  • Подпись на эллиптических кривых (ECDSA)
  • Подпись RSA
  1. Пошаговые инструкции
  2. Электронная подпись
  3. Электронная подпись и проверка подписи

Электронная подпись и проверка подписи по хэшу данных

Статья создана
Yandex Cloud
Улучшена
mmerihsesh
Обновлена 21 апреля 2025 г.
  • Перед началом работы
  • Создайте электронную подпись
    • Подпись сообщения на приватном ключе
  • Подпись файла по хэшу данных
  • Проверьте электронную подпись
    • Подпись на эллиптических кривых (ECDSA)
    • Подпись RSA

Сервис Key Management Service позволяет создать электронную подпись, которую можно использовать для подтверждения подлинности и проверки целостности данных, а также для защиты подписанных данных от изменений.

Перед началом работыПеред началом работы

Проверка действительности электронной подписи в этой инструкции выполняется с помощью утилиты OpenSSL. Если эта утилита у вас не установлена, установите ее:

Linux
Windows

Выполните команду:

sudo apt-get install openssl

Воспользуйтесь пакетным менеджером Chocolatey. От имени администратора выполните команду в терминале PowerShell:

choco install openssl

Создайте электронную подписьСоздайте электронную подпись

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

Подпись сообщения на приватном ключеПодпись сообщения на приватном ключе

Примечание

Подпись на приватном ключе применяется для сообщений размером до 32 КБ.

  1. Если у вас еще нет ключевой пары электронной подписи, создайте ее.

  2. Получите открытый ключ подписи и сохраните его:

    Консоль управления
    CLI
    1. В консоли управления выберите каталог, в котором находится нужная ключевая пара электронной подписи.
    2. В списке сервисов выберите Key Management Service.
    3. На панели слева выберите Асимметричные ключи.
    4. Перейдите на вкладку Подпись.
    5. В строке с нужной ключевой парой нажмите значок и выберите Публичный ключ.
    6. В открывшемся окне нажмите кнопку Скачать, чтобы скачать публичный ключ электронной подписи.

    Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите и инициализируйте его.

    По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.

    1. Посмотрите описание команды CLI для получения открытого ключа подписи:

      yc kms asymmetric-signature-crypto get-public-key --help
      
    2. Получите идентификатор каталога, в котором сохранена ключевая пара электронной подписи.

    3. Получите идентификатор нужной ключевой пары электронной подписи, указав идентификатор каталога:

      yc kms asymmetric-signature-key list \
        --folder-id <идентификатор_каталога>
      

      Результат:

      +----------------------+----------------------+---------------------------+---------------------+--------+
      |          ID          |         NAME         |    SIGNATURE ALGORITHM    |     CREATED AT      | STATUS |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      | abj9g2dil5sj******** | sample-signature-key | RSA_2048_SIGN_PSS_SHA_512 | 2023-08-16 09:06:57 | ACTIVE |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      
    4. Получите открытый ключ электронной подписи, указав полученный ранее идентификатор ключевой пары:

      yc kms asymmetric-signature-crypto get-public-key \
        --id <идентификатор_ключевой_пары>
      

      Результат:

      key_id: abj9g2dil5sj********
      public_key: |
      -----BEGIN PUBLIC KEY-----
      MIIB...
      ...QAB
      -----END PUBLIC KEY-----
      

      Сохраните полученный ключ в файл, например, в файл public.key. Убедитесь, что в файле отсутствуют пробелы в начале строк.

  3. Создайте файл с сообщением в кодировке base64:

    1. Создайте текстовый файл, например, message.txt:

      cat > message.txt
      My sample message.
      It will be used to verify ECDSA signature.
      

      Размер сообщения не должен превышать 32 КБ.

    2. Переведите сообщение в кодировку base64, указав путь к создаваемому файлу сообщения в base64:

      base64 message.txt > <файл_сообщения_в_base64>
      
  4. Создайте подпись сообщения:

    CLI
    1. Посмотрите описание команды CLI для получения электронной подписи:

      yc kms asymmetric-signature-crypto sign --help
      
    2. Получите электронную подпись сообщения:

      yc kms asymmetric-signature-crypto sign \
        --id <идентификатор_ключевой_пары> \
        --signature-output-file <путь_к_файлу_подписи> \
        --message-file <путь_к_файлу_с_сообщением> \
        --inform base64 \
        --outform base64
      

      Где:

      • --id — идентификатор ключевой пары электронной подписи.
      • --signature-output-file — путь к файлу, в который будет сохранена электронная подпись.
      • --message-file — путь к созданному ранее файлу с сообщением в кодировке base64.
      • --inform — формат файла с сообщением. Возможные значения: raw (по умолчанию), base64 и hex.
      • --outform — формат файла подписи. Возможные значения: raw (по умолчанию), base64 и hex.

      Результат:

      key_id: abjcg4mhmdfe********
      signature: MAa7C...imw==
      
    3. Переведите полученную электронную подпись в формат DER, который необходим для утилиты OpenSSL:

      echo -n "$(< <путь_к_файлу_подписи>)" | base64 -d > <файл_подписи>
      

      Где:

      • <путь_к_файлу_подписи> — путь к полученному на предыдущем шаге файлу подписи.
      • <файл_подписи> — путь к создаваемому файлу подписи в формате DER.

    Полученный файл подписи в формате DER можно использовать при проверке подписи утилитой OpenSSL.

Подпись файла по хэшу данныхПодпись файла по хэшу данных

Примечание

Подпись по хэшу применяется для сообщений или файлов размером более 32 КБ.

  1. Если у вас еще нет ключевой пары электронной подписи, создайте ее.

  2. Получите открытый ключ электронной подписи и сохраните его:

    Консоль управления
    CLI
    1. В консоли управления выберите каталог, в котором находится нужная ключевая пара электронной подписи.
    2. В списке сервисов выберите Key Management Service.
    3. На панели слева выберите Асимметричные ключи.
    4. Перейдите на вкладку Подпись.
    5. В строке с нужной ключевой парой нажмите значок и выберите Публичный ключ.
    6. В открывшемся окне нажмите кнопку Скачать, чтобы скачать публичный ключ подписи.

    Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите и инициализируйте его.

    По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.

    1. Посмотрите описание команды CLI для получения открытого ключа подписи:

      yc kms asymmetric-signature-crypto get-public-key --help
      
    2. Получите идентификатор каталога, в котором сохранена ключевая пара электронной подписи.

    3. Получите идентификатор нужной ключевой пары электронной подписи, указав идентификатор каталога:

      yc kms asymmetric-signature-key list \
        --folder-id <идентификатор_каталога>
      

      Результат:

      +----------------------+----------------------+---------------------------+---------------------+--------+
      |          ID          |         NAME         |    SIGNATURE ALGORITHM    |     CREATED AT      | STATUS |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      | abj9g2dil5sj******** | sample-signature-key | RSA_2048_SIGN_PSS_SHA_512 | 2023-08-16 09:06:57 | ACTIVE |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      
    4. Получите открытый ключ электронной подписи, указав полученный ранее идентификатор ключевой пары:

      yc kms asymmetric-signature-crypto get-public-key \
        --id <идентификатор_ключевой_пары>
      

      Результат:

      key_id: abj9g2dil5sj********
      public_key: |
      -----BEGIN PUBLIC KEY-----
      MIIB...
      ...QAB
      -----END PUBLIC KEY-----
      

      Сохраните полученный ключ в файл, например, в файл public.key. Убедитесь, что в файле отсутствуют пробелы в начале строк.

  3. Получите хэш файла:

    Bash
    PowerShell

    Выполните команду:

    echo -n \
      $(<алгоритм_хэширования> <путь_к_исходному_файлу> | cut -d " " -f 1) > \
      <путь_к_файлу_с_хэшем>
    

    Где:

    • <алгоритм_хэширования> — алгоритм хэширования, использованный при создании ключевой пары электронной подписи. Алгоритм хэширования указан выше в поле SIGNATURE ALGORITHM в результатах получения списка ключевых пар. Возможные значения:
      • sha256sum — для алгоритмов SHA-256;
      • sha384sum — для алгоритмов SHA-384;
      • sha512sum — для алгоритмов SHA-512.
    • <путь_к_исходному_файлу> — путь к файлу, хэш которого нужно получить.
    • <путь_к_файлу_с_хэшем> — путь к файлу, в который будет сохранен хэш.

    Выполните команду:

    (Get-FileHash -Path <путь_к_исходному_файлу> -Algorithm <алгоритм_хэширования>).Hash.ToLower() | `
      Out-File -FilePath <путь_к_файлу_с_хэшем> `
      -encoding ASCII `
      -NoNewline
    

    Где:

    • <алгоритм_хэширования> — алгоритм хэширования, использованный при создании ключевой пары подписи. Алгоритм хэширования указан выше в поле SIGNATURE ALGORITHM в результатах получения списка ключевых пар. Возможные значения:
      • SHA256 — для алгоритмов SHA-256;
      • SHA384 — для алгоритмов SHA-384;
      • SHA512 — для алгоритмов SHA-512.
    • <путь_к_исходному_файлу> — путь к файлу, хэш которого нужно получить.
    • <путь_к_файлу_с_хэшем> — путь к файлу, в который будет сохранен хэш.
  4. Создайте подпись файла по хэшу:

    CLI
    1. Посмотрите описание команды CLI для получения электронной подписи по хэшу:

      yc kms asymmetric-signature-crypto sign-hash --help
      
    2. Получите идентификатор каталога, в котором сохранена ключевая пара электронной подписи.

    3. Получите идентификатор нужной ключевой пары электронной подписи, указав идентификатор каталога:

      yc kms asymmetric-signature-key list \
        --folder-id <идентификатор_каталога>
      

      Результат:

      +----------------------+----------------------+---------------------------+---------------------+--------+
      |          ID          |         NAME         |    SIGNATURE ALGORITHM    |     CREATED AT      | STATUS |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      | abj9g2dil5sj******** | sample-signature-key | RSA_2048_SIGN_PSS_SHA_512 | 2023-08-16 09:06:57 | ACTIVE |
      +----------------------+----------------------+---------------------------+---------------------+--------+
      
    4. Получите электронную подпись по хэшу:

      yc kms asymmetric-signature-crypto sign-hash \
        --id <идентификатор_ключевой_пары> \
        --signature-output-file <путь_к_файлу_подписи> \
        --message-hash-file <путь_к_файлу_с_хэшем> \
        --inform hex
      

      Где:

      • --id — идентификатор ключевой пары электронной подписи.
      • --signature-output-file — путь к файлу, в который будет сохранена электронная подпись.
      • --message-hash-file — путь к созданному ранее файлу с хэшем.
      • --inform — формат файла с хэшем. Для универсальности в примере приведено значение hex — такой формат работает на всех платформах. Возможные значения: raw (по умолчанию), base64 и hex.

      Результат:

      signature: W7V8A...22g==
      

Проверьте электронную подписьПроверьте электронную подпись

Подпись на эллиптических кривых (ECDSA)Подпись на эллиптических кривых (ECDSA)

Bash
Java
Go
Python

Проверьте электронную подпись с помощью утилиты OpenSSL:

openssl dgst \
  -<алгоритм_хэширования> \
  -verify <путь_к_файлу_открытого_ключа> \
  -signature <путь_к_файлу_подписи> \
  <путь_к_подписанному_файлу>

Где:

  • <алгоритм_хэширования> — алгоритм хэширования, использованный при создании ключевой пары подписи. Возможные значения:
    • sha256 — для алгоритмов SHA-256;
    • sha384 — для алгоритмов SHA-384;
    • sha512 — для алгоритмов SHA-512.
  • -verify — путь к файлу с открытым ключом подписи.
  • -signature — путь к файлу с электронной подписью.
  • <путь_к_подписанному_файлу> — путь к файлу, для которого проверяется электронная подпись.

Если подпись корректна, утилита OpenSSL вернет статус Verified OK.

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.io.StringReader;
import java.security.*;
import java.security.spec.*;
import java.util.Base64;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class VerifyEcdsaSign {

    public static void main(String[] args) throws Exception {
        String publicKeyPem = 
        """
        -- -- - BEGIN PUBLIC KEY-- -- -
        <содержимое_открытого_ключа>
            -- -- - END PUBLIC KEY-- -- - 
        """;
        String signatureStr = "<подпись>";
        byte[] signatureDer = Base64.getDecoder().decode(signatureStr);
        System.out.println(verifyEcdsaSignature(publicKeyPem, signatureDer, "<сообщение>", "<тип_алгоритма>"));
    }

    public static boolean verifyEcdsaSignature(String publicKeyPem, byte[] signatureDer, String message, String hash_algorithm)
    throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
    SignatureException, IOException {

        // Public key and subscription decoding
        PemReader pemReader = new PemReader(new StringReader(publicKeyPem));
        PemObject pemObject = pemReader.readPemObject();
        byte[] publicKeyBytes = pemObject.getContent();

        // Creating a PublicKey object from the decoded public key
        KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());
        EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
        PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

        // Creating a Signature object and initializing it with a public key
        Signature signature = Signature.getInstance(hash_algorithm + "withECDSA", new BouncyCastleProvider());
        signature.initVerify(publicKey);

        // Updating a Signature Object with Message Data
        byte[] messageBytes = message.getBytes();
        signature.update(messageBytes);

        // Signature verification using original message and decoded signature
        return signature.verify(signatureDer);
    }
}

Где:

  • <содержимое_открытого_ключа> — содержимое открытого ключа подписи.
  • <подпись> — содержимое электронной подписи в кодировке base64.
  • <сообщение> — строка, содержащая исходное сообщение, подписанное электронной подписью, или хэш подписанного электронной подписью файла.
  • <тип_алгоритма> — использованная для подписи хэш-функция. Возможные значения: SHA256, SHA384 и SHA512.

Код выполняет проверку электронной подписи на эллиптических кривых (ECDSA). Если подпись корректна, код возвращает true, если нет — false.

import (
    "crypto/ecdsa"
    "crypto/sha256"
    "crypto/x509"
    "encoding/asn1"
    "encoding/base64"
    "encoding/pem"
    "fmt"
    "hash"
    "log"
    "math/big"
)

func runEcdsaSignTest() {
    publicKeyPem := `-----BEGIN PUBLIC KEY-----
    <содержимое_открытого_ключа>
    -----END PUBLIC KEY-----`
    signatureB64 := "<подпись>"
    signatureDER, _ := base64.StdEncoding.DecodeString(signatureB64)
    message := "<сообщение>"

        fmt.Println(verifyEcdsa(publicKeyPem, signatureDER, message, <тип_алгоритма>))
}

type ECDSASignature struct {
    R, S *big.Int
}

func verifyEcdsa(publicKeyPem string, signatureDER []byte, message string, hashFunc hash.Hash) bool {

    // Decode the public key
    block, _ := pem.Decode([]byte(publicKeyPem))
    if block == nil {
        log.Fatal("failed to decode PEM block containing public key")
    }

    // Parse the public key
    pub, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
	    log.Fatal(err)
    }

    publicKey, ok := pub.(*ecdsa.PublicKey)
    if !ok {
	    log.Fatal("not ECDSA public key")
    }

    // Parse the signature
    var signature ECDSASignature
    _, err = asn1.Unmarshal(signatureDER, &signature)
    if err != nil {
	    log.Fatal(err)
    }

    // Compute the hash of the message
    hashFunc.Write([]byte(message))
    hashed := hashFunc.Sum(nil)

    // Verify the signature
    return ecdsa.Verify(publicKey, hashed, signature.R, signature.S)
}

Где:

  • <содержимое_открытого_ключа> — содержимое открытого ключа подписи в кодировке base64.
  • <подпись> — содержимое электронной подписи в кодировке base64.
  • <сообщение> — строка, содержащая исходное сообщение, подписанное электронной подписью, или хэш подписанного электронной подписью файла.
  • <тип_алгоритма> — использованная для подписи хэш-функция. Возможные значения: sha256.New(), sha512.New384() и sha512.New().

Код выполняет проверку электронной подписи на эллиптических кривых (ECDSA). Если подпись корректна, код возвращает true, если нет — false.

import base64
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.backends import default_backend

# Define hash algorithms
def verify_ecdsa_signature(public_key_b64, signature_der, message, hash_algorithm):
    hash_algorithms = {
        'SHA256': hashes.SHA256,
        'SHA384': hashes.SHA384,
        'SHA512': hashes.SHA512
    }

    # Check if the provided hash algorithm is supported
    if hash_algorithm not in hash_algorithms:
        raise ValueError('Unsupported hash algorithm: ' + hash_algorithm)

    # Loading a PEM Encoded Public Key
    public_key = serialization.load_pem_public_key(
        public_key_b64.encode(),
        backend = default_backend()
    )

    # Create Signature object and initialize it with the public key
    signature = ec.ECDSA(hash_algorithms[hash_algorithm]())

    # Update the Signature object with the message data
    message_bytes = message.encode()

    # Verify the signature using the original message and the decoded signature
    try:
        public_key.verify(signature_der, message_bytes, signature)
        return True
    except InvalidSignature:
        return False

def test_verify_signature():
    public_key_b64 = """
    -----BEGIN PUBLIC KEY-----
    <содержимое_открытого_ключа>
    -----END PUBLIC KEY-----"""
    signature_b64 = "<подпись>"
    signature_der = base64.b64decode(signature_b64)
    message = '<сообщение>'
    print(verify_ecdsa_signature(public_key_b64, signature_der, message, "<тип_алгоритма>"))

Где:

  • <содержимое_открытого_ключа> — содержимое открытого ключа подписи.
  • <подпись> — содержимое электронной подписи в кодировке base64.
  • <сообщение> — строка, содержащая исходное сообщение, подписанное электронной подписью, или хэш подписанного электронной подписью файла.
  • <тип_алгоритма> — использованная для подписи хэш-функция. Возможные значения: SHA256, SHA384 и SHA512.

Код выполняет проверку электронной подписи на эллиптических кривых (ECDSA). Если подпись корректна, код возвращает true, если нет — false.

Подпись RSAПодпись RSA

Bash
Java
Go
Python

Проверьте электронную подпись с помощью утилиты OpenSSL:

openssl dgst \
  -<алгоритм_хэширования> \
  -sigopt rsa_padding_mode:pss \
  -sigopt rsa_pss_saltlen:-1 \
  -verify <путь_к_файлу_открытого_ключа> \
  -signature <путь_к_файлу_подписи> \
  <путь_к_подписанному_файлу>

Где:

  • <алгоритм_хэширования> — алгоритм хэширования, использованный при создании ключевой пары подписи. Возможные значения:
    • sha256 — для алгоритмов SHA-256;
    • sha384 — для алгоритмов SHA-384;
    • sha512 — для алгоритмов SHA-512.
  • -verify — путь к файлу с открытым ключом подписи.
  • -signature — путь к файлу с электронной подписью.
  • <путь_к_подписанному_файлу> — путь к файлу, для которого проверяется электронная подпись.

Если подпись корректна, утилита OpenSSL вернет статус Verified OK.

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.io.StringReader;
import java.security.*;
import java.security.spec.*;
import java.util.Base64;

public class VerifyRsaSign {

    public static void main(String[] args) throws Exception {
        String publicKeyPem = """
        -----BEGIN PUBLIC KEY-----
        <содержимое_открытого_ключа>
        -----END PUBLIC KEY-----""";
        String signatureStr = "<подпись>";
        byte[] signatureBytes = Base64.getDecoder().decode(signatureStr);
        String message = "<сообщение>";
        System.out.println(verifyRsaSignature(publicKeyPem, signatureBytes, message, "<тип_алгоритма>"));
    }

    private static boolean verifyRsaSignature(String publicKeyPem, byte[] signatureBytes, String message, String hashAlgorithm)
    throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
    SignatureException, InvalidAlgorithmParameterException, IOException {

        // Get the public key
        PemReader pemReader = new PemReader(new StringReader(publicKeyPem));
        PemObject pemObject = pemReader.readPemObject();
        byte[] publicKeyBytes = pemObject.getContent();

        // Create a PublicKey object using the decoded public key
        KeyFactory keyFactory = KeyFactory.getInstance("RSA", new BouncyCastleProvider());
        EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
        PublicKey pubKey = keyFactory.generatePublic(publicKeySpec);

        MessageDigest messageDigest = MessageDigest.getInstance(hashAlgorithm);
        int saltLength = messageDigest.getDigestLength();

        // Initialize the PSS signer
        PSSParameterSpec pssSpec = new PSSParameterSpec(hashAlgorithm, "MGF1", new MGF1ParameterSpec(hashAlgorithm), saltLength, 1);
        Signature signer = Signature.getInstance("RSASSA-PSS");
        signer.setParameter(pssSpec);
        signer.initVerify(pubKey);

        // Update the signature with the hash of the message
        byte[] messageBytes = message.getBytes();
        signer.update(messageBytes);

        // Verify the signature
        return signer.verify(signatureBytes);
    }
}

Где:

  • <содержимое_открытого_ключа> — содержимое открытого ключа подписи.
  • <подпись> — содержимое электронной подписи в кодировке base64.
  • <сообщение> — строка, содержащая исходное сообщение, подписанное электронной подписью, или хэш подписанного электронной подписью файла.
  • <тип_алгоритма> — использованная для подписи хэш-функция. Возможные значения: SHA256, SHA384 и SHA512.

Код выполняет проверку электронной подписи RSA. Если подпись корректна, код возвращает true, если нет — false.

import (
    "crypto"
    "crypto/rsa"
    "crypto/sha256"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "fmt"
    "log"
)

func runRsaSignTest() {
    publicKeyB64 := "<содержимое_открытого_ключа>"
    signatureB64 := "<подпись>"
    signatureBytes, _ := base64.StdEncoding.DecodeString(signatureB64)
    message := "<сообщение>"

        fmt.Println(verifyRsa(publicKeyB64, signatureBytes, message, <тип_алгоритма>))
}

func verifyRsa(publicKeyPem string, signatureBytes []byte, message string, hash crypto.Hash) bool {

    // Decode the public key
    block, _ := pem.Decode([]byte(publicKeyPem))
    if block == nil {
        log.Fatal("failed to decode PEM block containing public key")
    }

    // Parse the public key
    pub, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
	    log.Fatal(err)
    }

    publicKey, ok := pub.(*rsa.PublicKey)
    if !ok {
	    log.Fatal("not RSA public key")
    }

    // Calculate the hash of the message
    hasher := hash.New()
    hasher.Write([]byte(message))
    hashed := hasher.Sum(nil)

    // Set the PSS options: salt length auto, and the hash function
    pssOptions := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthAuto, Hash: hash}

    // Verify the signature
    err = rsa.VerifyPSS(publicKey, hash, hashed, signatureBytes, pssOptions)
    if err != nil {
	    fmt.Println("Verification failed:", err)
	    return false
    } else {
	    return true
    }
}

Где:

  • <содержимое_открытого_ключа> — содержимое открытого ключа подписи в кодировке base64.
  • <подпись> — содержимое электронной подписи в кодировке base64.
  • <сообщение> — строка, содержащая исходное сообщение, подписанное электронной подписью, или хэш подписанного электронной подписью файла.
  • <тип_алгоритма> — использованная для подписи хэш-функция. Возможные значения: crypto.SHA256, crypto.SHA384 и crypto.SHA512.

Код выполняет проверку электронной подписи RSA. Если подпись корректна, код возвращает true, если нет — false.

import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.backends import default_backend

# Define hash algorithms and corresponding salt lengths
def verify_rsa_signature(public_key_b64, signature_bytes, message, hash_algorithm):
    hash_algorithms = {
        'SHA256': hashes.SHA256,
        'SHA384': hashes.SHA384,
        'SHA512': hashes.SHA512
    }

    # Check if the provided hash algorithm is supported
    if hash_algorithm not in hash_algorithms:
        raise ValueError('Unsupported hash algorithm: ' + hash_algorithm)

    # Loading a PEM Encoded Public Key
    public_key = serialization.load_pem_public_key(
        public_key_b64.encode(),
        backend=default_backend()
    )

    # Update the Signature object with the message data
    message_bytes = message.encode()

    # Automatically calculate salt length based on hash digest size
    salt_length = hash_algorithms[hash_algorithm]().digest_size

    # Verify the signature using the original message and the decoded signature
    try:
        public_key.verify(
            signature_bytes,
            message_bytes,
            padding.PSS(
                mgf = padding.MGF1(hash_algorithms[hash_algorithm]()),
                salt_length = salt_length
            ),
            hash_algorithms[hash_algorithm]()
        )
        return True
    except InvalidSignature:
        return False

def test_verify_signature():
    public_key_b64 = """
    -----BEGIN PUBLIC KEY-----
    <содержимое_открытого_ключа>
    -----END PUBLIC KEY-----"""
    signature_b64 = '<подпись>'
    signature_bytes = base64.b64decode(signature_b64)
    message = '<сообщение>'
    print(verify_rsa_signature(public_key_b64, signature_bytes, message, '<тип_алгоритма>'))

Где:

  • <содержимое_открытого_ключа> — содержимое открытого ключа подписи в кодировке base64.
  • <подпись> — содержимое электронной подписи в кодировке base64.
  • <сообщение> — строка, содержащая исходное сообщение, подписанное электронной подписью, или хэш подписанного электронной подписью файла.
  • <тип_алгоритма> — использованная для подписи хэш-функция. Возможные значения: SHA256, SHA384 и SHA512.

Код выполняет проверку электронной подписи RSA. Если подпись корректна, код возвращает true, если нет — false.

Была ли статья полезна?

Предыдущая
Права доступа к ключевой паре электронной подписи
Следующая
Электронная подпись файлов и артефактов с помощью Cosign
Проект Яндекса
© 2025 ООО «Яндекс.Облако»