Python libsodium加解密方法

前言

公司的接口全部采用 libsodium 加密了,導(dǎo)致接口測(cè)試非常不方便;
先前,也找到了pynacl,但是鉆研了好久始終沒成功,網(wǎng)上搜了個(gè)遍,沒有看到一個(gè)完整的可適用的例子,心塞;
然后,曲線救國(guó),把 JAVA 的加密方法打包成 jar 包,然后 Python 調(diào) jar 去執(zhí)行加解密方法。能用,但是心里不爽,畢竟走了彎路;
然后又開始鉆研pynacl。其實(shí) pythonlibsodium 庫(kù)有好幾個(gè),具體可以看這里,而pynacl是 star 最多的,所以就選擇這個(gè);
然后反復(fù)*100次對(duì)比 java 的加解密步驟及轉(zhuǎn)碼方式,最終調(diào)通了 Python 的,看到最終的代碼其實(shí)也不難,但是官方文檔都沒有太好的例子,我是通過pynacl項(xiàng)目的測(cè)試用例找到的具體怎么調(diào)用,才最終完成代碼,實(shí)屬不易;

安裝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環(huán)境中未找到nacl,請(qǐng)先執(zhí)行 pip install pynacl 進(jìn)行安裝')


def encrypt(public_key: str, private_key: str, nonce: str, plain_text: str):
    """
    libsodium 加密
    :param public_key: 公鑰
    :param private_key: 私鑰
    :param nonce: 隨機(jī)碼
    :param plain_text: 加密文本
    :return:加密后的密文,str 類型
    """
    if len(public_key) != 64:
        raise ValueError('public_key 長(zhǎng)度必須為64')
    if len(private_key) != 64:
        raise ValueError('private_key 長(zhǎng)度必須為64')
    if len(nonce) != 32:
        raise ValueError('nonce 長(zhǎng)度必須為32')

    # 公鑰轉(zhuǎn) bytes,注意encoder指定HexEncoder
    public = PublicKey(
        public_key.encode(),
        encoder=HexEncoder,
    )

    # 私鑰轉(zhuǎn) bytes,注意encoder指定HexEncoder
    private = PrivateKey(
        private_key.encode(),
        encoder=HexEncoder,
    )

    # 生成 box
    box = Box(private, public)

    # 隨機(jī)碼先轉(zhuǎn)成 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: 隨機(jī)碼
    :param ciphertext: 密文
    :return: 解密后的文本,str 類型
    """
    if len(public_key) != 64:
        raise ValueError('public_key 長(zhǎng)度必須為64')
    if len(private_key) != 64:
        raise ValueError('private_key 長(zhǎng)度必須為64')
    if len(nonce) != 32:
        raise ValueError('nonce 長(zhǎng)度必須為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)

使用

調(diào)用encrypt()加密

調(diào)用decrypt()解密

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容