资讯专栏INFORMATION COLUMN

python 实现私钥加密公钥解密

lewinlee / 2220人阅读

摘要:实现私钥加密公钥解密业界普遍的用法是公钥用来加密,私钥来解密,许多人却不知道也可以用私钥加密,公钥来解密基础知识对称加密非对称加密公私钥的几个常见格式图片来源使用私钥加密待编辑使用公钥解密参考文档的实现公钥格式如下,若公钥已经是格式,则无需

python 实现私钥加密公钥解密

业界普遍的用法是公钥用来加密,私钥来解密,许多人却不知道也可以用私钥加密,公钥来解密

基础知识 对称加密 非对称加密 公私钥的几个常见格式
图片来源: https://www.openssl.org/docs/...

使用私钥加密

待编辑

使用公钥解密

参考文档:

https://www.cnblogs.com/masak...
https://www.linuxidc.com/Linu...
python2.7 的实现
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
python3 的实现
# 系统库
import six
import logging
import coloredlogs
# 第三方库
import rsa
import base64

p = logging.getLogger()
console_formatter = logging.StreamHandler()
console_formatter.setFormatter(coloredlogs.ColoredFormatter("%(asctime)s - %(module)-14s[line:%(lineno)3d] - %(levelname)-8s: %(message)s"))
p.addHandler(console_formatter)
p.setLevel(logging.DEBUG)

PUB_KEY_STRING = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsKfRext58G0buLDabQQNBVWEB1/B62PapiZ2tSiITw/3X4cI00QB6m7dryMqs7pKntUD3MTGeMCj9zwXX0kmqkrA8og0H0eOHQnAeuw671lkSVYnD1YVcICPv+fbJ1JL+DP3RkXuy0+V2iQC2GDQmfgTcKVowU4c+ToQIp0pUBQIDAQAB"


class DecryptByPublicKey(object):
    """
        先产生模数因子
        然后生成rsa公钥
        再使用rsa公钥去解密传入的加密str
    """
    def __init__(self, encrypt_text):
        self._encrypt_text = encrypt_text
        self._pub_string_key = PUB_KEY_STRING
        # 使用公钥字符串求出模数和因子
        self._modulus = None   # 模数
        self._exponent = None  # 因子
        # 使用PublicKey(模数,因子)算出公钥
        self._pub_rsa_key = None

    def _gen_modulus_exponent(self, s) ->int:
        p.debug("Now base64 decode pub key,return modulus and exponent")
        # 对字符串解码, 解码成功返回 模数和指数
        b_str = base64.b64decode(s)
        if len(b_str) < 162:
            return False
        hex_str = b_str.hex()
        # 找到模数和指数的开头结束位置
        m_start = 29 * 2
        e_start = 159 * 2
        m_len = 128 * 2
        e_len = 3 * 2
        self._modulus = int(hex_str[m_start:m_start + m_len], 16)
        self._exponent = int(hex_str[e_start:e_start + e_len], 16)

    def _gen_rsa_pubkey(self):
        # 将pub key string 转换为 pub rsa key
        p.debug("Now turn key string to rsa key")
        try:
            rsa_pubkey = rsa.PublicKey(self._modulus, self._exponent)
            # 赋值到_pub_rsa_key
            self._pub_rsa_key = rsa_pubkey.save_pkcs1()
            # p.debug("self._pub_rsa_key:{}".format(self._pub_rsa_key))
        except Exception as e:
            p.error(e)
            p.error("Invalid public_key")
            raise e

    def decode(self) ->str:
        """
        decrypt msg by public key
        """
        p.debug("Now decrypt msg by public rsa key")
        b64decoded_encrypt_text = base64.b64decode(self._encrypt_text)
        public_key = rsa.PublicKey.load_pkcs1(self._pub_rsa_key)
        encrypted = rsa.transform.bytes2int(b64decoded_encrypt_text)
        decrypted = rsa.core.decrypt_int(encrypted, public_key.e, public_key.n)
        # p.debug("decrypted: {}".format(decrypted))
        decrypted_bytes = rsa.transform.int2bytes(decrypted)
        # 这里使用了six库的iterbytes()方法去模拟python2对bytes的轮询
        if len(decrypted_bytes) > 0 and list(six.iterbytes(decrypted_bytes))[0] == 1:
            try:
                raw_info = decrypted_bytes[decrypted_bytes.find(b"x00")+1:]
            except Exception as e:
                p.error(e)
                raise e
        return raw_info.decode("utf-8")

    def decrypt(self) -> str:
        """
        先产生模数因子
        然后生成rsa公钥
        再使用rsa公钥去解密
        """
        self._gen_modulus_exponent(self._pub_string_key)
        self._gen_rsa_pubkey()
        ret = self.decode()
        return ret


if __name__ == "__main__":
    encrypt_text = "xxxxxx"  # encrypt_text 是被私钥加密后的密文
    result = DecryptByPublicKey(encrypt_text).decrypt()
    p.info(result)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42934.html

相关文章

  • Python&Java互通rsa加密解密

    摘要:我们只考虑能解密就行明文公钥加密,私钥解密密文明文公钥私钥使用生成格式的公钥私钥文件。直接使用该密钥需要转换为格式公钥私钥,密钥字符串不需要。库安装会有环境问题,直接安装成功,安装失败。 记录一次项目使用RSA加解密 项目使用Java和Python在开发,RSA加密解密互通代码: Python代码 # -*- coding: utf-8 -*- RSA加解密 import base...

    Arno 评论0 收藏0
  • Python的RSA加密和PBE加密

    摘要:最近在写接口的时候,遇到了需要使用加密和加密的情况,对方公司提供的都是的,我需要用来实现。于是,小明通过事先老板给他的公钥来加密情报。使用对方公司的公钥对所有的参数进行加密,加密之后进行编码。 最近在写接口的时候,遇到了需要使用RSA加密和PBE加密的情况,对方公司提供的DEMO都是JAVA的,我需要用python来实现。在网上搜了一下,python的RSA加密这块写的还是比较多的,但...

    Tony_Zby 评论0 收藏0
  • 非对称加密算法-RSA

    摘要:非对称加密,加密与解密使用的密钥不是同一密钥,对中一个对外公开,称为公钥,另一个只有所有者知道,称为私钥。对称加密算法不能实现签名,因此签名只能非对称算法。正因为,这种加密是单向的,所以被称为非对称加密算法。 非对称加密,加密与解密使用的密钥不是同一密钥,对中一个对外公开,称为公钥,另一个只有所有者知道,称为私钥。用公钥加密的信息只有私钥才能解开,反之,用私钥加密的信息只有公钥才能解开...

    gggggggbong 评论0 收藏0
  • 聊聊公钥私钥

    摘要:是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被推荐为公钥数据加密标准。算法基于一个十分简单的数论事实将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。 在编程中,我们为了保证数据安全,免不了要经常进行数据加密,于是产生了各种各样的加密算法.无论怎样,都还是存在被破解的风险.今天就来说说RSA算法. 背景 R...

    Stardustsky 评论0 收藏0
  • 慕课网_《Java实现非对称加密》学习总结

    摘要:时间年月日星期三说明本文部分内容均来自慕课网。秘密密钥,生成一个分组的秘密密钥。 时间:2017年4月12日星期三说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:https://github.com/zccodere/s...个人学习源码:https://github.com/zccodere/s... 第一章:概述 1-1 概述 非对称...

    dailybird 评论0 收藏0

发表评论

0条评论

lewinlee

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<