事出有因
在完成创建数据源的需求时,需要对数据源的用户密码等相关敏感信息进行加密传递,Vue前端加密,Java后端和Python后端解密。经过方案调研后,最终确定采用RSA加解密的方案。
Bug现场
由Java后端通过工具生成公私钥字符串,并将公钥给到前端,前端在创建数据源利用公钥对用户输入的敏感信息进行加密,Java服务接收请求进行校验,并保存。Python服务需要在使用数据源时进行敏感信息解密,此时遇到的问题是,经java服务解密校验通过,而Python则无法进行解密。
迎刃而解
根因分析:
经过对Java服务和Python服务的加解密实现进行深入研究,发现Java中使用的PKCS8,而Python中只有PKCS1,因为此协议不匹配,导致无法解密。
PKCS #1 为 OpenSSH 默认使用的加密标准
PKCS #8 为 Java 默认使用的加密标准
方案1尝试:试图在python的工具包中找到关于PKCS8的实现,未果。
方案2尝试:试图在Java的工具包中找到关于PKCS1的实现,未果。
方案3尝试:经过一番搜索,找到一种思路,将PKCS8生成的私钥转换成PKCS1的私钥,再进行尝试,成功。
完成流程总结
1
| openssl genrsa -out private.pem 1024
|
1 2 3 4 5 6
| -----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQDAQWZDPB5q3B0hKNO8Schw4ihwrJAITWHMMImjSKcRUSbAaKsM 3kLhI8Sx7mPHVW21W6X4MOWyPLAlAOfX3DWNSHBThsJKOEeIlNmZ68MjCE6hWx+W fpUtPWmj8CBNUuZrHmAip4/2TTMHEfJPPzRA5FBmzjH7cn/5w+QlZjeINwIDAQAB ... -----END RSA PRIVATE KEY-----
|
1
| openssl rsa -in private.pem -out public.pem -pubout
|
1
| openssl pkcs8 -topk8 -inform PEM -in private.pem -outform pem -nocrypt -out pkcs8.pem
|
扩展
Python代码片段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import base64
from Crypto.Cipher import PKCS1_v1_5 from Crypto.PublicKey import RSA
PUBLIC_KEY = "MRFM4nWu25GsG+gLwkqClZk1DUva\nKfkKK73ZQ8mcLI3Pbx8zaX+1P38S7KUIOK8QI9gzsIZ0RMamOmrwl4ECAwEAAQ==" PRIVATE_KEY = "MIIBOQIBAA8mcLI3Pbx8z\naX+1P38S7KUIOK8QI9gzsIZ0RMamOmrwl4ECAwEAAQJAdZzQARRCEZ1P9GkIVbVa\naYWcXSe53Paet+YeteIN3xJELq4qYYuYAGlF2HmP9wpKZHXHdmlGEs8fi+pUMEGP\n8QIhAOYVlA5Jihog5jSEb5S2Id7Z7LjrusLs67MtjjQzj3ddAiEAm1QpjN/QzB4l\nRxIHG2BlzwmU/vSJYGH8ePkRMuC8knUCIHF+43HIxN7uq5/sVD4/OaX8SdFONupA\nhGP2bNdDN9nhAiATKYXauD3VAJ8Orn2r9e95ZDA6Z8aO2mfAMNHbWfhJhQIgCtFH\nzTtqqn/mgfftb/9g3vYyBRAz90vlKAaHgd9/U/k="
def decrypt(data: str, private_key: str) -> str: convert_data = base64.b64decode(bytes(data, encoding="utf8")) rsa_key = RSA.importKey(base64.b64decode(private_key)) cipher = PKCS1_v1_5.new(rsa_key) return str(cipher.decrypt(convert_data, "DecryptError"), encoding='utf-8')
def encrypt(data: str, public_key: str) -> str: rsa_key = RSA.importKey(base64.b64decode(public_key)) cipher = PKCS1_v1_5.new(rsa_key) result_data = cipher.encrypt(bytes(data, encoding="utf8")) return str(base64.b64encode(result_data), encoding='utf-8')
if __name__ == '__main__': encrypt_result = encrypt('123456', PUBLIC_KEY) print(encrypt_result) decrypt_data = decrypt(encrypt_result, PRIVATE_KEY) print(decrypt_data)
|
RSA的秘钥类型汇总
RSA的格式转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| openssl genrsa -out private.pem 1024
openssl pkcs8 -topk8 -inform PEM -in private.pem -outform pem -nocrypt -out pkcs8.pem
openssl rsa -in pkcs8.pem -out pkcs1.pem
openssl rsa -in private.pem -pubout -out public.pem
openssl rsa -in pkcs8.pem -pubout -out public_pkcs8.pem
openssl rsa -pubin -in public_pkcs8.pem -RSAPublicKey_out
openssl rsa -RSAPublicKey_in -in pub_pkcs1.pem -pubout
|