Как проверить в pycrypto подпись, созданную openssl? - PullRequest
10 голосов
/ 15 июня 2011

Я создал закрытый / открытый ключ в openssl и подписал некоторые данные:

openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
echo 'data to sign' > data.txt
openssl dgst -md5 < data.txt > hash
openssl rsautl -sign -inkey private.pem -keyform PEM -in hash  > signature

сейчас в python, я пытаюсь проверить эти данные:

pubKey = open('public.pem').read()
data = open('data.txt').read()
signature = open('signature').read()

from Crypto import PublicKey
key = PublicKey.RSA.importKey(pubKey)
pub = key.publickey()
hash = MD5.new(data).hexdigest()
# here, hash is same, as contents of 'hash' file
print pub.verify(hash, signature) # <-- here

проблема в том, что pub.verify ожидает, что второй параметр будет одноэлементным списком с некоторым большим числом.И я не знаю, как преобразовать двоичные данные в файле signature в это целое число.Каждый пример с pycrypto показывает сигнатуру, сгенерированную из pycrypto, а key.sign() генерирует правильную сигнатуру в форме (1832273432...2340234L, ).Но я не знаю, как использовать внешнюю подпись.

Если это необходимо, ниже приведены дополнительные сведения, которые я точно не знаю, как интерпретировать:

Краткая техническая информация:

  • Формат цифровой подписи: PKCS # 7 «Подписанные данные»
  • Процедура с открытым ключом: DSS
  • Длина ключа: 512 - 1024 бита
  • Открытыйэкспонента: 2 + 1
  • Формат открытого ключа: сертификат X.509 v3
  • Алгоритм MD (Message Digest): MD5 или RIPEMD-160 16

Ответы [ 4 ]

8 голосов
/ 13 мая 2012

Модуль Crypto.Signature - это то, что вам нужно. Из Crypto.Signature.PKCS1_v1_5 документации:

key = RSA.importKey(open('pubkey.der').read())
h = SHA.new(message)
verifier = PKCS1_v1_5.new(key)
if verifier.verify(h, signature):
   print "The signature is authentic."
else:
   print "The signature is not authentic."
6 голосов
/ 01 октября 2015

У меня была та же проблема, и вот примеры для генерации и проверки с помощью openssl и python.Надеюсь, что это кому-то поможет ...

Bash:

#!/bin/bash
# Generate keys
openssl genrsa -out priv.pem
# Export public key
openssl rsa -pubout -in priv.pem -out pub.pem
# Create test file
echo test123 > test.txt
# Create SHA1 signature
openssl dgst -sha1 -sign priv.pem -out test.txt.sig test.txt
# Verify SHA1 signature
openssl dgst -sha1 -verify pub.pem -signature test.txt.sig test.txt

Python:

#!/usr/bin/python
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from Crypto import Random
# Read public key from file
fd = open('pub.pem', 'r')
key_data = fd.read()
fd.close()
# Load public key
key = RSA.importKey(key_data)
# Read test file
fd = open('test.txt', 'r')
message = fd.read()
fd.close()
# Create SHA1 hash object
h = SHA.new(message)
# Create PKCS1 handler
cipher = PKCS1_v1_5.new(key)
# Read signature file
fd = open('test.txt.sig', 'r')
signature = fd.read()
fd.close()
# Verify signature
print cipher.verify(h, signature)
# Read private key from file
fd = open('priv.pem', 'r')
priv_key_data = fd.read()
fd.close()
# Load private key
priv_key = RSA.importKey(priv_key_data)
# Create PKCS1 handler
priv_cipher = PKCS1_v1_5.new(priv_key)
# Sign hash of test file content and compare
signature2 = priv_cipher.sign(h)
if signature == signature2:
    print "Match!! :)"

После некоторого прочтения я выучил (https://en.wikipedia.org/wiki/PKCS_1)что PKCS1_PSS - это новая схема, которая должна использоваться для создания подписей.

Оба сценария требуют некоторых изменений:

Bash:

#!/bin/bash
# Generate keys
openssl genrsa -out priv.pem
# Export public key
openssl rsa -pubout -in priv.pem -out pub.pem
# Create test file
echo test123 > test.txt
# Create SHA1 signature
openssl dgst -sha1 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -sign priv.pem -out test.txt.sig test.txt
# Verify SHA1 signature
openssl dgst -sha1 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 -verify pub.pem -signature test.txt.sig test.txt

Python:

#!/usr/bin/python
from Crypto.Signature import PKCS1_PSS
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from Crypto import Random
# Read public key from file
fd = open('pub.pem', 'r')
key_data = fd.read()
fd.close()
# Load public key
key = RSA.importKey(key_data)
# Read test file
fd = open('test.txt', 'r')
message = fd.read()
fd.close()
# Create SHA1 hash object
h = SHA.new(message)
# Create PKCS1 handler
cipher = PKCS1_PSS.new(key)
# Read signature file
fd = open('test.txt.sig', 'r')
signature = fd.read()
fd.close()
# Verify signature
print cipher.verify(h, signature)
# Read private key from file
fd = open('priv.pem', 'r')
priv_key_data = fd.read()
fd.close()
# Load private key
priv_key = RSA.importKey(priv_key_data)
# Create PKCS1 handler
priv_cipher = PKCS1_PSS.new(priv_key)
# Sign hash of test file content and compare
signature2 = priv_cipher.sign(h)
# PKCS1_PSS signatures always differ!
#if signature == signature2:
#    print "Match!! :)"
0 голосов
/ 26 августа 2011

Вот решение.

from Crypto.Util import number
signature  = number.bytes_to_long(signature) #Convert the signature to long
print pub.verify(hash, (signature,) ) #Pass tuple to verify
0 голосов
/ 12 июля 2011

Этот пост дает вам лучший ответ. Как проверить подпись RSA SHA1 в Python?

pycrypto не удалось проверить подпись, созданную OpenSSL.Вы можете попробовать M2Crypto.

...