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

2018-11-08 17:38:52 +08:00
 cruithne
百度了一天,用 rsa 模块,会报错:'str' object has no attribute 'n'
看了一下源码,大概意思是公钥私钥要通过 rsa 模块生成,公钥是一个对象,自带了 n 这个属性,我自己传一个 str 是不行的。可是我已有公钥,只想将字符串加密,该怎么搞?
7602 次点击
所在节点    Python
22 条回复
justfly
2018-11-08 17:44:46 +08:00
RSA 库肯定有 API 用来把你的字符串格式公钥 Load 到一个 PublicKey 对象啊,找找呗。
ThirdFlame
2018-11-08 17:49:41 +08:00
读公钥 得到 n e , 密文=libnum.n2s(pow(libnum.s2n('字符串'),e,n))
WordTian
2018-11-08 17:55:41 +08:00
不能,私钥加密,公钥解密,这是常识。
boom7
2018-11-08 18:02:03 +08:00
用 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()))
phithon
2018-11-08 18:06:32 +08:00
@WordTian
加密:公钥负责加密,私钥负责解密。
签名:私钥负责签名,公钥负责校验。
Yanni0507
2018-11-08 18:34:08 +08:00
@WordTian 这不是常识,你说反了....
summic
2018-11-08 18:39:21 +08:00
@WordTian 这不是常识,你说反了....

PHP 版本对应函数:
penssl_public_encrypt

另外还有几个函数一起看:
openssl_​ private_​ decrypt
openssl_​ private_​ encrypt
openssl_​ public_​ decrypt
openssl_public_encrypt
Leigg
2018-11-08 18:41:39 +08:00
专门写一篇文章实现这个,用 python 实现的
https://blog.csdn.net/sc_lilei/article/details/83027970
belin520
2018-11-08 18:44:04 +08:00
楼上的回复尴尬了?
znood
2018-11-08 18:44:15 +08:00
@WordTian 按你这么说 tls 怎么通信?
WordTian
2018-11-08 18:53:18 +08:00
尴尬了。。。
居然记错了,还是理解不到家

感谢各位指正
@phithon
@Yanni0507
@summic
@znood
bp0
2018-11-08 19:46:46 +08:00
@WordTian 你说的没错,只是没说全。

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

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

上面其他人说公钥用来验证签名。不过,验证签名的原理就是在解密,而不是加密。
leavic
2018-11-08 21:16:26 +08:00
@WordTian 私钥和公钥是对等的,哪个算私钥哪个算公钥完全看应用。
xml123
2018-11-08 21:19:26 +08:00
实际上加密和解密用的算法是完全一样的
37Y37
2018-11-08 22:27:22 +08:00
看看这个文章
https://mp.weixin.qq.com/s/dpGqieL4WCmGdQh1AEG4Gw

里边一段 python3 代码实现生成秘钥并加解密的功能:
```
import binascii
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_v1_5


class RsaCrypto():
'''RSA 加解密'''

def create_rsa_key(self):
'''生成 RSA 秘钥对'''
try:
key = RSA.generate(2048)
encrypted_key = key.exportKey(pkcs=8)

public_key = key.publickey().exportKey().decode('utf-8')
private_key = encrypted_key.decode('utf-8')

return {'state': 1, 'message': {'public_key': public_key, 'private_key': private_key}}
except Exception as err:
return {'state': 0, 'message': str(err)}

def encrypt(self, public_key, plaintext):
'''加密方法'''
try:
recipient_key = RSA.import_key(public_key)
cipher_rsa = PKCS1_v1_5.new(recipient_key)

en_data = cipher_rsa.encrypt(plaintext.encode('utf-8'))
hex_data = binascii.hexlify(en_data).decode('utf-8')

return {'state': 1, 'message': hex_data}
except Exception as err:
return {'state': 0, 'message': str(err)}

def decrypt(self, private_key, hex_data):
'''解密方法'''
try:
private_key = RSA.import_key(private_key)
cipher_rsa = PKCS1_v1_5.new(private_key)

en_data = binascii.unhexlify(hex_data.encode('utf-8'))
data = cipher_rsa.decrypt(en_data, None).decode('utf-8')

return {'state': 1, 'message': data}
except Exception as err:
return {'state': 0, 'message': str(err)}


if __name__ == '__main__':
print(RsaCrypto().create_rsa_key())
```
20150517
2018-11-09 03:03:39 +08:00
rsa 的 key 是用来加密 key 的,rsa 加密长字串效率特别低,一般是用 aes 加密,再把 aes 密码用 rsa 加密发出来
msg7086
2018-11-09 08:56:50 +08:00
公钥和私钥的区别在于私钥包含了完整的密钥对而公钥只含有其中一个密钥(即只有半个密钥对)。
metrxqin
2018-11-09 09:09:29 +08:00
@WordTian I feel pity for you.
1010543618
2018-11-09 09:09:45 +08:00
以前看书总结的

## 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
CloudMx
2018-11-09 09:15:46 +08:00
非对称加密嘛,我发布出去的就叫公钥,自己保留的就叫私钥。
用公钥加密后,用私钥解密。
用私钥加密后,用公钥解密。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/505860

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX