python 實現私鑰加密公鑰解密

python 實現私鑰加密公鑰解密

業界普遍的用法是公鑰用來加密,私鑰來解密,許多人卻不知道也可以用私鑰加密,公鑰來解密

基礎知識

對稱加密

非對稱加密

公私鑰的幾個常見格式

圖片來源: https://www.openssl.org/docs/...

圖片描述

使用私鑰加密

待編輯

使用公鑰解密

參考文檔:

https://www.cnblogs.com/masak...
https://www.linuxidc.com/Linu...

from rsa import PublicKey, common, transform, core

# 公鑰格式如下,若公鑰已經是 RSAPublicKey 格式,則無需將 pub key 轉換爲 string
PUB_KEY_STRING = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsKfRext58G0buLDabQQNBVWEB1/B62PapiZ2tSiITw/3X4cI00QB6m7dryMqs7pKntUD3MTGeMCj9zwXX0kmqkrA8og0H0eOHQnAeuw671lkSVYnD1YVcICPv+fbJ1JL+DP3RkXuy0+V2iQC2GDQmfgTcKVowU4c+ToQIp0pUBQIDAQAB'

class DecryptByPublicKey(object):
    """
    使用 publib key來解密用primary key加密後生成的base64類型的密文
    返回解密後的數據
    """
    def __init__(self, encrypt_text):
        self.encrypt_text = encrypt_text

    @staticmethod
    def str2key(s):
        # 對字符串解碼, 解碼成功返回 模數和指數
        b_str = base64.b64decode(s)
        if len(b_str) < 162:
            return False
        hex_str = ''
        # 按位轉換成16進制
        for x in b_str:
            h = hex(ord(x))[2:]
            h = h.rjust(2, '0')
            hex_str += h
        # 找到模數和指數的開頭結束位置
        m_start = 29 * 2
        e_start = 159 * 2
        m_len = 128 * 2
        e_len = 3 * 2
        modulus = hex_str[m_start:m_start + m_len]
        exponent = hex_str[e_start:e_start + e_len]
        return modulus,exponent

    @staticmethod
    def f(cipher, PUBLIC_KEY):
        """
        decrypt msg by public key
        """
        public_key = PublicKey.load_pkcs1(PUBLIC_KEY)
        encrypted = transform.bytes2int(cipher)
        decrypted = core.decrypt_int(encrypted, public_key.e, public_key.n)
        text = transform.int2bytes(decrypted)
        if len(text) > 0 and text[0] == '\x01':
            pos = text.find('\x00')
            if pos > 0:
                return text[pos+1:]
            else:
                return None

    def pub_decrypt_with_pubkeystr(self):
        """
        將 base64 編碼的 pub_key 轉成 bio 對象,
        再將bio對象轉換成公鑰對象
        """
        # 將 pub key 轉換爲 string
        # Note: 若公鑰已經是 RSAPublicKey 格式,則無需執行這一步 !
        try:
            key = self.str2key(PUB_KEY_STRING) # 將 base64 編碼的公鑰進行拆解,取出模數和指數
            if not key:
                raise Exception, "decode public key falid"
            modulus = int(key[0], 16)
            exponent = int(key[1], 16)
            rsa_pubkey = PublicKey(modulus, exponent) # 根據模數和指數生成 pubkey 對象
            self.pub_key = rsa_pubkey.save_pkcs1()    # 將 pubkey 對象導出爲 RSAPublicKey 格式的公鑰
        except Exception, e:
            assert False, "Invalid public_key"

    
        # 開始解密
        try:
            ret = self.f(self.encrypt_text.decode("base64"), self.pub_key)
        except Exception, e:
            self.error_info = str(e)
            assert False, "Decrypt by public key fails! Invalid encrypt_text"
        return ret

if __name__ == "__main__":
    encrypt_text = 'xxxxxx'  # encrypt_text 是被私鑰加密後的密文
    decrypt = DecryptByPublicKey(encrypt_text)
    result = decrypt.pub_decrypt_with_pubkeystr()
    print result
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章