Python实现RSA非对称加密(有界面)

makeprime.py

import random
from random import randint


def proBin(w):  # w表示希望产生位数,生成目标位数的伪素数
    list = []
    list.append('1')  # 最高位定为1
    for _ in range(w - 2):
        c = random.choice(['0', '1'])
        list.append(c)
    list.append('1')  # 最低位定为1
    res = int(''.join(list), 2)
    return res

# 幂模运算


def X_n_mod_P(base, exponent, n):
    bin_array = bin(exponent)[2:][::-1]
    r = len(bin_array)
    base_array = []

    pre_base = base
    base_array.append(pre_base)

    for _ in range(r - 1):
        next_base = (pre_base * pre_base) % n
        base_array.append(next_base)
        pre_base = next_base

    a_w_b = __multi(base_array, bin_array, n)
    return a_w_b % n


def __multi(array, bin_array, n):
    result = 1
    for index in range(len(array)):
        a = array[index]
        if not int(bin_array[index]):
            continue
        result *= a
        result = result % n  # 加快连乘的速度
    return result


def MillerRabin(a, p):  # 素性测试
    if X_n_mod_P(a, p - 1, p) == 1:
        u = (p-1) >> 1
        while (u & 1) == 0:
            t = X_n_mod_P(a, u, p)
            if t == 1:
                u = u >> 1
            else:
                if t == p - 1:
                    return True
                else:
                    return False
        else:
            t = X_n_mod_P(a, u, p)
            if t == 1 or t == p - 1:
                return True
            else:
                return False
    else:
        return False


def testMillerRabin(p, k):  # k为测试次数,p为待测奇数
    while k > 0:
        a = randint(2, p - 1)
        if not MillerRabin(a, p):
            return False
        k = k - 1
    return True


def makeprime(w):           # 产生w位素数
    while 1:
        d = proBin(w)
        for i in range(50):  # 伪素数附近50个奇数都没有真素数的话,重新再产生一个伪素数
            u = testMillerRabin(d+2*(i), 5)
            if u:
                b = d + 2*(i)
                break
            else:
                continue
        if u:
            return b
        else:
            continue


if __name__ == "__main__":  # 测试
    print(makeprime(67))

RSA+模幂运算.py

import numpy as np
import tkinter
from makeprime import makeprime

# 字符与数字之间的映射转换
dict = {'a': '31', 'b': '32', 'c': '33', 'd': '34', 'e': '35', 'f': '36', 'g': '37',
        'h': '38', 'i': '39', 'j': '10', 'k': '11', 'l': '12', 'm': '13', 'n': '14',
        'o': '15', 'p': '16', 'q': '17', 'r': '18', 's': '19', 't': '20', 'u': '21',
        'v': '22', 'w': '23', 'x': '24', 'y': '25', 'z': '26', '1': '41', '2': '42',
        '3': '43', '4': '44', '5': '45', '6': '46', '7': '47', '8': '48', '9': '49',
        '0': '40', ' ': '50', '\n': '51'}

# RSA参数初始化
p, q = 0, 0
n = 0
l = 0
e = 0
d = 0
'''
扩展欧几里的算法
计算 ax + by = 1中的x与y的整数解(a与b互质)
'''


def ext_gcd(a, b):
    if b == 0:
        x1 = 1
        y1 = 0
        x = x1
        y = y1
        r = a
        return r, x, y
    else:
        r, x1, y1 = ext_gcd(b, a % b)
        x = y1
        y = x1 - a // b * y1
        return r, x, y


'''
超大整数超大次幂然后对超大的整数取模
(base ^ exponent) mod n
'''


def exp_mode(base, exponent, n):
    bin_array = bin(exponent)[2:][::-1]
    r = len(bin_array)
    base_array = []

    pre_base = base
    base_array.append(pre_base)

    for _ in range(r - 1):
        next_base = (pre_base * pre_base) % n
        base_array.append(next_base)
        pre_base = next_base

    a_w_b = __multi(base_array, bin_array, n)
    return a_w_b % n


def __multi(array, bin_array, n):
    result = 1
    for index in range(len(array)):
        a = array[index]
        if not int(bin_array[index]):
            continue
        result *= a
        result = result % n  # 加快连乘的速度
    return result


