說明: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))