Какая информация необходима для проверки подписи? - PullRequest
2 голосов
/ 04 октября 2019

Я написал тестовую демонстрацию подписи и полной проверки процесса на базе rsa, которая помогает мне выяснить логику процесса.

# https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa

# Preparation phase
# Generate key pairs
# private_key contains the both private key and public key
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
    backend=default_backend()
)

# Serilize the keys
from cryptography.hazmat.primitives import serialization

pem = private_key.private_bytes(
   encoding=serialization.Encoding.PEM,
   format=serialization.PrivateFormat.PKCS8,
   encryption_algorithm=serialization.BestAvailableEncryption(b'mypassword')
)
with open('private-key.pem', 'wb') as f:
    f.write(pem)
    f.close()

public_key = private_key.public_key()
pem = public_key.public_bytes(
   encoding=serialization.Encoding.PEM,
   format=serialization.PublicFormat.SubjectPublicKeyInfo
)
with open('public-key.pem', 'wb') as f:
    f.write(pem)
    f.close()

# Signer
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import utils

with open('private-key.pem', 'rb') as f:
    private_key = serialization.load_pem_private_key(
        f.read(),
        password=b'mypassword',
        backend=default_backend()
    )

    chosen_hash = hashes.SHA256()
    hasher = hashes.Hash(chosen_hash, default_backend())
    hasher.update(b"data & ")
    hasher.update(b"more data")
    digest = hasher.finalize()

    signature = private_key.sign(
        digest,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        ),
        utils.Prehashed(chosen_hash)
    )

    with open('signature', 'wb') as f:
        f.write(signature)
        f.close()

# Verifier
chosen_hash = hashes.SHA256()
hasher = hashes.Hash(chosen_hash, default_backend())
hasher.update(b"data & ")
hasher.update(b"more data")
digest = hasher.finalize()

hasher1 = hashes.Hash(chosen_hash, default_backend())
hasher1.update(b"data & more data")
digest1 = hasher1.finalize()
print(digest == digest1)

with open('signature', 'rb') as f:
    signature = f.read()

with open('public-key.pem', 'rb') as f:
    public_key  = serialization.load_pem_public_key(
        f.read(),
        backend=default_backend()
    )

    if isinstance(public_key, rsa.RSAPublicKey):
        public_key.verify(
            signature,
            digest,
            padding.PSS(
                mgf=padding.MGF1(hashes.SHA256()),
                salt_length=padding.PSS.MAX_LENGTH
            ),
            utils.Prehashed(chosen_hash)
        )

Вопрос:

Заполняет ли заполнениетип (например, PSS), который должен быть известен как ввод при проверке?

Но в CLI Генерация пары ключей EC из командной строки OpenSSL

openssl dgst -sha256 -verify public.pem -signature msg.signature.txt msg.digest.txt

Почему здесь не упоминается обивка? Я думаю, что независимо от того, какой алгоритм пар ключей (ECC или RSA) различен или нет, входной параметр (стандартного?) Метода проверки должен быть одинаковым.

Другой вопрос, который я видел в python с isinstance(public_key, rsa.RSAPublicKey)можно выяснить алгоритм ключей.

Нужен ли тип алгоритма также для метода проверки?

Как внутри библиотеки могут быть такие ecc_verify rsa_verify методы.

Кстати, для моего понимания, параметр метода verify (такой же, как CLI openssl):

  • открытый ключ
  • тип хэша
  • подпись

1 Ответ

2 голосов
/ 04 октября 2019

Должен ли тип заполнения (например, PSS) быть известен как ввод при проверке?

Да, заполнение является обязательным параметром конфигурации, который должен быть известен заранее.

Почему здесь не упоминается заполнение?

Проверка подписи ECDSA не требует заполнения;он значительно отличается от генерации / проверки подписи RSA.

Для него существует только один используемый стандарт, как это было ранее для RSA (заполнение PKCS # 1 v1.5). PSS был добавлен только позже в стандартах RSA PKCS # 1, когда была опубликована версия 2.0.

Требуется ли тип алгоритма также для метода проверки?

Хотя существуетВероятно, это не прямая атака, вы должны предположить, что алгоритм проверки известен заранее, как и в случае метода заполнения. RSA, как описано в PKCS # 1, имеет как минимум две функции генерации сигнатур, а в других стандартах их больше, хотя они вообще не являются общими.

Кстати, на мой взгляд, параметр метода verify (то же самое)как openssl CLI):

Как вы уже видели, RSA PSS использует две хеш-функции, одну для хеширования входных данных и одну для внутренней функции MGF1, используемой для заполнения. Таким образом, существует не один тип хеша, а два. Типы хеширования не обязательно одинаковы, и реализации различаются в зависимости от того, как определяется хэш MGF1 (указав его явно, как вы делаете, лучше).

...