def transferToNum(str):
    m = ""
    for d in str:
        m += dict[d]
    return m


def transferTostr(num):
    n = ""
    for i in range(0, len(num), 2):
        n += {value: key for key, value in dict.items()}[num[i]+num[i+1]]
    return n


def euler(p, q) -> int:
    return (p-1)*(q-1)


def gcd(a, b):
    if a < b:
        return gcd(b, a)
    while a % b != 0:
        temp = b
        b = a % b
        a = temp
    return b


def part1():
    print("part1")
    text_p1_N.delete("1.0", tkinter.END)
    text_p1_L.delete("1.0", tkinter.END)
    text_p1_E.delete("1.0", tkinter.END)
    text_p1_D.delete("1.0", tkinter.END)

    p = makeprime(int(entry_p1_p.get()))
    q = makeprime(int(entry_p1_q.get()))
    ######### N ##############
    n = p*q
    text_p1_N.insert("insert", f"{n}={p}*{q}")
    ######### L ##############
    l = (p-1)*(q-1)
    text_p1_L.insert("insert", f"{l}=({p}-1)*({q}-1)")
    ######### E ##############
    e = 65537                    # 选取e 65537
    text_p1_E.insert("insert", f"e选定为{e}")
    ######### D ##############
    a = e
    b = l
    x = ext_gcd(a, b)[1]
    if x < 0:
        d = x + l
    else:
        d = x
    text_p1_D.insert("insert", f"{d}")

    entry_p1_public_key_E.insert("insert", f"{e}")
    entry_p1_public_key_N.insert("insert", f"{n}")
    entry_p1_private_key_D.insert("insert", f"{d}")
    entry_p1_private_key_N.insert("insert", f"{n}")


def part2():
    print("part2")
    text_p2_plain_byte.delete("1.0", tkinter.END)
    text_p2_cipher_text.delete("1.0", tkinter.END)

    e = int(entry_p2_public_key_E.get())
    n = int(entry_p2_public_key_N.get())
    mingwen_text = text_p2_plain_text.get('1.0', tkinter.END)
    plain_text = int(transferToNum(mingwen_text))
    text_p2_plain_byte.insert("insert", f"plain_text={plain_text}")
    cipher_text = exp_mode(plain_text, e, n)
    text_p2_cipher_text.insert(
        "insert", f"{cipher_text}={plain_text}^{e} % {n}")


def part3():
    print("part3")
    text_p3_plain_text.delete("1.0", tkinter.END)
    text_p3_mingwen_text.delete("1.0", tkinter.END)

    d = int(entry_p3_private_key_D.get())
    n = int(entry_p3_private_key_N.get())
    cipher_text = int(text_p3_cipher_text.get('1.0', tkinter.END))
    plain_text = exp_mode(cipher_text, d, n)
    text_p3_plain_text.insert(
        "insert", f"{plain_text}={cipher_text}^{d} % {n}")
    mignwen_text = transferTostr(str(plain_text))
    text_p3_mingwen_text.insert(
        "insert", f"mignwen_text={mignwen_text}")


# # 生成窗口之基本信息
root = tkinter.Tk()
root.geometry('1200x430')    # 窗口的宽度x高度
root.resizable(False, False)  # 窗口可以改变大小
root.title('RSA非对称密钥')    # 设置窗口标题
root.config(bg='#ffffff')   # 窗口背景颜色
###################################################
lable_part1 = tkinter.Label(root, text="Part①-RSA密钥生成", font=("黑体", 13), width=25,
                            height=20, fg="black", bg="white")
lable_p1_p = tkinter.Label(root, text="请输入质数p位数:", font=("黑体", 13), width=25,
                           height=20, fg="black", bg="white")
entry_p1_p = tkinter.Entry(root, bd=5)
lable_p1_q = tkinter.Label(root, text="请输入质数q位数:", font=("黑体", 13), width=25,
                           height=20, fg="black", bg="white")
entry_p1_q = tkinter.Entry(root, bd=5)
lable_p1_EDN = tkinter.Label(root, text="E、D、N的生成:", font=("黑体", 13), width=25,
                             height=20, fg="black", bg="white")
