如何验证openssl创建的pycrypto签名?

发布于 2024-11-15 11:00:52 字数 1209 浏览 4 评论 0原文

我已经在 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 期望第二个参数为 1 - 数量较大的元素列表。而且我不知道如何将文件 signature 中的二进制数据转换为这个整数。关于 pycrypto 的每个示例都显示从 pycrypto 生成的签名,并且 key.sign() 生成格式为 (1832273432...2340234L, ) 的正确签名。但我不知道如何使用外部签名。

如果有必要,下面是我不知道如何解释的附加信息:

简要技术信息:

  • 数字签名格式: PKCS#7“签名数据”
  • 公钥程序: DSS
  • 密钥长度: 512 – 1024 位
  • 公开指数:2+1
  • 公开密钥格式:X.509 v3 证书
  • MD(消息摘要)算法:MD5 或 RIPEMD-160 16

I've created private/public key in openssl, and signed some data:

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

now in python, I'm trying to verify this data:

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

the problem is, that pub.verify expects second parameter to be one-element list with some large number. And I don't know how to convert binary data in file signature to this integer. Every example about pycrypto shows signature generated from pycrypto, and key.sign() generates correct signature in form (1832273432...2340234L, ). But I dont know how to use external signature.

If this is necessary, below are additional informations, which I don't exactly know how to interpret:

Brief technical information:

  • Format of digital signature: PKCS#7 “Signed-Data”
  • Public key procedure: DSS
  • Key length: 512 – 1024 bits
  • Public exponent: 2 +1
  • Public key format: X.509 v3 certificate
  • MD (Message Digest) algorithm: MD5 or RIPEMD-160 16

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冷…雨湿花 2024-11-22 11:00:52

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."

The Crypto.Signature module is what you want. From the Crypto.Signature.PKCS1_v1_5 documentation:

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."
吃→可爱长大的 2024-11-22 11:00:52

我遇到了同样的问题,这里有两个示例,使用 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!! :)"

I had the same problem and here are examples for both, generating and verifying with openssl and python. Hope this helps someone...

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!! :)"

After some more reading i've learned (https://en.wikipedia.org/wiki/PKCS_1) that PKCS1_PSS is the new scheme that should be used to create signatures.

Both scripts needs some changes:

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!! :)"
豆芽 2024-11-22 11:00:52

这是解决方案。

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

Here is the solution.

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
爱她像谁 2024-11-22 11:00:52

这篇文章给你最好的答案。
如何在 Python 中验证 RSA SHA1 签名?< /a>

pycrypto 无法验证 OpenSSL 创建的签名。您可以尝试 M2Crypto。

This post gives you the best answer.
How do you verify an RSA SHA1 signature in Python?

pycrypto could not verify a signature created by OpenSSL. You may try M2Crypto.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文