RSA-算法笔记

对称加密

  1. 1976年以前,所有的加密方法都是同一种模式:
  2. (1)甲方选择某一种加密规则,对信息进行加密;
  3. (2)乙方使用同一种规则,对信息进行解密。
  4. 由于加密和解密使用同样规则(简称"密钥"),这被称为"对称加密算法"

非对称加密算法

  1. 1976年,两位美国计算机学家Whitfield Diffie 和 Martin Hellman,提出了一种崭新构思,可以在不直接传递密钥的情况下,完成解密。这被称为"Diffie-Hellman密钥交换算法"
  2. 加密和解密可以使用不同的规则,只要这两种规则之间存在某种对应关系即可,这样就避免了直接传递密钥。
  3. (1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
  4. (2)甲方获取乙方的公钥,然后用它对信息加密。
  5. (3)乙方得到加密后的信息,用私钥解密。
  6. 如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。

RSA算法历史

  1. 1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。
  2. 目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。

RSA涉及基础数论:

  1. 互质关系:
  2. 如果两个正整数,除了1以外,没有其他公因子,我们就称这两个数是互质关系(coprime)
  3. 如,15和32没有公因子,所以它们是互质关系。这说明,不是质数也可以构成互质关系。
  4. 基础结论:
  • 任意两个质数构成互质关系,比如13和61。
  • 一个数是质数,另一个数只要不是前者的倍数,两者就构成互质关系,比如3和10。
  • 如果两个数之中,较大的那个数是质数,则两者构成互质关系,比如97和57。
  • 1和任意一个自然数是都是互质关系,比如1和99。
  • p是大于1的整数,则p和p-1构成互质关系,比如57和56。
  • p是大于1的奇数,则p和p-2构成互质关系,比如17和15。
  1. 欧拉函数:
  • 问题:任意给定正整数n,请问在小于等于n的正整数之中,有多少个与n构成互质关系?
  • 计算这个值的方法就叫做欧拉函数,以φ(n)表示。在1到8之中,与8形成互质关系的是1、3、5、7,所以 φ(n) = 4。
  • φ(n) 的计算方法并不复杂,但是为了得到最后那个公式,需要一步步讨论。
  • 第一种情况:如果n=1,则 φ(1) = 1 。因为1与任何数(包括自身)都构成互质关系。
  • 第二种情况:如果n是质数,则 φ(n)=n-1 。因为质数与小于它的每一个数,都构成互质关系。比如5与1、2、3、4都构成互质关系。
  • 第三种情况:如果n是质数的某一个次方,即 n = p^k (p为质数,k为大于等于1的整数),则φ(p^k) = p^k - p(k-1)=pk(1-1/p)
  • 第四种情况: 如果n可以分解成两个互质的整数之积,n = p1 × p2,则: φ(n) = φ(p1p2) = φ(p1)φ(p2)
  • 第五种情况:因为任意一个大于1的正整数,都可以写成一系列质数的积。
  1. 欧拉定理
  • 如果两个正整数a和n互质,则n的欧拉函数 φ(n) 可以让下面的等式成立:a ^ φ(n) ≡ 1(mod n)
  • 也就是说,a的φ(n)次方被n除的余数为1。或者说,a的φ(n)次方减去1,可以被n整除。
  • 比如,3和7互质,而7的欧拉函数φ(7)等于6,所以3的6次方(729)减去1,可以被7整除(728/7=104)。

模反元素

  1. 如果两个正整数a和n互质,那么一定可以找到整数b,使得 ab-1 被n整除,或者说ab被n除的余数是1。ab ≡ 1 (mod φ(n))
  2. 这时,b就叫做a的"模反元素"。

密钥生成的步骤

  1. 第一步,随机选择两个不相等的质数p和q。
  2. 第二步,计算p和q的乘积n。
  3. 第三步,计算n的欧拉函数φ(n)。 φ(n) = (p-1)(q-1)
  4. 第四步,随机选择一个整数e,条件是1 (实际应用中,常常选择65537。)
  5. 第五步,计算e对于φ(n)的模反元素d。

加密和解密

  1. (1)加密要用公钥 (n,e)
  2. (2)解密要用私钥(n,d)

示例:

# -*- coding:utf-8 -*-
from tkinter import *
import rsa
import base64

# 密钥生成
def GenerateKey():
    (public_key, private_key) = rsa.newkeys(1024)
    print("\n生成公钥:" + public_key.save_pkcs1().decode('utf8'))
    print("\n生成私钥:" + private_key.save_pkcs1().decode('utf8'))
    publicKeyText.delete(0.0, END)
    publicKeyText.insert(END, public_key.save_pkcs1().decode('utf8'))
    privateKeyText.delete(0.0, END)
    privateKeyText.insert(END, private_key.save_pkcs1().decode('utf8'))

# 用公钥加密
def EncryptionByPublickey():
    public_key_str = publicKeyText.get("0.0", "end").encode(encoding="utf-8")
    public_key = rsa.PublicKey.load_pkcs1(public_key_str)
    entry_str = entryText.get("0.0", "end").encode(encoding="utf-8")
    encrypt_msg = rsa.encrypt(entry_str, public_key)
    print("公钥加密后的文本为:\n" + base64.encodebytes(encrypt_msg).decode('utf8'))
    outputText.delete(0.0, END)
    outputText.insert(END, base64.encodebytes(encrypt_msg).decode('utf8'))

# 用私钥解密
def DecryptionByPrivatekey():
    private_key_str = privateKeyText.get("0.0", "end").encode(encoding="utf-8")
    private_key = rsa.PrivateKey.load_pkcs1(private_key_str)
    entry_str = entryText.get("0.0", "end").encode(encoding="utf-8")
    encrypt_msg = base64.decodebytes(entry_str)
    outputText.delete(0.0, END)
    try:
        decrypt_msg = rsa.decrypt(encrypt_msg, private_key)
        print("私钥解密后的文本为:\n" + decrypt_msg.decode('utf8'))
        outputText.insert(END, decrypt_msg.decode('utf8'))
    except:
        decrypt_msg = "私钥解密失败"
        print(decrypt_msg)
        outputText.insert(END, decrypt_msg)


window = Tk()
window.title("RSA加密解密程序")
frame = Frame(window)
frame.pack()
label = Label(frame, text="生成公钥为(公钥用于加密):")
label.grid(row=1, column=1, columnspan=4)
publicKeyText = Text(frame,width=50,height=8)
publicKeyText.grid(row=2, column=1,columnspan=4)

label = Label(frame, text="生成私钥为(私钥用于解密):")
label.grid(row=3, column=1,columnspan= 4)
privateKeyText = Text(frame,width=50,height=12)
privateKeyText.grid(row=4, column=1,columnspan = 4)

btGenerateKey = Button(frame, text = "生成公钥/私钥(点击我生成新的)",command=GenerateKey)
btGenerateKey.grid(row = 5, column = 1,columnspan = 4)


label = Label(frame, text = "请输入加密/解密的文本:")
label.grid(row = 6, column = 1,columnspan = 4)

entryText = Text(frame,width=50,height=5)
entryText.grid(row = 7, column = 1,columnspan = 4)

btEncryptionByPublickey = Button(frame, text="公钥加密",command=EncryptionByPublickey)
btEncryptionByPublickey.grid(row = 8, column = 1,pady = 10)

btDecryptionByPrivatekey = Button(frame, text = "私钥解密",command=DecryptionByPrivatekey)
btDecryptionByPrivatekey.grid(row=8, column=4)

outputText = Text(frame,width=50,height=5)
outputText.grid(row=9, column=1,columnspan=4)
label=Label(frame, text="结果生成。。")
label.grid(row=10, column=1,columnspan= 4)

print("欢迎使用……")
GenerateKey()
mainloop()

print("欢迎再次使用……")
  • 25
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值