概念
RSA算法是一种非对称密码算法,所谓非对称就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。加密解密是公钥加密、私钥解密,加密主要用对方的公钥,解密用自己的私钥;签名验签是私钥签名、公钥验签,签名用自己的私钥,验签用对方的公钥。
RSA密钥生成
执行openssl.exe
打开openssl文件夹下bin文件夹,执行openssl.exe,如下图:
生成原始RSA私钥
输入“genrsa -out rsa_private_key.pem 1024”命令回车,在bin文件夹中会生成一个rsa_private_key.pem文件,此文件为C端的原始私钥,请妥善保存。
生成PKCS8编码的私钥
输入“pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt”命令回车,将显示生成的PKCS8编码格式的私钥,右键点击openssl窗口上边边缘,选择“编辑标记”,选中要复制的PKCS8私钥(下图红框内的内容),再选择“编辑复制”,把复制的PKCS8私钥内容保存在一个新的文本文件中,并去掉空格和换行,妥善保存该文件,这是C端请求签名时需要用到的私钥。
生成RSA公钥
输入“rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem”命令回车,在bin文件夹中会生成一个rsa_public_key.pem文件。
用文本编辑器打开rsa_public_key.pem文件,删除文件头 “—–BEGIN PUBLIC KEY—–”与文件尾“—–END PUBLIC KEY—–”及空格、换行,如下图。最后得到一行字符串,这就是C端需要提供给S端的公钥,S端用此公钥来校验C端的数据签名的合法性。
代码实现
安装
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
链接:
rsa_pem:http://download.csdn.net/download/u011845833/9840947
https://pypi.python.org/pypi/pycrypto/2.6.1
http://tool.chacuo.net/cryptrsaprikey
赞助
如果您认为以上内容对您有所帮助或者您心情好,不妨支持我一下,谢谢。