说明:20180321确认Java程序使用security-0.0.1-SNAPSHOT.jar进# 行MD5withRSA签名数据与Python版签名结果signature是一致的,且相互之间可以相互验签成功。 Java版 pkcs8 产生私钥,MD5获取被签名数据特征值,RSA秘钥长度1024
1 from binascii import unhexlify 2 from Crypto.PublicKey import RSA 3 from Crypto.Cipher import PKCS1_OAEP, PKCS1_v1_5 4 import base64 5 from Crypto.Hash import SHA1,MD5 6 from Crypto.Signature import pkcs1_15 7 8 def create_rsa_key(password="123456"): 9 """ 10 创建RSA密钥,步骤说明: 11 1、从 Crypto.PublicKey 包中导入 RSA,创建一个密码(此密码不是RSA秘钥对) 12 2、生成 1024/2048 位的 RSA 密钥对(存储在私钥文件和公钥文件) 13 3、调用 RSA 密钥实例的 exportKey 方法(传入"密码"、"使用的 PKCS 标准"、"加密方案"这三个参数)得到私钥。 14 4、将私钥写入磁盘的文件。 15 5、使用方法链调用 publickey 和 exportKey 方法生成公钥,写入磁盘上的文件。 16 """ 17 key = RSA.generate(1024) 18 encrypted_key = key.exportKey(passphrase=password, pkcs=8,protection="scryptAndAES128-CBC") 19 # encrypted_key = key.exportKey(pkcs=1) 20 print('encrypted_key:',encrypted_key) 21 with open("my_private_rsa_key.pem", "wb") as f: 22 f.write(encrypted_key) 23 with open("my_rsa_public.pem", "wb") as f: 24 f.write(key.publickey().exportKey()) 25 26 def get_private_key(filepath,password="123456"): 27 return RSA.import_key(open(filepath).read(),passphrase=password) 28 29 def get_public_key(filepath): 30 return RSA.importKey(open(filepath).read()) 31 32 def rsa_MD5sign(message,privatekey_filepath,password="123456"): 33 #读取私钥信息用于加签 34 private_key = get_private_key(privatekey_filepath) 35 hash_obj = MD5.new(message) 36 # print(pkcs1_15.new(private_key).can_sign()) #check wheather object of pkcs1_15 can be signed 37 #base64编码打印可视化 38 signature = base64.b64encode(pkcs1_15.new(private_key).sign(hash_obj)) 39 return signature 40 41 def rsa_MD5signverify(message,signature,publickey_filepath): 42 #读取公钥信息用于验签 43 public_key = get_public_key(publickey_filepath) 44 #message做“哈希”处理,RSA签名这么要求的 45 hash_obj = MD5.new(message) 46 try: 47 #因为签名被base64编码,所以这里先解码,再验签 48 pkcs1_15.new(public_key).verify(hash_obj,base64.b64decode(signature)) 49 print('The signature is valid.') 50 return True 51 except (ValueError,TypeError): 52 print('The signature is invalid.') 53 54 55 if __name__ == '__main__': 56 private_key = """-----BEGIN ENCRYPTED PRIVATE KEY----- 57 MIICXAIBAAKBgQDUrqmJYNpui84QJR/cdSjBDsLEqlNTpi0c9WlEo6uIuz7P4FFvbobY2P7MXKE4/qNQCJJB7GMf6LAjP3RE7WdgrgwSbFbppIO2IC6YmZcuYbA2lPJLeFolTMRVterY2vNTKb18oGR9kimqJPtQ0lrgTGRfhyn8HnVyZu+TQMqP6wIDAQABAoGAbMAu8o8ywgn8wSaqhwjlYOpST0uktgYn1UHrpOxn3s+YC6VxHqCOlT1H9Gl9Cu6xxU/MsabU/ND3l95vbntSOx90YTc4NOOjezRxy38obPaaGlNQM6E6R/eTYQfePbGIVlJvauTLJpKcVtBcN36SQe2+QcGfXFqkJ4ZdKoufzkECQQD1fBAz2SavG9r08wOzGUlUViciEXmts3KIEAnl44xMIAyVn4CKqaxxbm4QhREa07DElZqhtd9MRvRdPtt7AAnLAkEA3crlEIjaW+JC9OzSMsVGd9Peh/8trmba96XkNuOuMI5qk51rs2luzfH1kld+h1lYnVN9fito4qXkny+PqwFOYQJBAPCyk6Ry4AZEVr1kZhU+zvK9gqNZ5SfW0o7swvfA1Hhz2EMA4OWVFnsmHw9dmfbm5+TpF3RFwsukqsee8U86K18CQEDSVdRZSwhjvpH6zQxNn+TRpU42BFHeecy7TVHFhVlnpjpyXdHX1KyYNN+Kds50DHQevKStZ0AmoATuT5z5CsECQFGLa3X5nhpc7E5ZboUkNtmrguN43BE2aIdr0crbu56HhFEOZQ/vWxa/Jnu8o+RcsmNlNGcpf5oFTznmiz5eTWQ= 58 -----END ENCRYPTED PRIVATE KEY-----""" 59 public_key = """-----BEGIN PUBLIC KEY----- 60 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUrqmJYNpui84QJR/cdSjBDsLEqlNTpi0c9WlEo6uIuz7P4FFvbobY2P7MXKE4/qNQCJJB7GMf6LAjP3RE7WdgrgwSbFbppIO2IC6YmZcuYbA2lPJLeFolTMRVterY2vNTKb18oGR9kimqJPtQ0lrgTGRfhyn8HnVyZu+TQMqP6wIDAQAB 61 -----END PUBLIC KEY-----""" 62 message = b'123456' 63 privatekey_filepath = "my_private_rsa_key.pem" 64 publickey_filepath = "my_rsa_public.pem" 65 66 # create_rsa_key() 67 # signature = rsa_MD5sign(message,privatekey_filepath) 68 # print('signature:',signature) 69 # signature是java程序使用相同公钥对字符串"123456"的MD5withRSA签名结果 70 signature='n6iuYyfl4vVvOWSVCAlLpK/1ZWscRIYn2Gaql6DcozkXgtfn2r3CnWQPMB4gt+GW2HT7G7ML+B0wMpRPMWwo9VHh5EJzghTiMkRqgjoOAfDNC0gg7fvZVW4XwUv9NdRDh9ij2DO4PmwvQG6JV7mMp1+y6ox89r0MA2w9O5oKaeY=' 71 print(rsa_MD5signverify(message,signature,publickey_filepath))