Что вызывает это исключение InvalidSignature? (открытый ключ и подпись создаются PHP, а проверка выполняется в Python) - PullRequest
0 голосов
/ 06 января 2019

Я в основном пытаюсь создать подпись с помощью "openssl" (PHP) и проверить это с помощью "criptografy" (PYTHON). И я всегда получаю сообщение об ошибке «InvalidSignature», что означает, что я делаю что-то не так. Я знаю, что это разные языки и библиотеки, но как только я использую один и тот же алгоритм для обоих, я ожидал получить действительную подпись. Я ценю любую помощь.

PHP: создание открытого ключа и подписи без проблем

$config = array(
    "digest_alg" => "sha256",
    "private_key_bits" => 4096,
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$res = openssl_pkey_new($config);
openssl_pkey_export($res, $privKey);
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];
error_log($pubKey);

----- НАЧАТЬ ПУБЛИЧНЫЙ КЛЮЧ ----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtXyDj9vqTGkR / ITYZ6 + е xXATzalUOdBcqee + qcb5NJ6Z5DgNdYi9lWz / 4YfitYKp0EFwPzbem1zBzKbuQSko y7zRjpmyGbw8Q6wexO4SyA44jxs75JNXMA2x22dkNKajRE5kXngBIF1ixpzCxvvc kfyewM8C8y2iAy5j02YZYw9ysrQWJegamq6sidnMCJBtokOnPQaNJwbDQTqwrSRS 8IDy7BtBHB7F / bBwLArwxG7aLFjJ9vf2F7HpmZ3VvJa69OhY0pZMSqePQpJBIQ + 2 ztIywpKkOukJz22Brqoe0ygMQzVrcYoj2MZ8CSiKUCJL6Wm9ErFXvBh / XqPWjX1t nWdnF6qSD / 2itIw18 + PzCWYaoeu6w064dcbRrUQ4UOYxp69IFtrv5OHAsuWPJ27q 2IUCZ9DWWphlwhz + lI4rAb6whd2R8Sb7vEhvSz4Kd5kIjel9Dt8mJ + jGyhTjqIhP 7 amgcOQLKZJfmeltYI+F0U8oJcOPhxtlxfFB1MIxPDHvCcdR93LJGgU6NboTwcpx hnoI86xKblJmnxMxuQbUfPRU8vAuiizKVrpQS8z2k58mlxa9 + hykjMcqpAvQ6STM vLswdj0j9aqyv6I94z2Q2Lgcuoh7xSJcLhKN9QGaarUqjAY / zoZPiDnCxXlnVrav BMyQZ9PqbsaHsd7pVVpuW8MCAwEAAQ == ----- КОНЕЦ ОБЩЕСТВЕННОГО КЛЮЧА -----

$data = 'oi';
$pkeyid = openssl_pkey_get_private($privKey);
openssl_sign($data, $signature, $pkeyid);
error_log(base64_encode($signature));

MoUZzfaHCwME2mmxJnMBQWgo + lTLK2QfpfD + 5IEnSwi0wmRtgZgFl7IGsWYlTO + zTQCcB / aKg91CMClmb5P2jEtOkY3ie2pNflEIsc3aGqfWoVpHJUMoft + 4hytzgMszqwgbJdo6eac7zIxlrzmeb4jb58APtc4aaLLQru2Gga9oPRyCqbXrD0TXnQ6GzjDNGwi6wP30NU9KaHWaGfeq1WSqsAIaIbi2oG4MeWJYX6SOB / CX1Jg8SJYzWQahpJeybE4Z8fR6ncuvfbjp9aet1aKsPB / DFPQ5VFaAS4oItVb0Ha4wkQ8YgJu5fEUK7X9KzuOwidja5RLZtwDPa0bBSveCw9D8FUsguilaoIu7ueDPTRueK4bQkYstOc2OvVlzInukyOzFXVgZsiV23FTHrQ5FqHd9nCUbfuhgrMqHRYQmRFUgDaeyY + B5ve3bQ4lT3qm282ngKi8AZ + clB0VeaFiQxpF8SCCRMu0bX3dsQMaXRUeSVDipf3ZMABl9xXbzEjqXoJzuvC6tCnEv8K3HzKbjz2S1876eGy7opIixaUMwDu9QOiPoSiFUY / xCsX8D1Im8Mv4eyzWNV3FL1U / GS3LZzkq / NuJdB7wjCib3ieHaYX / bvTpmAp / oO0 + vbI2pzq9w71cpqQpsNsOZSGkgY2q1sO6u0I5jCFScdJVbJl0 =

