已知公钥,如何用Python将一段字符串进行RSA加密?

百度了一天,用 rsa 模块,会报错:‘str’ object has no attribute 'n’
看了一下源码,大概意思是公钥私钥要通过 rsa 模块生成,公钥是一个对象,自带了 n 这个属性,我自己传一个 str 是不行的。可是我已有公钥,只想将字符串加密,该怎么搞?
已知公钥,如何用Python将一段字符串进行RSA加密?

23 回复

RSA 库肯定有 API 用来把你的字符串格式公钥 Load 到一个 PublicKey 对象啊,找找呗。


from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import base64

def rsa_encrypt(public_key_str, plaintext):
    """
    使用RSA公钥加密字符串
    
    参数:
        public_key_str: PEM格式的公钥字符串
        plaintext: 要加密的明文字符串
    
    返回:
        Base64编码的加密结果
    """
    # 加载公钥
    public_key = RSA.import_key(public_key_str)
    
    # 创建加密器,使用PKCS1_OAEP填充方案
    cipher = PKCS1_OAEP.new(public_key)
    
    # 将字符串转换为字节
    plaintext_bytes = plaintext.encode('utf-8')
    
    # 加密
    encrypted_bytes = cipher.encrypt(plaintext_bytes)
    
    # 转换为Base64方便传输
    encrypted_b64 = base64.b64encode(encrypted_bytes).decode('utf-8')
    
    return encrypted_b64

# 示例用法
if __name__ == "__main__":
    # 示例公钥(PEM格式)
    public_key_pem = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzXoQkQKh6Y8lVg6z8x6v
...(这里应该是完整的公钥内容)...
-----END PUBLIC KEY-----"""
    
    # 要加密的字符串
    message = "Hello, RSA Encryption!"
    
    # 加密
    encrypted = rsa_encrypt(public_key_pem, message)
    print(f"加密结果: {encrypted}")

安装依赖:

pip install pycryptodome

核心要点:

  1. 密钥格式:公钥必须是PEM格式的字符串
  2. 填充方案:使用PKCS1_OAEP(推荐,比PKCS1_v1_5更安全)
  3. 编码处理:加密前需要将字符串转为字节,加密后建议用Base64编码

注意: RSA有长度限制,加密的数据不能超过密钥长度(如2048位密钥最多加密245字节)。对于长文本,通常采用:

  • 加密一个对称密钥(如AES密钥)
  • 用对称密钥加密实际数据

一句话建议: 确保使用正确的填充方案和密钥格式。

读公钥 得到 n e , 密文=libnum.n2s(pow(libnum.s2n(‘字符串’),e,n))

不能,私钥加密,公钥解密,这是常识。

用 pycrypto
例 pkcs1.5:

import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
key = RSA.importKey(base64.b64decode(public_key))
pkcs1 = PKCS1_v1_5.new(key)
pkcs1.encrypt(“123456”.encode()))


加密:公钥负责加密,私钥负责解密。
签名:私钥负责签名,公钥负责校验。

这不是常识,你说反了…

这不是常识,你说反了…

PHP 版本对应函数:
penssl_public_encrypt

另外还有几个函数一起看:
openssl_​ private_​ decrypt
openssl_​ private_​ encrypt
openssl_​ public_​ decrypt
openssl_public_encrypt

专门写一篇文章实现这个,用 python 实现的
https://blog.csdn.net/sc_lilei/article/details/83027970

楼上的回复尴尬了?

按你这么说 tls 怎么通信?

尴尬了。。。
居然记错了,还是理解不到家

感谢各位指正



你说的没错,只是没说全。

准确的说,
公钥加密,私钥解密。可以得到正确的内容。
私钥加密,公钥解密。可以得到正确的内容。

只不过,既然都叫它是公钥了,所以一般没人用他来解密,而是用来加密。

上面其他人说公钥用来验证签名。不过,验证签名的原理就是在解密,而不是加密。

私钥和公钥是对等的,哪个算私钥哪个算公钥完全看应用。

实际上加密和解密用的算法是完全一样的

看看这个文章
https://mp.weixin.qq.com/s/dpGqieL4WCmGdQh1AEG4Gw

里边一段 python3 代码实现生成秘钥并加解密的功能:
<br>import binascii<br>from Cryptodome.PublicKey import RSA<br>from Cryptodome.Cipher import PKCS1_v1_5<br><br><br>class RsaCrypto():<br> '''RSA 加解密'''<br><br> def create_rsa_key(self):<br> '''生成 RSA 秘钥对'''<br> try:<br> key = RSA.generate(2048)<br> encrypted_key = key.exportKey(pkcs=8)<br><br> public_key = key.publickey().exportKey().decode('utf-8')<br> private_key = encrypted_key.decode('utf-8')<br><br> return {'state': 1, 'message': {'public_key': public_key, 'private_key': private_key}}<br> except Exception as err:<br> return {'state': 0, 'message': str(err)}<br><br> def encrypt(self, public_key, plaintext):<br> '''加密方法'''<br> try:<br> recipient_key = RSA.import_key(public_key)<br> cipher_rsa = PKCS1_v1_5.new(recipient_key)<br><br> en_data = cipher_rsa.encrypt(plaintext.encode('utf-8'))<br> hex_data = binascii.hexlify(en_data).decode('utf-8')<br><br> return {'state': 1, 'message': hex_data}<br> except Exception as err:<br> return {'state': 0, 'message': str(err)}<br><br> def decrypt(self, private_key, hex_data):<br> '''解密方法'''<br> try:<br> private_key = RSA.import_key(private_key)<br> cipher_rsa = PKCS1_v1_5.new(private_key)<br><br> en_data = binascii.unhexlify(hex_data.encode('utf-8'))<br> data = cipher_rsa.decrypt(en_data, None).decode('utf-8')<br><br> return {'state': 1, 'message': data}<br> except Exception as err:<br> return {'state': 0, 'message': str(err)}<br><br><br>if __name__ == '__main__':<br> print(RsaCrypto().create_rsa_key())<br>

rsa 的 key 是用来加密 key 的,rsa 加密长字串效率特别低,一般是用 aes 加密,再把 aes 密码用 rsa 加密发出来

公钥和私钥的区别在于私钥包含了完整的密钥对而公钥只含有其中一个密钥(即只有半个密钥对)。

I feel pity for you.

以前看书总结的

## RAS
### 生成密钥
1. 找大整数 p,q (素数测试算法)
2. 根据 N=pq,求 N (乘法)
2. 找任意与(p-1)(q-1)互素的数 e
3. 根据 ed≡(1 mod (p-1)(q-1)),求 d (拓展 Euclid 算法)

此时公钥为(N,e),私钥为(N,d)

### 加密解密
1. 加密:y=x^e mod N
2. 解密:x=y^d mod N

### 破解?
方法 1:尝试所有可能的 x 判断x^e = y mod N是否成立
方法 2:对 N 因式分解,得到 p 和 q,进而计算出 d

非对称加密嘛,我发布出去的就叫公钥,自己保留的就叫私钥。
用公钥加密后,用私钥解密。
用私钥加密后,用公钥解密。

主要是私钥比较长,并且知道公钥也算不出一个对应的私钥

回到顶部