2017-07-06 80 views
1

我正在使用pyCrypto PKCS1_v1_5簽名來簽署消息。 (Original codeRSA登錄python並驗證在JS

from Crypto.Signature import PKCS1_v1_5 
from Crypto.Hash import * 
from Crypto.PublicKey import RSA 
from Crypto import Random 
import base64 
import codecs 

private_key = """-----BEGIN RSA PRIVATE KEY----- 
MIICXAIBAAKBgQDtmBQTFLfaYOsio48B0Sbw4qMnaXJ7Qk4i1gzI+lgLIOPV0YyU 
fWMKgl24iJsGN6W5Vk+4GfDE7jKGkti9ZsswaJ/1Un+zFpXlVCOjEe9CZz3npIEK 
G8jJL1rwnBc2qPY3YD8jWBhLaPUgchbxUbe1Q2eKDmlRF7B8BzeNG4aVdQIDAQAB 
AoGBAK+x6Q5fIMHVL6vyxRqz3pb9EWdgm664Tm2GWff44EiCbti717gqrKWl18ZR 
Bkpnth5CzDq4vAn0ltpbFvmgXRmnUL8WsxigrL6tf2mcx4QAgcqr4B6er7X738lB 
UDSaEiSLmT/hr9Rg6H/P8IoP01tLKnj/gYQd5CVLkh/VD+dVAkEA9InBNnM5ViAM 
Aq7lL/+RWc+jfKnT9kWo+X0v7K8fD9/188K45G6zK/9X0J6Qj83dk1uni5QGx1i1 
VVBXIlUnqwJBAPi7AEl8nmmohrSsq8YHX6lTTy6EybSgQS4Qu3SBcVl2RoG89BLx 
kReqyTRGupZz/fNS9VfGFZU9VOHcFCeVl18CQEOiLgwvRjZp2qiLUtw5pSvf3+nE 
1tkQXzHRzAV8Ue0EFnR68MRNUcTjdJhAot8DIzt0aByUrmNIR67274KRZs0CQC1X 
kZ7T2+Dw+tV24L1x3Kt2Z2nYhRirWhZ2sGV1r18ao5HFC01kwglpddJUznDc5j90 
MQt2LbsN+ipOP1JT/8sCQE4qVh+TeYVd8aXSqlJaTsLZNzDMjmREYfuodmyZp5WR 
q1R6SaZoxQltHgTtK85QqhDxmmWPkR6jdNLDlIR0Bx4= 
-----END RSA PRIVATE KEY-----""" 

public_key = """"-----BEGIN PUBLIC KEY----- 
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDtmBQTFLfaYOsio48B0Sbw4qMn 
aXJ7Qk4i1gzI+lgLIOPV0YyUfWMKgl24iJsGN6W5Vk+4GfDE7jKGkti9ZsswaJ/1 
Un+zFpXlVCOjEe9CZz3npIEKG8jJL1rwnBc2qPY3YD8jWBhLaPUgchbxUbe1Q2eK 
DmlRF7B8BzeNG4aVdQIDAQAB 
-----END PUBLIC KEY-----""" 

message = 'To be signed' 
key = RSA.generate(1024) 
pub_key = key.publickey().exportKey(public_key) 
priv_key = key.exportKey(private_key) 

h = SHA256.new(message) 
print '-----------------' 
signer = PKCS1_v1_5.new(key) 
signature = signer.sign(h) 
print signature 
hexlify = codecs.getencoder('hex') 
m = hexlify(signature)[0] #<--- I am sending this hex signature to JS. 
#--------------Code below is to test the verify in python, n it works ! 
h = SHA256.new('To be signed') 
verifier = PKCS1_v1_5.new(key.publickey()) 
if verifier.verify(h, signature): 
    print "The signature is authentic." 
else: 
    print "The signature is not authentic." 

進行測試,以驗證在JS,我使用this演示示例頁面。它寫在頁面上的Signature值應該是十六進制編碼的'RSASSA-PKCS1-v1_5'簽名,所以這就是爲什麼我在python中將我的簽名轉換爲十六進制值,但簽名仍然不匹配JS。

我注意到了python代碼中的一件奇怪的事情,那就是當我用生成一個簽名的時候,修改了的私鑰,簽名是不一樣的。這是正常的嗎?但在JS中,它每次都給我一個固定的簽名。

注意:JS DEMO示例頁面有一個小錯誤,請轉到源代碼並將rsa.signString更改爲rsa.sign。並且,將rsa.verifyString更改爲rsa.verify。我在他的Github上提出this issue,他說他會很快修復它。

+0

我希望這只是一個虛擬的/一次性私鑰你剛纔張貼在這裏:) –

+0

@TimPietzcker你希望對:) –

回答

1

當我用固定的私鑰生成一個簽名時,簽名是不一樣的。這是正常的嗎?

不正常。對於PKCS#1 v1.5,簽名應始終與相同的私鑰相同。

檢查以下內容:

  • 的SHA256哈希正好在兩個同樣的目的
  • 我不是一個Python的專家,但它也似乎不可思議,你在呼喚RSA.generate()的時候您已經擁有密鑰

鑑於您的Python代碼每次都給出不同的簽名,所以我會將調查集中在該部分。如果輸入數據中的單個字節不同,則生成的散列值不同 - 因此請檢查您的Python代碼,如果散列值使用相同的輸入數據更改。

0

有人發佈了一個答案,提示我檢查python代碼,並告訴它不正常以獲得不同的簽名以獲得固定的私鑰。我不知道他爲什麼刪除了答案,但他的觀察是正確的。其實我在Python中獲取密鑰對的方式是完全錯誤的。我每次生成新的密鑰對並將其導出到本地變量pub_key & priv_key。相反,我應該做這樣的事情;

#key = RSA.generate(2048) 
#pub_key = RSA.publickey().exportKey(public_key) 
priv_key = RSA.importKey(private_key) 
pub_key = RSA.importKey(public_key) 

就這樣,我得到這個固定的私鑰簽名相同,而它真正的JS代碼簽名相匹配:d ...

+1

這是我的答案。我意識到我也有一些關於你的密鑰大小的錯誤觀察,所以我最終刪除了答案。由於您發現它有幫助,所以我將其刪除並重新修改了一下。 – quinz