V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
cruithne
V2EX  ›  Python

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

  •  
  •   cruithne · 2018-11-08 17:38:52 +08:00 · 7632 次点击
    这是一个创建于 2233 天前的主题,其中的信息可能已经有所发展或是发生改变。
    百度了一天,用 rsa 模块,会报错:'str' object has no attribute 'n'
    看了一下源码,大概意思是公钥私钥要通过 rsa 模块生成,公钥是一个对象,自带了 n 这个属性,我自己传一个 str 是不行的。可是我已有公钥,只想将字符串加密,该怎么搞?
    22 条回复    2019-08-12 23:04:08 +08:00
    justfly
        1
    justfly  
       2018-11-08 17:44:46 +08:00
    RSA 库肯定有 API 用来把你的字符串格式公钥 Load 到一个 PublicKey 对象啊,找找呗。
    ThirdFlame
        2
    ThirdFlame  
       2018-11-08 17:49:41 +08:00
    读公钥 得到 n e , 密文=libnum.n2s(pow(libnum.s2n('字符串'),e,n))
    WordTian
        3
    WordTian  
       2018-11-08 17:55:41 +08:00 via Android
    不能,私钥加密,公钥解密,这是常识。
    boom7
        4
    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
        5
    phithon  
       2018-11-08 18:06:32 +08:00   ❤️ 1
    @WordTian
    加密:公钥负责加密,私钥负责解密。
    签名:私钥负责签名,公钥负责校验。
    Yanni0507
        6
    Yanni0507  
       2018-11-08 18:34:08 +08:00
    @WordTian 这不是常识,你说反了....
    summic
        7
    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
        8
    Leigg  
       2018-11-08 18:41:39 +08:00 via iPhone
    专门写一篇文章实现这个,用 python 实现的
    https://blog.csdn.net/sc_lilei/article/details/83027970
    belin520
        9
    belin520  
       2018-11-08 18:44:04 +08:00
    楼上的回复尴尬了?
    znood
        10
    znood  
       2018-11-08 18:44:15 +08:00 via iPhone
    @WordTian 按你这么说 tls 怎么通信?
    WordTian
        11
    WordTian  
       2018-11-08 18:53:18 +08:00 via Android
    尴尬了。。。
    居然记错了,还是理解不到家

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

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

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

    上面其他人说公钥用来验证签名。不过,验证签名的原理就是在解密,而不是加密。
    leavic
        13
    leavic  
       2018-11-08 21:16:26 +08:00
    @WordTian 私钥和公钥是对等的,哪个算私钥哪个算公钥完全看应用。
    xml123
        14
    xml123  
       2018-11-08 21:19:26 +08:00
    实际上加密和解密用的算法是完全一样的
    37Y37
        15
    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
        16
    20150517  
       2018-11-09 03:03:39 +08:00 via Android
    rsa 的 key 是用来加密 key 的,rsa 加密长字串效率特别低,一般是用 aes 加密,再把 aes 密码用 rsa 加密发出来
    msg7086
        17
    msg7086  
       2018-11-09 08:56:50 +08:00
    公钥和私钥的区别在于私钥包含了完整的密钥对而公钥只含有其中一个密钥(即只有半个密钥对)。
    metrxqin
        18
    metrxqin  
       2018-11-09 09:09:29 +08:00
    @WordTian I feel pity for you.
    1010543618
        19
    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
        20
    CloudMx  
       2018-11-09 09:15:46 +08:00
    非对称加密嘛,我发布出去的就叫公钥,自己保留的就叫私钥。
    用公钥加密后,用私钥解密。
    用私钥加密后,用公钥解密。
    no1xsyzy
        21
    no1xsyzy  
       2018-11-09 10:34:18 +08:00
    @leavic 主要是私钥比较长,并且知道公钥也算不出一个对应的私钥
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1012 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:06 · PVG 05:06 · LAX 13:06 · JFK 16:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.