chaigang 2019-06-30
业界普遍的用法是公钥用来加密,私钥来解密,许多人却不知道也可以用私钥加密,公钥来解密
图片来源: 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
# 系统库 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)