# RSA学习

xiaoxiao2021-02-28  13

## 概念

RSA算法是一种非对称密码算法，所谓非对称就是指该算法需要一对密钥，使用其中一个加密，则需要用另一个才能解密。加密解密是公钥加密、私钥解密，加密主要用对方的公钥，解密用自己的私钥；签名验签是私钥签名、公钥验签，签名用自己的私钥，验签用对方的公钥。

## 代码实现

### 安装

pip install pycrypto #!/usr/bin/env python # -*- coding: utf-8 -*- """ # @file py_rsa.py # @brief --------------------------------------------------------- 功能简介 RSA的学习 编程环境 python3.5 --------------------------------------------------------- # @version 1.0.0 # @author LindenTao(lindentao@qq.com) # @date 2017/5/13 22:16 """ import base64 from Crypto.Hash import SHA from Crypto import Random from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5 from Crypto.PublicKey import RSA # pkcs8_rsa_private_key.pem test_rsa_private_key.pem test_rsa_public_key.pem message = 'To be encrypted or signed' # 公钥加密 with open('test_rsa_public_key.pem', 'r') as f: key = RSA.importKey(f.read()) h = SHA.new(message.encode()) cipher = Cipher_pkcs1_v1_5.new(key) ciphertext = cipher.encrypt(message.encode() + h.digest()) # ciphertext = base64.b64encode(cipher.encrypt(message.encode())) print(ciphertext) # 私钥解密 with open('test_rsa_private_key.pem', 'r') as f: key = RSA.importKey(f.read()) dsize = SHA.digest_size sentinel = Random.new().read(15 + dsize) cipher = Cipher_pkcs1_v1_5.new(key) message = cipher.decrypt(ciphertext, sentinel) # message = cipher.decrypt(base64.b64decode(ciphertext), sentinel) # print(message) digest = SHA.new(message[:-dsize]).digest() print(message[:len(message) - dsize]) if digest == message[-dsize:]: print("Encryption was correct.") else: print("Encryption was not correct.") # 私钥签名 with open('pkcs8_rsa_private_key.pem', 'r') as f: key = RSA.importKey(f.read()) h = SHA.new(message) signer = Signature_pkcs1_v1_5.new(key) signature = signer.sign(h) # signature = base64.b64encode(signature) print(signature) # 公钥验签 with open('test_rsa_public_key.pem', 'r') as f: key = RSA.importKey(f.read()) h = SHA.new(message) verifier = Signature_pkcs1_v1_5.new(key) is_verify = verifier.verify(h, signature) # is_verify = verifier.verify(h, base64.b64decode(signature)) if is_verify: print("Encryption was correct.") else: print("Encryption was not correct.") print(is_verify)

## 案例