lable_p1_N = tkinter.Label(root, text="1. N = p × q", font=("黑体", 13), width=25,
                           height=20, fg="black", bg="white")
text_p1_N = tkinter.Text(root, bd=2, width=40, height=1)
lable_p1_L = tkinter.Label(root, text="2. L = (p-1) × (q-1)", font=("黑体", 13), width=25,
                           height=20, fg="black", bg="white")
text_p1_L = tkinter.Text(root, bd=2, width=40, height=1)
lable_p1_E = tkinter.Label(root, text="3. E: gcd(E,L) = 1", font=("黑体", 13), width=25,
                           height=20, fg="black", bg="white")
text_p1_E = tkinter.Text(root, bd=2, width=40, height=1)
lable_p1_D = tkinter.Label(root, text="4. D: E × D mod L = 1", font=("黑体", 13), width=25,
                           height=20, fg="black", bg="white")
text_p1_D = tkinter.Text(root, bd=2, width=40, height=1)

lable_p1_public_key = tkinter.Label(root, text="公钥{E,N} = ", font=("黑体", 13), width=25,
                                    height=20, fg="black", bg="white")
entry_p1_public_key_E = tkinter.Entry(root, bd=5)
entry_p1_public_key_N = tkinter.Entry(root, bd=5)
lable_p1_private_key = tkinter.Label(root, text="私钥{D,N} = ", font=("黑体", 13), width=25,
                                     height=20, fg="black", bg="white")
entry_p1_private_key_D = tkinter.Entry(root, bd=5)
entry_p1_private_key_N = tkinter.Entry(root, bd=5)

button_p1 = tkinter.Button(
    root, text="RSA密钥生成", font=("黑体", 13), command=part1)
###################################
lable_part2 = tkinter.Label(root, text="Part②-RSA加密过程", font=("黑体", 13), width=25,
                            height=20, fg="black", bg="white")
lable_p2_private_key = tkinter.Label(root, text="请输入公钥{E,N}:", font=("黑体", 13), width=25,
                                     height=20, fg="black", bg="white")
entry_p2_public_key_E = tkinter.Entry(root, bd=5)
entry_p2_public_key_N = tkinter.Entry(root, bd=5)
lable_p2_plain_text = tkinter.Label(root, text="请输入明文:", font=("黑体", 13), width=25,
                                    height=20, fg="black", bg="white")
text_p2_plain_text = tkinter.Text(root, bd=5, width=20, height=5)
lable_p2_RSA = tkinter.Label(root, text="RSA的加密", font=("黑体", 13), width=25,
                             height=20, fg="black", bg="white")
lable_p2_plain_byte = tkinter.Label(root, text="1. Plain = encode(明文)", font=("黑体", 13), width=25,
                                    height=20, fg="black", bg="white")
text_p2_plain_byte = tkinter.Text(root, bd=5, width=40, height=4)
lable_p2_cipher_text = tkinter.Label(root, text="2. Cipher = Plain ^ E mod N", font=("黑体", 13), width=25,
                                     height=20, fg="black", bg="white")
text_p2_cipher_text = tkinter.Text(root, bd=5, width=40, height=4)
button_p2 = tkinter.Button(
    root, text="RSA密钥加密", font=("黑体", 13), command=part2)
###################################
lable_part3 = tkinter.Label(root, text="Part③-RSA解密过程", font=("黑体", 13), width=25,
                            height=20, fg="black", bg="white")
lable_p3_private_key = tkinter.Label(root, text="请输入私钥{D,N}:", font=("黑体", 13), width=25,
                                     height=20, fg="black", bg="white")
entry_p3_private_key_D = tkinter.Entry(root, bd=5)
entry_p3_private_key_N = tkinter.Entry(root, bd=5)
lable_p3_cipher_text = tkinter.Label(root, text="请输入密文:", font=("黑体", 13), width=25,
                                     height=20, fg="black", bg="white")
text_p3_cipher_text = tkinter.Text(root, bd=5, width=20, height=5)
lable_p3_RSA = tkinter.Label(root, text="RSA的解密", font=("黑体", 13), width=25,
                             height=20, fg="black", bg="white")
