回答
這是對example in the documentation:
import Crypto.Hash.MD5 as MD5
import Crypto.PublicKey.RSA as RSA
import Crypto.PublicKey.DSA as DSA
import Crypto.PublicKey.ElGamal as ElGamal
import Crypto.Util.number as CUN
import os
plaintext = 'The rain in Spain falls mainly on the Plain'
# Here is a hash of the message
hash = MD5.new(plaintext).digest()
print(repr(hash))
# '\xb1./J\xa883\x974\xa4\xac\x1e\x1b!\xc8\x11'
for alg in (RSA, DSA, ElGamal):
# Generates a fresh public/private key pair
key = alg.generate(384, os.urandom)
if alg == DSA:
K = CUN.getRandomNumber(128, os.urandom)
elif alg == ElGamal:
K = CUN.getPrime(128, os.urandom)
while CUN.GCD(K, key.p - 1) != 1:
print('K not relatively prime with {n}'.format(n=key.p - 1))
K = CUN.getPrime(128, os.urandom)
# print('GCD({K},{n})=1'.format(K=K,n=key.p-1))
else:
K = ''
# You sign the hash
signature = key.sign(hash, K)
print(len(signature), alg.__name__)
# (1, 'Crypto.PublicKey.RSA')
# (2, 'Crypto.PublicKey.DSA')
# (2, 'Crypto.PublicKey.ElGamal')
# You share pubkey with Friend
pubkey = key.publickey()
# You send message (plaintext) and signature to Friend.
# Friend knows how to compute hash.
# Friend verifies the message came from you this way:
assert pubkey.verify(hash, signature)
# A different hash should not pass the test.
assert not pubkey.verify(hash[:-1], signature)
一個充實出的版本據當時資料:
https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA._RSAobj-class.html
你不應該從PyCrypto使用Crypto.PublicKey.RSA.sign功能在實際代碼中:
注意:此功能執行這是簡單的,原始的RSA解密(教科書)。在實際應用中,您總是需要使用適當的加密填充,並且不應該使用此方法直接簽署數據。不這樣做可能會導致安全漏洞。建議使用模塊Crypto.Signature.PKCS1_PSS或Crypto.Signature.PKCS1_v1_5。
我結束了使用實現PKCS1_v1_5的RSA module。 documentation for signing非常簡單。其他have recommended use M2Crypto。
下面是我創建執行所有必要的RSA功能(加密,解密,簽名,驗證簽名&生成新密鑰)
rsa.py
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
from Crypto import Random
from base64 import b64encode, b64decode
hash = "SHA-256"
def newkeys(keysize):
random_generator = Random.new().read
key = RSA.generate(keysize, random_generator)
private, public = key, key.publickey()
return public, private
def importKey(externKey):
return RSA.importKey(externKey)
def getpublickey(priv_key):
return priv_key.publickey()
def encrypt(message, pub_key):
#RSA encryption protocol according to PKCS#1 OAEP
cipher = PKCS1_OAEP.new(pub_key)
return cipher.encrypt(message)
def decrypt(ciphertext, priv_key):
#RSA encryption protocol according to PKCS#1 OAEP
cipher = PKCS1_OAEP.new(priv_key)
return cipher.decrypt(ciphertext)
def sign(message, priv_key, hashAlg="SHA-256"):
global hash
hash = hashAlg
signer = PKCS1_v1_5.new(priv_key)
if (hash == "SHA-512"):
digest = SHA512.new()
elif (hash == "SHA-384"):
digest = SHA384.new()
elif (hash == "SHA-256"):
digest = SHA256.new()
elif (hash == "SHA-1"):
digest = SHA.new()
else:
digest = MD5.new()
digest.update(message)
return signer.sign(digest)
def verify(message, signature, pub_key):
signer = PKCS1_v1_5.new(pub_key)
if (hash == "SHA-512"):
digest = SHA512.new()
elif (hash == "SHA-384"):
digest = SHA384.new()
elif (hash == "SHA-256"):
digest = SHA256.new()
elif (hash == "SHA-1"):
digest = SHA.new()
else:
digest = MD5.new()
digest.update(message)
return signer.verify(digest, signature)
用法示例的helper class
import rsa
from base64 import b64encode, b64decode
msg1 = "Hello Tony, I am Jarvis!"
msg2 = "Hello Toni, I am Jarvis!"
keysize = 2048
(public, private) = rsa.newkeys(keysize)
encrypted = b64encode(rsa.encrypt(msg1, public))
decrypted = rsa.decrypt(b64decode(encrypted), private)
signature = b64encode(rsa.sign(msg1, private, "SHA-512"))
verify = rsa.verify(msg1, b64decode(signature), public)
print(private.exportKey('PEM'))
print(public.exportKey('PEM'))
print("Encrypted: " + encrypted)
print("Decrypted: '%s'" % decrypted)
print("Signature: " + signature)
print("Verify: %s" % verify)
rsa.verify(msg2, b64decode(signature), public)
我覺得這很讓人困惑。 rsa的簽名。加密是''(message,pub_key)''',但是示例用法中的調用是rsa.encrypt(msg1,private)''',使得它看起來需要一個公鑰,但實際上得到一個私鑰。此外,rsa.newkeys()返回兩個值,其中一個來自另一個值(特別是''(x,x.public_key())'''),這與「純英文」解釋'''(公共,私人)''' – mwag 2018-01-20 00:28:43
感謝您指出樣本用法(現在更新)中的錯誤。爲了做加密,你需要調用'rsa.encrypt(msg1,public)'。對於RSA,您需要用於加密和驗證的公共密鑰,解密和簽名需要私鑰。您也可以始終從「私鑰」獲取「公鑰」,但從另一方面來說不可能 – Dennis 2018-01-20 06:49:38
- 1. 使用PyCrypto驗證Google Licensing的RSA簽名
- 2. 如何使Botan RSA簽名驗證與PyCrypto相匹配
- 3. RSA數字簽名驗證
- 4. C#使用RSA簽名和驗證簽名。編碼問題
- 5. 驗證RSA簽名iOS
- 6. RSA在java中籤名和驗證
- 7. 使用DPAPI簽名和驗證數據
- 8. 使用Crypt :: RSA和Crypt :: RSA :: SS :: PSS在Perl中無法驗證RSA PSS簽名
- 9. 澄清RSA簽名驗證參數
- 10. RSA用PHP簽名並用C驗證#
- 11. 使用RSA在iOS上簽名和驗證
- 12. 使用Twitter joauth和RSA-SHA1驗證OAuth1a簽名請求?
- 13. PyCrypto RSA和泡菜
- 14. 如何使用pycrypto和RSA加密(和解密)數據?
- 15. 無法驗證SHA1簽名與RSA
- 16. 簽名驗證ActionScript中的RSA
- 17. 無法驗證Android上的rsa簽名
- 18. SAML RSA FIM(EMC)無法驗證簽名
- 19. RSA使用.Net簽名並使用OpenSSL命令進行驗證
- 20. 使用pyCrypto的RSA python publickey
- 21. C#使用BouncyCastle與RSA簽名數據
- 22. 簽名數據和蟒蛇驗證它
- 23. RSA - PyCrypto和Javascript RSA庫(PidCrypt)ecoding問題
- 24. 使用RSA公鑰驗證JWT簽名PHP
- 25. 使用Base64編碼的公鑰來驗證RSA簽名
- 26. 使用WinCrypt/CryptoAPI驗證基於OpenPGP的RSA簽名
- 27. 使用加密++庫進行RAW RSA簽名驗證
- 28. 使用RSA(PKCS 7)分配/驗證簽名(PKCS 7)
- 29. c#中的RSA簽名和Crypto ++的C++驗證
- 30. OpenSSL RSA簽名和PKCS#1填充不正確驗證
謝謝,這是非常只有一個問題,signature中的''''= RSAkey.sign(hash,「」)'是什麼意思? – 2010-11-20 19:03:38
此外,我看到簽名是一個元組,什麼是以便攜式的方式存儲它的好方法? – 2010-11-20 19:39:45
@Noah McIlraith:對於RSA,不使用第二個參數'K'。對於ElGamal和DSA,需要提供長字符串或隨機數據「K」。詳細信息可在http://www.dlitz.net/software/pycrypto/doc/#crypto-publickey-public-key-algorithms下找到,題目爲「ElGamal和DSA算法」。 – unutbu 2010-11-20 20:16:56