--------------------------------------加密算法---------------------------------------------- 加密算法：RSA 签名算法：SHA1withRSA 签名内容（系统参数+业务参数，值为空的系统参数不参与签名，业务参数为空不参与签名）： 1、系统参数按参数名升序进行排序，按【参数名=值】 的格式拼接，多个参数间用&连接。 示例：TransactionID=20160706220343001&abilityCode=OI_ReverseSubscribe&access_token=ea3333d32-8d2c-b34c-ab32-8013f729a42cd&format=json×tamp=20160706220343&version=1.0 2、把拼接后的系统参数按utf-8字符集编码为 byte 数组 3、把业务参数（即json串）按utf-8字符集编码为 byte 数组 4、分别把系统参数 byte 数组与业务参数byte数组拷贝到新数组，新数组长度为系统参数数组长度+业务参数数组长度 5、对新数组用RSA算法SHA1withRSA签名 系统参数： TransactionID=20160706220343001&abilityCode=OI_ReverseSubscribe&access_token=ea3333d32-8d2c-b34c-ab32-8013f729a42cd&format=json×tamp=20160706220343&version=1.0 业务参数： {"id":1} 私钥: String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKTXezkybtwdL0W2GYZX8hgBrYxTjuwKu+wIBIAT/Fljah+nq1+cEoZPJedh27IG5me1AYytqGr6qnRLWpOJqRf9hXRksIOkU4AripCQ6wU50oAkdh5BL02nBNJJbENbsGK82hSDDcoZNkG5KtnFdvsDE1TymFYVchkiWzpQ0WlFAgMBAAECgYEAoD+21AjaSvO4Q/3eXILcoEfpTjThCUj6HWBB97z2InQJ9BINANp6C8Wf5It2h2A71u/ZPMiJpM5grMOgnzNBhLiK3H4F/JK4wsDlC+7nKzoR41sFh1fcrfuAQi7InqH6mArhJQTTobteWsr94XKwWg6Mt/PCYe5I2e/WHhZ2FKECQQDPzoHoACrkM4FODMiDuQwZKhZoxadkTDFK1U2vRLUtqkjLvBeoWLAydF+uDJTAME6BKAMSbv5AmIxoMyTR8sU9AkEAyxIkk+VOtNAEOg7hoJKCMIVimOih6mqI8RKuV6zT2RVXkfygHqO7hfGfNU9gqsvaLZlvodCLGKUSZWGtJF1EqQJAXzeDRJeXD5sd+3JWCi0nAvzK6dTvH0DeMSjNgKqdzb/BvUCBIo0IpwW1tZ1kJy+7OOjph2++JkD/zNrqWxy/DQJAMHCeewz67lSkfXjpR1VLaumWcGUlonZRPjg3kEBwtFrL7c32H/jslXHiiWPq6jMAU1pDb7UASRuvPLHFDGSXKQJANri/bz0FYAN3MToc1COJ7fCE5ne3N8VqSaOE3SzzRuKdnOf9d00v4GsBo2XYrK9X4TfSUf+VBhz5M9gW/bifiw=="; sign签名值： dPGV+KR8sAT0DJHjJPq+8GmZpDf4jUfSrpsDibYcXhy9F/tcCq+SCUMYMPB9PPib4PNB7A7Cj24/i/9GwtoCS6gV5KK9WqwWxUmJ1J/NuCGh/aFLaZeztrCsEVbyCD65ZvvB/suxiRVfsJhgRRJs6uzfdN5I+i+UyM+HVRJO+Bs= # python代码实现 private_key = "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKTXezkybtwdL0W2GYZX8hgBrYxTjuwKu+wIBIAT/Fljah+nq1+cEoZPJedh27IG5me1AYytqGr6qnRLWpOJqRf9hXRksIOkU4AripCQ6wU50oAkdh5BL02nBNJJbENbsGK82hSDDcoZNkG5KtnFdvsDE1TymFYVchkiWzpQ0WlFAgMBAAECgYEAoD+21AjaSvO4Q/3eXILcoEfpTjThCUj6HWBB97z2InQJ9BINANp6C8Wf5It2h2A71u/ZPMiJpM5grMOgnzNBhLiK3H4F/JK4wsDlC+7nKzoR41sFh1fcrfuAQi7InqH6mArhJQTTobteWsr94XKwWg6Mt/PCYe5I2e/WHhZ2FKECQQDPzoHoACrkM4FODMiDuQwZKhZoxadkTDFK1U2vRLUtqkjLvBeoWLAydF+uDJTAME6BKAMSbv5AmIxoMyTR8sU9AkEAyxIkk+VOtNAEOg7hoJKCMIVimOih6mqI8RKuV6zT2RVXkfygHqO7hfGfNU9gqsvaLZlvodCLGKUSZWGtJF1EqQJAXzeDRJeXD5sd+3JWCi0nAvzK6dTvH0DeMSjNgKqdzb/BvUCBIo0IpwW1tZ1kJy+7OOjph2++JkD/zNrqWxy/DQJAMHCeewz67lSkfXjpR1VLaumWcGUlonZRPjg3kEBwtFrL7c32H/jslXHiiWPq6jMAU1pDb7UASRuvPLHFDGSXKQJANri/bz0FYAN3MToc1COJ7fCE5ne3N8VqSaOE3SzzRuKdnOf9d00v4GsBo2XYrK9X4TfSUf+VBhz5M9gW/bifiw==\n-----END PRIVATE KEY-----" sign_array = 'TransactionID=20160706220343001&abilityCode=OI_ReverseSubscribe&access_token=ea3333d32-8d2c-b34c-ab32-8013f729a42cd&format=json×tamp=20160706220343&version=1.0' busi_array = '{"id":1}' params_str = sign_array + busi_array key = RSA.importKey(private_key) h = SHA.new(params_str) signer = Signature_pkcs1_v1_5.new(key) signature = signer.sign(h) sign = base64.b64encode(signature) print sign