zoukankan      html  css  js  c++  java
  • RSA (python)

    what?

    非对称的加密算法,能够保证加密数据的机密性

    why?

    RSA算法的难解性取决于大素数的分解难度,在有限算力的情况下是不能破解的。

    how?

    一、密钥的产生


    1 选取两个保密的大素数 p 和 q
    2 计算 n=pq , fai(n) = (p-1)(q-1)
    3 选一整数 e, 满足 1<e<fai(n), gcd(fai(n),e)=1
    4 计算d, 满足 d.e=1 mod fai(n)

    二、加密


    1 将明文比特串分组,使得每个分组对应的十进制数小于n(分组长度< (log_2n)

    [c=m^c mod n ]

    三、解密


    解密运算 (m=c^d mod n)

    填充模式

    1、RSA_PKCS1_PADDING 填充模式(常用)

    要求

    INPUT:必须必模长(e)短至少11个字节,即 RSA_size(rsa) – 11。如果输入的明文过长,必须切割,然后进行填充。
    OUTPUT: 与模(e)一样长
    据此要求:
    对于512bit的密钥, 填充的长度为 512/8-11=53字节
    对于1024bit的密钥, 填充的长度为 1024/8-11=117字节
    对于2048bit的密钥, 填充的长度为 2048/8-11=245字节
    对于4096bit的密钥, 填充的长度为 4096/8-11=501字节

    2、RSA_PKCS1_OAEP_PADDING

    要求

    INPUT:RSA_size(rsa) – 41
    OUTPUT: 与模(e)一样长

    3、for RSA_NO_PADDING 不填充

    INPUT:可以和RSA钥模长一样长,如果输入的明文过长,必须切割, 然后填充
    OUTPUT:和模(e)一样长

    代码

    #/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    #----rsa 算法 ------#
    """
    1 选取两个保密的大素数 p 和 q
    2 计算 n=p*q , fai(n) = (p-1)*(q-1)
    3 选一整数 e, 满足 1<e<fai(n), gcd(fai(n),e)=1
    4 计算d, 满足 d.e=1 mod fai(n)
    => (e,n)为公钥 ; (d,n)为私钥
    
    e : 模数默认情况下为65537(HEX:10001)
    
    """
    import rsa
    import sys
    import base64
    # 打印 python 版本 与 windows 系统编码
    print("---- 1 ----")
    print(sys.version)
    print(sys.getdefaultencoding())
    print(sys.getfilesystemencoding())
    # 先生成一对密钥,然后保存.pem格式文件,当然也可以直接使用
    print("---- 2 ----")
    (pubkey, privkey) = rsa.newkeys(1024) # 随机生成1024bit的公私钥
    pub = pubkey.save_pkcs1()
    print(type(pub))
    pubfile = open('public.pem','w+')
    pubfile.write(pub.decode('utf-8'))
    pubfile.close()
    print("---- 3 ----")
    pri = privkey.save_pkcs1()
    print(type(pri))
    prifile = open('private.pem','w+')
    prifile.write(pri.decode('utf-8'))
    prifile.close()
    # load公钥和密钥
    print("---- 4 ----")
    message = 'helloxpp'
    print('message:',type(message))
    with open('public.pem') as publickfile:
     p = publickfile.read()
     print(type(p))
     pubkey = rsa.PublicKey.load_pkcs1(p.encode('utf-8')) #pkcs1_padding
    with open('private.pem') as privatefile:
     p = privatefile.read()
     print(type(p))
     privkey = rsa.PrivateKey.load_pkcs1(p.encode('utf-8')) # pkcs1_padding
    # 用公钥加密、再用私钥解密
    crypto = rsa.encrypt(message.encode('utf-8'),pubkey)
    print(crypto)
    print("---- 5 ----")
    print('crypto:',type(crypto))
    print('cry_base64:',base64.encodebytes(crypto))
    print('cry_base64_utf8:',base64.encodebytes(crypto).decode('utf-8'))
    # 保存到本地文件
    cry_file = open('cry_file.txt','w+')
    cry_file.write(base64.encodebytes(crypto).decode('utf-8'))
    cry_file.close()
    print("---- 6 ----")
    # 从本地文件读取
    cry_file = open('cry_file.txt','r')
    cry_text = ''
    for i in cry_file.readlines():
     cry_text += i
    print('cry_text_type:',type(cry_text))
    print('cry_text:',cry_text)
    print('cry_base64:',cry_text.encode('utf-8'))
    crypto_tra = base64.decodebytes(cry_text.encode('utf-8'))
    print("---- 7 ----")
    assert crypto == crypto_tra
    print(crypto)
    print("---- 8 ----")
    plaintext = rsa.decrypt(crypto,privkey)
    assert message == plaintext.decode('utf-8')
    print(plaintext.decode('utf-8'))
    
  • 相关阅读:
    计算函数执行时间
    Go语言生成随机数
    413 Request Entity Too Large
    JavaScript变量与数据类型详解
    OAuth2.0认证详解
    prompt的工作原理
    JS 实现上传图片
    移动端的长按事件的实现
    实现自动关闭当前页面的效果
    前端异常捕获与上报
  • 原文地址:https://www.cnblogs.com/Erma/p/12346359.html
Copyright © 2011-2022 走看看