PYTHON: ошибка недопустимой подписи

from cryptography.hazmat.backends import default_backend  
from cryptography.hazmat.primitives.asymmetric import padding  
from cryptography.hazmat.primitives import hashes  
from cryptography.hazmat.primitives.serialization import load_pem_private_key  
from cryptography.hazmat.primitives.serialization import load_pem_public_key
signature= 'MoUZzfaHCwME2mmxJnMBQWgo+lTLK2QfpfD+5IEnSwi0wmRtgZgFl7IGsWYlTO+zTQCcB/aKg91CMClmb5P2jEtOkY3ie2pNflEIsc3aGqfWoVpHJUMoft+4hytzgMszqwgbJdo6eac7zIxlrzmeb4jb58APtc4aaLLQru2Gga9oPRyCqbXrD0TXnQ6GzjDNGwi6wP30NU9KaHWaGfeq1WSqsAIaIbi2oG4MeWJYX6SOB/CX1Jg8SJYzWQahpJeybE4Z8fR6ncuvfbjp9aet1aKsPB/DFPQ5VFaAS4oItVb0Ha4wkQ8YgJu5fEUK7X9KzuOwidja5RLZtwDPa0bBSveCw9D8FUsguilaoIu7ueDPTRueK4bQkYstOc2OvVlzInukyOzFXVgZsiV23FTHrQ5FqHd9nCUbfuhgrMqHRYQmRFUgDaeyY+B5ve3bQ4lT3qm282ngKi8AZ+clB0VeaFiQxpF8SCCRMu0bX3dsQMaXRUeSVDipf3ZMABl9xXbzEjqXoJzuvC6tCnEv8K3HzKbjz2S1876eGy7opIixaUMwDu9QOiPoSiFUY/xCsX8D1Im8Mv4eyzWNV3FL1U/GS3LZzkq/NuJdB7wjCib3ieHaYX/bvTpmAp/oO0+vbI2pzq9w71cpqQpsNsOZSGkgY2q1sO6u0I5jCFScdJVbJl0='

decoded = base64.b64decode(signature)

plaintextMessage="oi"

# /tmp/public contains the public key
alicePubKey = load_pem_public_key(open('/tmp/public', 'rb').read(),default_backend())  

ciphertext = alicePubKey.verify(  
    decoded,  
    plaintextMessage,  
    padding.PSS(  
            mgf=padding.MGF1(algorithm=hashes.SHA256()),  
            salt_length=padding.PSS.MAX_LENGTH,  
    ),  
    hashes.SHA256()  
)

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Как сказал Джеймс, функция openssl_sign по умолчанию использует SHA1, что можно решить с помощью параметра OPENSSL_ALGO_SHA256.

Итак, я сделал эти изменения:

PHP

openssl_sign($data, $signature, $pkeyid, OPENSSL_ALGO_SHA256);

Python

ciphertext = alicePubKey.verify(  
    decoded,  
    plaintextMessage,  
    padding.PKCS1v15(),
    hashes.SHA256()  
 )
0 голосов
/ 07 января 2019

Довольно ясно, что ваш код PHP:

  1. Подписано с использованием RSA с SHA1, не SHA256
  2. Использовано заполнение PKCS # 1 версии 1.5, не PSS

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

Таким образом, следующий фрагмент кода Python должен проверить:

ciphertext = alicePubKey.verify(  
    decoded,  
    b'oi',  
    padding.PKCS1v15(),  
    hashes.SHA1()  
)

PSS и SHA-256 - лучший выбор, поэтому вам следует изучить возможность модификации своего кода PHP, чтобы использовать их вместо модификации кода Python.

...