Python libsodium加解密方法

前言

公司的接口全部采用 libsodium 加密了,導致接口測試非常不方便;
先前,也找到了pynacl,但是鉆研了好久始終沒成功,網上搜了個遍,沒有看到一個完整的可適用的例子,心塞;
然后,曲線救國,把 JAVA 的加密方法打包成 jar 包,然后 Python 調 jar 去執行加解密方法。能用,但是心里不爽,畢竟走了彎路;
然后又開始鉆研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()解密

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容