lable_p3_plain_text = tkinter.Label(root, text="1. Plain = Cipher ^ D mod N", font=("黑体", 13), width=25,
                                    height=20, fg="black", bg="white")
text_p3_plain_text = tkinter.Text(root, bd=5, width=40, height=4)
lable_p3_mingwen_text = tkinter.Label(root, text="2. 明文 = decode(Plain)", font=("黑体", 13), width=25,
                                      height=20, fg="black", bg="white")
text_p3_mingwen_text = tkinter.Text(root, bd=5, width=40, height=4)
button_p3 = tkinter.Button(
    root, text="RSA密钥解密", font=("黑体", 13), command=part3)
c1 = tkinter.Canvas(bg='black', width=2, height=430)
c2 = tkinter.Canvas(bg='black', width=2, height=430)
b1 = tkinter.Canvas(bg='black', width=398, height=2)
b2 = tkinter.Canvas(bg='black', width=393, height=2)
b3 = tkinter.Canvas(bg='black', width=393, height=2)
###Part1#################################################
lable_part1.place(x=100, y=10, width=200, height=20)
lable_p1_p.place(x=20, y=50, width=150, height=20)
entry_p1_p.place(x=20, y=70)

lable_p1_q.place(x=200, y=50, width=150, height=20)
entry_p1_q.place(x=200, y=70)

lable_p1_EDN.place(x=10, y=110, width=130, height=20)
lable_p1_N.place(x=10, y=130, width=115, height=20)
text_p1_N.place(x=10, y=150)
lable_p1_L.place(x=10, y=170, width=186, height=20)
text_p1_L.place(x=10, y=190)
lable_p1_E.place(x=10, y=210, width=162, height=20)
text_p1_E.place(x=10, y=230)
lable_p1_D.place(x=10, y=250, width=200, height=20)
text_p1_D.place(x=10, y=270)

lable_p1_public_key.place(x=20, y=300, width=120, height=20)
entry_p1_public_key_E.place(x=20, y=320)
entry_p1_public_key_N.place(x=20, y=350)
lable_p1_private_key.place(x=200, y=300, width=120, height=20)
entry_p1_private_key_D.place(x=200, y=320)
entry_p1_private_key_N.place(x=200, y=350)
b1.place(x=0, y=100)
c1.place(x=400, y=0)
button_p1.place(x=140, y=390)
###Part2#################################################
lable_part2.place(x=500, y=10, width=200, height=20)
lable_p2_private_key.place(x=420, y=50, width=150, height=20)
entry_p2_public_key_E.place(x=420, y=70)
entry_p2_public_key_N.place(x=420, y=100)
lable_p2_plain_text.place(x=600, y=50, width=120, height=20)
text_p2_plain_text.place(x=600, y=70)
lable_p2_RSA.place(x=410, y=160, width=100, height=20)
lable_p2_plain_byte.place(x=410, y=180, width=210, height=20)
text_p2_plain_byte.place(x=420, y=200)
lable_p2_cipher_text.place(x=410, y=280, width=250, height=20)
text_p2_cipher_text.place(x=420, y=300)
b2.place(x=404, y=150)
c2.place(x=800, y=0)
button_p2.place(x=540, y=390)
###Part3#################################################
lable_part3.place(x=900, y=10, width=200, height=20)
lable_p3_private_key.place(x=820, y=50, width=150, height=20)
entry_p3_private_key_D.place(x=820, y=70)
entry_p3_private_key_N.place(x=820, y=100)
lable_p3_cipher_text.place(x=1000, y=50, width=120, height=20)
text_p3_cipher_text.place(x=1000, y=70)
lable_p3_RSA.place(x=810, y=160, width=100, height=20)
lable_p3_plain_text.place(x=810, y=180, width=250, height=20)
text_p3_plain_text.place(x=820, y=200)
lable_p3_mingwen_text.place(x=810, y=280, width=210, height=20)
text_p3_mingwen_text.place(x=820, y=300)
b3.place(x=804, y=150)
button_p3.place(x=940, y=390)

root.mainloop()

RSA代码部分参考自:https://blog.csdn.net/qq_36944952/article/details/103973849

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值