Python libsodium加解密方法

前言

公司的接口全部采用 libsodium 加密了,导致接口测试非常不方便;
先前,也找到了pynacl,但是钻研了好久始终没成功,网上搜了个遍,没有看到一个完整的可适用的例子,心塞;
然后,曲线救国,把 JAVA 的加密方法打包成 jar 包,然后 Pythonjar 去执行加解密方法。能用,但是心里不爽,毕竟走了弯路;
然后又开始钻研pynacl。其实 pythonlibsodium 库有好几个,具体可以看这里,而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()解密

你可能感兴趣的:(Python libsodium加解密方法)