前言
公司的接口全部采用 libsodium
加密了,导致接口测试非常不方便;
先前,也找到了pynacl
,但是钻研了好久始终没成功,网上搜了个遍,没有看到一个完整的可适用的例子,心塞;
然后,曲线救国,把 JAVA
的加密方法打包成 jar
包,然后 Python
调 jar
去执行加解密方法。能用,但是心里不爽,毕竟走了弯路;
然后又开始钻研pynacl
。其实 python
的 libsodium
库有好几个,具体可以看这里,而pynacl
是 star 最多的,所以就选择这个;
然后反复*100次对比 java
的加解密步骤及转码方式,最终调通了 Python
的,看到最终的代码其实也不难,但是官方文档都没有太好的例子,我是通过pynacl
项目的测试用例找到的具体怎么调用,才最终完成代码,实属不易;
安装pynacl
pip install pynacl
代码
# @author: chengjie142039
# @file: libsodium.py
# @time: 2020/12/24
# @desc: python libsodium 加解密
try:
from nacl.encoding import HexEncoder, Base64Encoder
from nacl.public import Box, PrivateKey, PublicKey
except ImportError:
raise ImportWarning('python环境中未找到nacl,请先执行 pip install pynacl 进行安装')
def encrypt(public_key: str, private_key: str, nonce: str, plain_text: str):
"""
libsodium 加密
:param public_key: 公钥
:param private_key: 私钥
:param nonce: 随机码
:param plain_text: 加密文本
:return:加密后的密文,str 类型
"""
if len(public_key) != 64:
raise ValueError('public_key 长度必须为64')
if len(private_key) != 64:
raise ValueError('private_key 长度必须为64')
if len(nonce) != 32:
raise ValueError('nonce 长度必须为32')
# 公钥转 bytes,注意encoder指定HexEncoder
public = PublicKey(
public_key.encode(),
encoder=HexEncoder,
)
# 私钥转 bytes,注意encoder指定HexEncoder
private = PrivateKey(
private_key.encode(),
encoder=HexEncoder,
)
# 生成 box
box = Box(private, public)
# 随机码先转成 bytes,再 base64 decode
nonce_bytes = Base64Encoder.decode(nonce.encode())
encrypted = box.encrypt(
plain_text.encode(),
nonce_bytes
)
ciphertext = Base64Encoder.encode(encrypted.ciphertext)
return str(ciphertext, encoding="utf8")
def decrypt(public_key: str, private_key: str, nonce: str, ciphertext: str):
"""
libsodium 解密
:param public_key: 公钥
:param private_key: 私钥
:param nonce: 随机码
:param ciphertext: 密文
:return: 解密后的文本,str 类型
"""
if len(public_key) != 64:
raise ValueError('public_key 长度必须为64')
if len(private_key) != 64:
raise ValueError('private_key 长度必须为64')
if len(nonce) != 32:
raise ValueError('nonce 长度必须为32')
public = PublicKey(
public_key.encode(),
encoder=HexEncoder,
)
private = PrivateKey(
private_key.encode(),
encoder=HexEncoder,
)
box = Box(private, public)
nonce_bytes = Base64Encoder.decode(nonce.encode())
ciphertextByte = Base64Encoder.decode(ciphertext.encode())
decrypted = box.decrypt(ciphertextByte, nonce_bytes)
return str(decrypted, encoding='utf-8')
if __name__ == '__main__':
# pass
import json
public = '5116b4433193568bf77c0a036f7cbe2476bd4701d7c2083bb8f397c56ee83255'
private = '749ac37351cf4c0232958227018658f1f67490337f4b48dd40c622b65345c099'
nonce = 'luN2OEQoVCXQUPwCa9Fu7n22mmnewqe1'
text = json.dumps({"password": "123456", "jigsawVerificationCode": {"offset": "", "token": ""}, "account": "LS5"})
ciphertext = encrypt(public, private, nonce, text)
print(ciphertext)
text_1 = decrypt(public, private, nonce, ciphertext)
print(text_1)
使用
调用encrypt()
加密
调用decrypt()
解密
网友评论