RSA登录python并在JS

时间:2017-07-06 09:53:12

标签: javascript python digital-signature pycrypto

我使用pyCrypto PKCS1_v1_5签名来签名消息。 (Original code

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代码中有一个奇怪的东西,就是说,当我使用 fixed 私钥生成签名时,签名就不一样了。这是正常的吗?但是在JS中它每次都给我固定的签名。

注意:JS DEMO示例页面中有一个小错误,转到源代码并将rsa.signString更改为rsa.sign。另外,将rsa.verifyString更改为rsa.verify。我在他的Github中提出了this issue,他说他很快就会修复它。

2 个答案:

答案 0 :(得分:1)

  

当我生成带有固定私钥的签名时,签名就不一样了。这是正常的吗?

不正常。对于PKCS#1 v1.5,签名应始终与相同的私钥相同。

检查以下内容:

  • 两端的SHA256哈希完全相同
  • 我不是Python专家,但是当你已经拥有密钥时调用RSA.generate()似乎很奇怪

鉴于您的Python代码每次都给出不同的签名,我会集中精力研究该部分。如果输入数据中的单个字节不同,则生成的哈希值会有所不同 - 因此,如果哈希值使用相同的输入数据进行更改,请检查Python代码。

答案 1 :(得分:0)

有人发布了一个答案,建议我检查一下python代码,并告诉我不正常获得固定私钥的不同签名。我不知道他删除答案的原因是什么,但他的观察是正确的。实际上我在python中获取密钥对的方式是完全错误的。我每次生成新的密钥对并将其导出到本地变量pub_key&amp; 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 ...