参考连接:
http://www.51testing.com/html/12/15124112-3725723.html
在线加解密:
http://tool.chacuo.net/cryptaes
用到的公私钥:
public-key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCz7qr6NXTP0OJhx0pQCjgP67Me5ljTftsWCyfD/2QPh+0tCQw6wQ5QGGpF9tDyR4irW3Zq9j31x+GorSIBLuwoUT2YkqafZPTzp1eBTHezVY3zGzbvIE3QYhJs3LN4SuV623aYW8l8Bbej+33vNe2tlqmINtkJpioQRHRJVXheZwIDAQAB
-----BEGIN RSA PRIVATE KEY-----
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALPuqvo1dM/Q4mHHSlAKOA/rsx7mWNN+2xYLJ8P/ZA+H7S0JDDrBDlAYakX20PJHiKtbdmr2PfXH4aitIgEu7ChRPZiSpp9k9POnV4FMd7NVjfMbNu8gTdBiEmzcs3hK5XrbdphbyXwFt6P7fe817a2WqYg22QmmKhBEdElVeF5nAgMBAAECgYEAjt1+HFS9fxRX61MVih/TC7EV8/7poGQlCIeq91Cc3kgK5as9bplDCA2atBqZJQXvWj+w8pS59aDTZ96wFUhwcO3GqdNHB1RRW/3wF0agV0nS2xAoXhNEYocVKPD4LdmYuVYXJo04uDJLRm21QhI24KqMYgOyf3VmGX+ibsPTTyECQQDboYwbAcXlcs+486BBH3331ACF3y9M0iGVLTRpwUQewkgcX+13IZ8/e6VH3pV7qMdEQ1kDiKivHPoE4nS1VcLVAkEA0bo83gwwcRSbdobhqSFQsGzhqiBSurIQ3KPO9fYWGDrMWCqobngYYszxzqmaq3xcF37l5Z65SJJ+f1k+F5giSwJABGq9TJW+ixzB/LA5mtWtTNygnhCc/OiE8GEWWsIeQpgZpyhuuCSe9UHhUw6w5unACClqkt2ettbYWFzNiBAPeQJBAJ+ivonVhVnNcbf6WvG9pglkFzDDgbURrLwFA5c8RP0UZE4HykSrrQQnMzc26b/13LMVqC/rbOTMfPS6HQUgi5kCQQCebJshZiHQwOBo4h7dp9JaN77IQri490RmbCcMGcAqQSNasC99qQ5McErNOJJBR4Iz9g4rLxHfdLt+h8bqNjko
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbNfTwCTjfV11ZTSA/Y4lphim13KmSI3/B0y5wrt4tUtx6f0c9Lc0U7R2ieqZ0hxl/F5SMSwFnpAbvbOIW2XN9EBVa2HY3szoF0ojFhis7m8MfHaUKaf8ulB69IYmBP+rZSg8rs67tpODxAnnI5TJjiDr4gJHRtKhFE9KoUnXYXQIDAQAB
-----END PUBLIC KEY-----
private-key: MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJs19PAJON9XXVlNID9jiWmGKbXcqZIjf8HTLnCu3i1S3Hp/Rz0tzRTtHaJ6pnSHGX8XlIxLAWekBu9s4hbZc30QFVrYdjezOgXSiMWGKzubwx8dpQpp/y6UHr0hiYE/6tlKDyuzru2k4PECecjlMmOIOviAkdG0qEUT0qhSddhdAgMBAAECgYAvM9Kg6X0VV0F5dh43iPLyV635s/kSC5+/95SpClVhXVDWJD0rGvHCynX3wus6hxe28hnoLKtptJWzXN7JaipXxievf7Gpt1O/bkWSRISK1OmwdtqaoPBy1WSCJXgbCO9QjKmM6BMsWlvcJMasBSl8RpSwbAgzZaRuL4ypIhJZdQJBAM7aAr47p+ipTb7eil9kvR93goSwhrl93cSkxtlG7ErPI3VxXrl2UuV5KA41Y57xtI9FRPYxgEAQwb3mOb3u/6sCQQDAFtUMC+sxCAHd/RHoQG76AkDEOgwdYqjB69h71vCnCTiZSYjhtpArg2TPzfX3veJcmz0h5IGfpfB8o2c8lqAXAkABlZ3rwx04JQPZcG7y6ByivxGa3pdJmHM4bGKxi1+H+yo0Xhfxp7xe0ZzC7xnCP+u4JTmwARUQaJBzWe4bTFddAkBLQ+cAjF8AXEHXCIUOusiBH4bfHFuI3BKBwXaWt5ad7IgHz/9ZaZ493oMOxYXeJ8HdRVqDwDRmKK/9Nk2KOP7LAkAUwKLhdtWO3K+Fnyzei/rDJhr/l5lM0DlxyeUdawnvRZRcWwHf3e3Wcrpb4tZm/QRR/gDUZwbk0sLAHqP+Dc0A
代码如下:
1 import re 2 import json 3 import random 4 import binascii 5 6 from Crypto.Cipher import AES 7 from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 8 from Crypto.PublicKey import RSA 9 from flask import Flask, request 10 11 app = Flask(__name__) 12 app.config['JSON_AS_ASCII'] = False 13 app.config['DEBUG'] = True 14 15 16 def encrypt(message): 17 """加密 18 :param message: 19 """ 20 with open('.pem') as f: 21 key = f.read() 22 rsakey = RSA.importKey(key) 23 cipher = Cipher_pkcs1_v1_5.new(rsakey) 24 cipher_text = binascii.b2a_base64(cipher.encrypt(message)) 25 return cipher_text 26 27 28 def decrypt(cipher_text): 29 """RSA解密步骤: 30 1.对cipher_text进行base64解码:binascii.a2b_base64(cipher_text) 31 2.对上一步结果RSA解密:ipher.decrypt() 32 :param cipher_text: 33 """ 34 with open('private.pem') as f: 35 key = f.read() 36 rsakey = RSA.importKey(key) 37 cipher = Cipher_pkcs1_v1_5.new(rsakey) 38 text = cipher.decrypt(binascii.a2b_base64(cipher_text), b'xyz') 39 return text 40 41 42 def aes_encrypt(message, key): 43 """aes加密函数 44 :param key: 45 :param data: 46 """ 47 cipher = AES.new(str.encode(key), AES.MODE_ECB) # 设置AES加密模式 此处设置为ECB模式 48 bs = AES.block_size 49 message = bytes(message, encoding="utf8") 50 print("3333333333333333", message) 51 print(bs) 52 print(len(message)) 53 # # 如data不是16的倍数,则需要补位,utf8中文转gbk才能正确计算位数为2 54 PADDING = lambda s: s + (bs - len(s.encode('gbk')) % bs) * chr(bs - len(s.encode('gbk')) % bs) 55 # encrypted = cipher.encrypt((PADDING(message)).encode(encoding="gbk")) 56 # 转gbk后java解格式不正确,要执行该句则注释message = bytes(message, encoding="utf8")和下面这句 57 encrypted = cipher.encrypt(message) # aes加密 58 result = binascii.b2a_hex(encrypted) # b2a_hex encode 将二进制转换成16进制 59 return result 60 61 62 def aes_decode(data, key): 63 """aes解密 64 :param key: 65 :param data: 66 """ 67 result2 = binascii.a2b_hex(data) # 十六进制还原成二进制 68 cipher = AES.new(key, AES.MODE_ECB) # 默认加密模式AES.MODE_ECB,常用的还有AES.MODE_CBC 69 decrypted = cipher.decrypt(result2) 70 return re.compile('[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f\n\r\t]').sub('', str(decrypted, 71 encoding='utf-8')) # 解密完成后将补位的字符删除 72 73 74 def req_encrypt(message): 75 ''' 76 :param data: 需返回的消息 77 :return: 加密后的消息 78 ''' 79 # one_key1 = str(random.randint(1023508068686366, 9023508068686366)) 80 one_key1 = "8137539783958708" 81 one_key2 = bytes(one_key1, encoding="utf8") 82 # print("onekey2", one_key2) 83 key2 = encrypt(one_key2) 84 # print(key2) 85 key2 = key2[:-1] 86 # print(key2) 87 # print("message:", message) 88 message2 = aes_encrypt(message, one_key1) # python AES_ECB加密后比java少位数 89 # print(message2) 90 response = '{"key": "%s", "content": "%s705e5812a74e12a0a6a957599c38a209", "sign_string": "B+MvMPSdn/lV3P7XqD6EpmsuMO2VLHnS29qXt6c0waZ0Z3mq0t7aKHMExevAgVh7+uWJJqLxQLxXbNHlyRhckdFTMD06Abke0nYhKIuJNOWjcjoNEOYDpOnluRrtabzhvABiqt6EHibs0Vje2UaeZyFuM9Sz9K+i0BVUCljK5Bw="}' % ( 91 key2.decode("utf-8"), message2.decode('utf-8')) 92 93 return response 94 95 96 def req_decode(data): 97 ''' 98 :param data: 原始请求 99 :return: 解密后的请求 100 ''' 101 json_str = data.decode('utf-8') # utf-8解码成string 102 dict_data = json.loads(json_str) 103 key1 = dict_data['key'] 104 onekey1 = decrypt(key1) # RSA解密onekey1 105 # print("key:", onekey1) 106 # print(type(onekey1)) 107 108 content1 = dict_data['content'] 109 # print(content1) 110 content2 = aes_decode(content1, onekey1) # ASE用onekey1解密content1 111 # print(content2) 112 return content2 113 114 115 @app.route('/debtaccountws/openapi/v4/weixinjinke/sendaccountsign', methods=['POST', 'GET']) 116 def sendaccountsign(): 117 """银行卡签约申请发送验证码接口""" 118 req_data = request.data 119 decode_req = req_decode(req_data) 120 print(decode_req) 121 """ 122 To do: 123 输入值校验 124 """ 125 req_no = 'N' + str(random.randint(1018072417502134562855, 9018072417502134562855)) 126 print(req_no) 127 message = '{"returnCode": "000000", "detailMessage": "操作成功","body": {"reqNo":"%s","status":1}}' % (req_no) 128 response = req_encrypt(message) 129 130 print(response) 131 return response 132 133 134 @app.route('/debtaccountws/openapi/v4/weixinjinke/verifyaccountsign', methods=['POST', 'GET']) 135 def verifyaccountsign(): 136 """银行卡签约校验验证码接口""" 137 req_data = request.data 138 decode_req = req_decode(req_data) 139 print(type(decode_req)) 140 """ 141 To do: 142 输入值校验 143 """ 144 req_no = decode_req[10:33] 145 print("req_no: ", req_no) 146 message = '{"returnCode": "000000", "detailMessage": "操作成功","body": {"reqNo": "%s","status": 1,"channelName": "****"}}' % ( 147 req_no) 148 response = req_encrypt(message) 149 print(response) 150 return response 151 152 153 @app.route('/debtaccountws/openapi/v4/weixinjinke/queryaccountsign', methods=['POST', 'GET']) 154 def queryaccountsign(): 155 """银行卡签约查询接口""" 156 req_data = request.data 157 decode_req = req_decode(req_data) 158 print(decode_req) 159 """ 160 To do: 161 输入值校验 162 """ 163 message = '{"returnCode":"000000","detailMessage":"操作成功","body":{"signList":[{"status":1,"requestNo":"N2018072417502134562855","channelName":"**"},{"status":1,"requestNo":"N2018072417502134562855","channelName":"**"}]}}' 164 response = req_encrypt(message) 165 print(response) 166 return response 167 168 169 if __name__ == '__main__': 170 app.run(host='0.0.0.0', port=2018)
pkcs5padding补位python无现成的方法,下面代码可实现(需完善)
1 import re 2 import chardet 3 import binascii 4 5 from Crypto.Cipher import AES 6 7 8 def aes_encrypt(message, key): 9 """aes加密函数 10 :param key: 11 :param data: 12 """ 13 cipher = AES.new(str.encode(key), AES.MODE_ECB) # 设置AES加密模式 此处设置为ECB模式 14 bs = AES.block_size 15 s = bytes(message, encoding="utf8") 16 print("3333333333333333", message) 17 # # 如data不是16的倍数,则需要补位,utf8中文转gbk才能正确计算位数为2 18 print(bs) 19 print(len(s)) 20 print((bs - len(s) % bs) * chr(bs - len(s) % bs)) 21 PADDING = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs) 22 print("PADDING:", PADDING(message)) 23 encrypted = cipher.encrypt((PADDING(message)).encode(encoding="gbk")) # aes加密 24 # print("11111111111", chardet.detect(encrypted)) 25 print(encrypted) 26 result = encrypted 27 # result = binascii.b2a_hex(encrypted) # b2a_hex encode 将二进制转换成16进制 28 print("22222222222", chardet.detect(encrypted)) 29 print("222222222222", result) 30 return result 31 32 33 def aes_decode(data, key): 34 """aes解密 35 :param key: 36 :param data: 37 """ 38 result2 = binascii.a2b_hex(data) # 十六进制还原成二进制 39 cipher = AES.new(str.encode(key), AES.MODE_ECB) # 默认加密模式AES.MODE_ECB,常用的还有AES.MODE_CBC 40 decrypted = cipher.decrypt(result2) 41 # return decrypted 42 message = re.compile('[\\x08\\x0b-\\x0c\\x0e-\\x1f\n\r\t]').sub('', str(decrypted)) 43 print('4444444444444', message) 44 message = bytes(message, encoding="utf8") 45 message = message.decode('utf8') 46 return message # 解密完成后将补位的字符删除 47 48 49 key = '8137539783958708' 50 message = '{"returnCode": "000000", "detailMessage": "操作成功", "body": {"reqNo": "N2815998908977810149916","status": 1,"channelName": "****"}}' 51 data = 'be168ecda5fde039054e7db0e769583103c1c845a4e66aae720c93f438e152d68b795274089f50995e3016865f4db77d8ac28ab17461d503572a185c3b015339dee0d22e5321a7b06df750a9838aefae9bbcd7f1a19be7ed4df83e7ba4dc247cc81dd44c6cff68e46ceeb02e4af87973705332365d3f87d98c74a035ee882344d24c06f57748fbf3f0a84e2d45ba3fbf' 52 result = aes_encrypt(message, key) 53 print("result:", result) 54 decrypted = aes_decode(data, key) 55 print("decrypted:", decrypted)