Python + PHP + RSA 实现加密(解决Python-RSA无法解密一般字符串的问题)
来源:互联网 发布:matlab矩阵循环赋值 编辑:程序博客网 时间:2024/05/16 14:26
摘要
微信校园卡需要一个能够加密的Python中继和PHP后台,由于是对短字符串的加密,并且考虑到效率,所以想要使用一种非对称加密的方法进行加密,RSA就是其中一种
最终实现的效果是:PHP后台对数据进行加密后生成二维码,通过扫码枪输入到Python中继后,通过与后台通信判定当前二维码合法性(当然,这只是个DEMO,生产环境下,私钥应该是放在Python端的)
严重的问题
(1) RSA模块使用base64转码后的密文进行解密操作
问题在于在PHP中用了base64进行解码 T.T
具体参考下文中的:《Python base64编码的问题》(2) Python-RSA 模块使用的public key 开头是—–BEGIN RSA PUBLIC KEY—–,而有些模块,如PHP的,文件开头就不是这个,这会导致public key文件读取失败:
需要注意的问题
- url转码(urlencode)
- RSA加密等级对系统速度的影响
- 最好用POST传递哦,安全又方便
PHP实现
参考: http://blog.csdn.net/wsliangjian/article/details/45867351
加密信息,并生成二维码
public function gen_qr(){ $uid = "201621060701"; $time = $this->get_time(); $text = $uid.$time; $text = $this->rsa->encrypt_public($text); if(FALSE == $text){ echoJSON(500,"加密失败"); } $data = [ 'en_text' => $text, 'text' => $uid.$time ]; /* 生成二维码并显示 */ show_QR();}
RSA封装
<?php/* 使用openssl实现非对称加密 */class RSA{ private $private_key = '-----BEGIN RSA PRIVATE KEY-----MIICWgIBAAKBgQC8bNv2gSyf60muXcXkrOsAo3DkONaDSCFccu6WsvKrHHuXTEmZUdfvyrTFj1oLEK9yqgBOPTb9aVpejPAyhYDwECUF/KHOWjaPMHhgSqfrfLEag/V+dfasdffasdfdfefadvBTsNmxnNPa/CCFC11Lbch2GvEE1aWx8VsQx+f91x3sq3sqvKHJjqQD+ZOLKaoh6zWeQhHn9nNPNUVsQx+f91x3sqVsQx+f91x3sqVsQx+f91xsBTsNmxnNPa/CCFC11Lbch2GvEE1aWx8VsQx+f91x3sqwefgsdgadg234g234gegavKHJjqQD+ZOLKaoh6zWeQhHn9nNPNUJBTsNmxnNPa/CCFC11Lbch2GvEE1aWx8fdvKHJjqQD+ZOLKaoh6zf91x3sqBTsNmxnNPa/CCsdscssFC11Lbch2GvEE1aWx8VsvKHJjqQD+ZOLKaoh6zWeQhHn9nNPNUgT47jtJGL+EFuHmQI/LBTsNmxnNPa/CCFCvKHJjqQD+ZOLKaoh6zWeQhHn9nNPNUR8+ZuqJzgo-----END RSA PRIVATE KEY-----'; private $public_key = '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8bNv2gSyf60muXcXkrOsAo3DkONaDSCFccu6WsvKrHHuXTEmZUdfvyrTFj1oLEK9yqgBOPTb9aVpejPAyhYDwECUF/KHOWjaPMHhgSqfrfLEag/V+rT86qdpj0HVgMDPw4ctfpHBe6rTMJnC+mUbfaWLOS8fsEDAfIwWEf5/jGQIDAQAB-----END PUBLIC KEY-----'; /* 使用公钥加密 */ public function encrypt_public($data){ /* 判断公钥是否是可用的 */ $pu_key = openssl_pkey_get_public($this->public_key); if($pu_key==FALSE) { return FALSE; }else{ $encrypted = ""; openssl_public_encrypt($data,$encrypted,$pu_key);//公钥加密 $encrypted = base64_encode($encrypted); return $encrypted; } } /* 使用密钥解密 */ public function decrypt_private($encrypted_data){ /* 判断私钥是否是可用的 */ $pi_key = openssl_pkey_get_private($this->private_key); if($pi_key==FALSE) { return FALSE; }else{ $decrypted = ""; openssl_private_decrypt(base64_decode($encrypted_data),$decrypted,$pi_key);//私钥解密 return $decrypted; } }}?>
Python base64编码的问题
Python环境下RSA编解码请参考:
https://stuvel.eu/files/python-rsa-doc/usage.html
http://www.cnblogs.com/renfanzi/p/6062261.html但是,在将PHP中所生成的加密字符串传入Python中时,出现了字符串冲突的问题:
在网上搜索了以下资料,发现并没用什么可用的讯息。 然后,通过debug RSA模块的加密函数的返回值后发现,输出的大概是这么个东西:
b"%k\xd9\xb6\xc5\xde\x19\x86\xf00#\x80s\x17\x9b\xb5\x04]\x96\x93\xf9\xd6\x96\xb5j\\\xbb\xbf\xbd\x8f\x07^+\xdfL8=\xee\xf .......
那么答案就很明显了:这TM是个base64 encode过的bytes字符串
因此,我们需要对从PHP处生成的字符串做一些些转码,整个实现的代码如下:
import rsaimport base64# Warning : 这里必须用'rb'模式打开,或者在f.read()后使用encode()函数进行转码with open('./rsa_key/rsa_private_key.pem','rb') as f: privkey = rsa.PrivateKey.load_pkcs1(f.read()) # ALTER : # privkey = rsa.PrivateKey.load_pkcs1(f.read().encode())while(1): try: encrypted_str = input(">>") # 将str转码成bytes encrypted_str = encrypted_str.encode() # 将bytes进行base64编码 encrypted_str = base64.b64decode(encrypted_str) # 进行RSA解码 decrypted_str = rsa.decrypt(encrypted_str, privkey) except Exception as e: print("FAIL, Try Again PLS") continue # 将bytes转为str decrypted_str = decrypted_str.decode() print(decrypted_str)
Python 通过POST与web后台交互
import web # 参考web.pyimport timewhile(1): text = input('>>') url = "http://www.wunyungsumu.cn/WechatCard/u" values = { 'text' : text } result = web.post(url=url, values=values) result_str = str(result, encoding="utf-8") if(result_str=='0'): print("Failed, Try Again Please !") continue uid = result_str[:12] tim = result_str[12:] print("uid:",uid," time:",tim)
Python 网络web封装
web.py
import urllib.parse as upimport urllib.request as urdef get(url): req = ur.Request(url) response = ur.urlopen(req) return response.read()def post(url,values): data = up.urlencode(values).encode(encoding='UTF8') req = ur.Request(url, data) response = ur.urlopen(req) return response.read()# url = 'http://umbra.nascom.nasa.gov/cgi-bin/eit-catalog.cgi'# values = {# 'obs_year': '2011',# 'obs_month': 'March'# }## print(post(url=url, values=values))
实现效果
- Python + PHP + RSA 实现加密(解决Python-RSA无法解密一般字符串的问题)
- Python 和 java的 RSA加密解密
- python实现rsa加密
- python实现aes加密解密,RSA签名和验签,RSA加密解密,并调用接口
- python实现aes加密解密,RSA签名和验签,RSA加密解密,并调用接口
- python下RSA加密解密以及跨平台问题
- python下RSA加密解密以及跨平台问题
- PHP--RSA加密解密
- php rsa加密解密
- Python下RSA加密/解密, 签名/
- php的RSA加密解密算法
- PHP的学习--RSA加密解密
- PHP的AES/RSA加密解密算法
- python rsa加解密
- 加密解密(RSA)
- Android RSA加密解密功能的实现
- RSA加密解密的实现详解_JAVA
- RSA加/解密算法--python实现
- 使用ionic制作app-来自qq圈摘录
- javaMail发送邮件
- 浅读java.util.Map及其实现类(四)
- linux下 Socket send函数和recv函数详解
- 细数目前做的比较好的智能家电
- Python + PHP + RSA 实现加密(解决Python-RSA无法解密一般字符串的问题)
- Android 6.0 运行时权限处理
- Excel文本字符串处理函数left,right,mid,find
- redis发布订阅
- Spring中jdbcTemplate的用法实例
- linux用户态和kernel之间共享内存 --- remap_pfn_range + mmap的实现方式
- EventBus 3.0 从入门到精通——初识EventBus
- 开源智能家居工具整理
- Leetcode题解---Regular Expression Matching Java实现