RSA公钥密码算法实现(基于python,非RSA库)

算法描述就不用说了,其他博客都有,直接上代码:

 

import random
import sys
sys.setrecursionlimit(100000)   #设置迭代次数限制
def main():
    p = BigPrime()
    q = BigPrime()
    n = p*q
    _n = (p-1)*(q-1)
    e = 0
    m = ""
    while(1):
        e = random.randint(1, _n+1)
        if gcd(e, _n)==1:
            break
    d = Ex_Euclid(e, _n)
    print('RSA加密算法开始!\n随机生成的大素数p为', p, '\n随机生成的大素数q为', q, '\n它们的乘积n是', n, '\n随机生成的e为', e, '\n用欧几里得算法可算出d为', d)
    m = input('现在请输入你的明文:')
    print('加密中。。。')
    c = encrypt(m, e, n)
    print('加密成功!密文是:', c)
    flag = input('现在请输入1开始解密:')
    if(flag != '1'):
        print("字数输入错误!")
        return 0
    print('解密中。。。')
    m1 = decrypt(c, d, n)
    print('解密成功!明文是:', m1)
    


    
def MRF(b,n,m):
    
        a=1
        x=b;y=n;z=m
        binstr = bin(n)[2:][::-1]	#通过切片去掉开头的0b,截取后面,然后反转
        for item in binstr:
                if item == '1':
                        a = (a*b)%m
                        b = (b**2)%m
                elif item == '0':
                        b = (b**2)%m
        return a

def MillerRabin(n):
    m = n - 1
    k = 0
    while(m%2==0):
        m = m // 2
        k += 1
    a = random.randint(2,n)
    b = MRF(a, m, n)
    if(b==1):
        return 1
    for i in range(k):
        if(b==n-1):
            return 1
        else:
            b = b * b % n
    return 0

def BigPrime():                     
    Min = 10 ** 22; Max = 10 ** 30; p = 0
    while(1):
        p = random.randrange(Min, Max, 1)
        for i in range(20):
            if MillerRabin(p) == 0:
                break
            elif i == 19:
                return p

def encrypt(m,e,n):
        cipher = ""
        nlength = len(str(hex(n))[2:])  #计算n的16进制长度,以便分组
        message = m             #读取明文
        for i in range(0,len(message),8):
            if i==len(message)//8*8:
                m = int(a2hex(message[i:]),16)  #最后一个分组
            m = int(a2hex(message[i:i+8]),16)
            c = MRF(m,e,n)
            cipher1 = str(hex(c))[2:]
            if len(cipher1)!=nlength:
                cipher1 = '0'*(nlength-len(cipher1))+cipher1    #每一个密文分组,长度不够,高位补0
            cipher += cipher1
        return cipher

def decrypt(c,d,n):
        #加密之后每一个分组的长度和n的长度相同
        cipher = c
        message = ""
        nlength = len(str(hex(n))[2:])
        for i in range(0,len(cipher),nlength):
            c = int(cipher[i:i+nlength],16)     #得到一组密文的c
            m = MRF(c,d,n)
            info = hex2a(str(hex(m))[2:])
            message += info
        return message

def gcd(a, b):
    if a%b == 0:
        return b
    else:
        return gcd(b, a%b)


def Ex_Euclid(x,n):
    r0=n
    r1=x%n
    if r1==1:
        y=1
    else:
        s0=1
        s1=0
        t0=0
        t1=1
        while (r0%r1!=0):
            q=r0//r1  
            r=r0%r1  
            r0=r1  
            r1=r  
            s=s0-q*s1 
            s0=s1 
            s1=s  
            t=t0-q*t1  
            t0=t1  
            t1=t  
            if r==1:
                y = (t+n)%n
    return y


#ascii_to_hex
def a2hex(raw_str):
        hex_str = ''
        for ch in raw_str:
                hex_str += hex(ord(ch))[2:]
        return hex_str
 
#hex_to_ascii
def hex2a(raw_str):
        asc_str = ''
        for i in range(0,len(raw_str),2):
                asc_str += chr(int(raw_str[i:i+2],16))
        return asc_str

if __name__ == "__main__":
    main()

结果展示:

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

篠原明裡-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值