2011-06-14 118 views
9

我创建了一个OpenSSL的公/私钥,并签署了一些数据:在Python现在如何验证由openssl创建的pycrypto签名?

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 

,我想验证这样的数据:

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(消息摘要)算法:MD5或RIPEMD-160 16

回答

-1

我相信我发现这个问题的解决是使用binascii.a2b_base64然后我用DerInteger到解码结果。我希望这是有帮助的。

pem = binascii.a2b_base64(pemstring) 

# we need a tuple to collect the data 
tup = [] 
idx = 0 

# this loop is lifted right out of DerSequence.decode. 
# since pem now contains what would be the payload 
# of the sequence, we can simply grab the data based 
# on how DerSequence.decode is written. 
while idx < len(pem): 
    num = asn1.DerInteger() 
    idx += num.decode(pem[idx:]) 
    tup.append(num.value) 

#@see DerSequence.decode 
del tup[0] 
del tup[6:8] 

# And BEHOLD! the key is now constructed. 
# Next step: make this into a pack-extension script. 
private = RSA.construct(tup) 
+0

我不知道这是否是相关的。你的变量('pemstring')表明你想用'private.pem'(或'public.pem')文件做一些事情,但我需要以某种方式解析'签名'文件。现在我已经注意到,我忘了在示例代码中添加两个相关的部分,我刚刚纠正了它们。如果我尝试将你的代码应用于'signature'文件的内容,那么我得到了'ValueError:负INTEGER.'异常 – Ivan 2011-06-15 18:47:15

+0

我也不是,但你没有什么意见和答案,所以我提供了我所能提供的。如果你觉得它没有帮助,我会很高兴删除它。 – cwallenpoole 2011-06-15 19:39:13

0

这是解决方案。

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 
+3

显然这种方式不工作 - 返回False。按照你的建议,我尝试过这种方式http://pastebin.com/uPtrwngm – Ivan 2011-08-29 17:24:25

7

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

我有同样的问题,这里有两个例子中,产生与OpenSSL和蟒蛇验证。希望这可以帮助别人......

击:

#!/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是要使用的新方案创建签名。

两个脚本需要一些变化:

击:

#!/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!! :)" 
相关问题