什么是同态加密?
- 定义
- 同态加密(Homomorphic Encryption)是一种特殊的加密技术。它允许在密文上直接进行特定类型的计算,得到的结果解密后与在明文上进行相同计算得到的结果相同。简单来说,就是可以在加密的数据上进行操作,而无需先解密数据。
- 工作原理
- 同态加密方案主要包括密钥生成、加密、解密和同态运算几个部分。
- 密钥生成:同态加密算法首先会生成一对密钥,包括公钥和私钥。公钥用于加密数据,私钥用于解密数据。
- 加密:使用公钥对原始数据(明文)进行加密,得到密文。
- 同态运算:在密文上进行特定的数学运算,如加法、乘法或者其他更复杂的运算。这些运算的类型和规则是由同态加密算法预先定义好的。
- 解密:使用私钥对经过同态运算后的密文进行解密,得到的结果与对原始明文进行相同运算后的结果相同。
- 应用场景
- 云计算和大数据隐私保护:
- 在云计算环境中,用户的数据存储在云端服务器上。如果用户不想让云服务提供商看到数据的内容,但又希望云服务器能够对数据进行计算,同态加密就可以发挥作用。例如,在医疗数据处理中,医院可以将患者的加密病历数据存储在云端。当需要对这些数据进行统计分析(如计算某种疾病的发病率)时,云服务器可以直接对加密数据进行运算,而不会泄露患者的隐私信息。
- 金融领域:
- 在金融交易中,隐私保护至关重要。同态加密可以用于对金融数据(如交易金额、账户余额等)进行加密。银行或金融机构可以在加密数据上进行一些必要的计算,如计算利息、验证账户余额是否足够等操作,而无需解密数据,从而保护用户的财务隐私。
- 云计算和大数据隐私保护:
- 类型
- 加法同态加密:这种类型的同态加密允许在密文上进行加法运算。例如,给定两个加密后的数字和(其中表示加密函数),可以计算,并且解密后的结果与对明文和进行加法运算后的结果相同。
- 乘法同态加密:允许在密文上进行乘法运算。即对于加密后的数字和,可以计算,解密后得到的结果与对明文和进行乘法运算后的结果相同。
- 全同态加密(Fully Homomorphic Encryption,FHE):这是最强大的同态加密类型,它允许在密文上进行任意的计算,包括加法、乘法以及它们的组合等多种运算。不过,全同态加密在计算效率和性能方面目前还面临一些挑战,其算法通常比较复杂,计算资源消耗较大。
带gui界面的、基于Python的代码如下。建议先好好学习RSA、什么是同态加密后再来思考代码。
建议先点赞收藏关注哈,创作不易
需要安装的库:
pip install sympy
源码:
import random
import tkinter as tk
from tkinter import scrolledtext
from tkinter import messagebox
from sympy import isprime, mod_inverse # 引入素数判断和求逆函数
# 随机生成一个指定位数的奇数p,作为生成大素数的候选数
def generate_prime_candidate(length):
"""
随机生成一个奇数p
参数:
length (int): 生成的随机数的位数
返回:
int: 生成的指定位数的奇数
"""
p = random.getrandbits(length)
p |= (1 << length - 1) | 1 # 通过位运算设置最高位和最低位为1,确保为奇数
return p
# 生成指定长度的大素数,通过不断尝试生成的候选数,直到找到素数为止
def generate_large_prime(length):
"""
生成指定长度的大素数
参数:
length (int): 期望生成的大素数的位数
返回:
int: 符合条件的大素数
"""
p = 4
while not isprime(p):
p = generate_prime_candidate(length)
return p
# 生成RSA密钥对,包括公钥(e, n)和私钥(d, n)
def generate_keys(bit_length):
"""
生成RSA密钥对
参数:
bit_length (int): 用于生成大素数的位数,决定密钥的强度
返回:
tuple: 包含公钥(e, n)和私钥(d, n)的元组
"""
# 生成两个大素数
p = generate_large_prime(bit_length)
q = generate_large_prime(bit_length)
n = p * q
phi_n = (p - 1) * (q - 1) # 计算欧拉函数值phi(n)
# 选择公钥指数,通常选取较小的质数,这里固定为65537
e = 65537
# 计算私钥指数,通过求e在模phi_n下的逆元得到d
d = mod_inverse(e, phi_n)
# 公钥 (e, n) 和 私钥 (d, n)
print("此时n=", n)
print((e, n), (d, n))
return ((e, n), (d, n))
# 使用公钥对明文进行加密,按照RSA加密算法公式 c = m^e (mod n) 计算密文
def encrypt(public_key, plaintext):
"""
使用公钥加密明文 c=m**e(mod n)
参数:
public_key (tuple): 包含公钥指数e和模数n的元组,格式为(e, n)
plaintext (int): 要加密的明文信息,以整数形式表示
返回:
int: 加密后的密文
"""
e, n = public_key
ciphertext = pow(plaintext, e, n)
return ciphertext
# 使用私钥对密文进行解密,按照RSA解密算法公式 m = c^d (mod n) 计算解密后的明文
def decrypt(private_key, ciphertext):
"""
使用私钥解密密文
参数:
private_key (tuple): 包含私钥指数d和模数n的元组,格式为(d, n)
ciphertext (int): 要解密的密文信息,以整数形式表示
返回:
int: 解密后的明文
"""
d, n = private_key
decrypted_int = pow(ciphertext, d, n)
return decrypted_int
# 同态乘法操作,在给定公钥的情况下,将两个密文对应的值相乘后对n取模
def homomorphic_multiply(ciphertext1, ciphertext2, public_key):
"""
同态乘法:乘两个密文
参数:
ciphertext1 (int): 第一个密文
ciphertext2 (int): 第二个密文
public_key (tuple): 公钥,格式为(e, n)
返回:
int: 同态乘法运算后的密文结果
"""
e, n = public_key
return (ciphertext1 * ciphertext2) % n
# 创建一个新的顶层窗口,用于承载各种操作对应的子窗口
def open_new_window(title):
"""
打开一个新的顶层窗口
参数:
title (str): 新窗口的标题
返回:
tk.Toplevel: 创建的新窗口对象
"""
new_window = tk.Toplevel(root)
new_window.title(title)
return new_window
# 生成密钥对,并在主窗口的文本框中展示私钥相关信息(改进了插入文本的格式)
def generate_key_pair_and_show():
"""
生成密钥对,并在主窗口的文本框中展示私钥相关信息
"""
public_key, private_key = generate_keys(16) # 设置bit_length,可根据需要调整
result_text.delete(1.0, tk.END) # 清空文本框内容
# 以更清晰的格式插入私钥和公钥信息到文本框中
result_text.insert(tk.END, f"私钥(d,n): {private_key}\n公钥(e,n): {public_key}")
# 主窗口
root = tk.Tk()
root.title("RSA同态app")
# 设置主窗口大小
root.geometry("400x400") # 宽度x高度
# 加密操作相关函数及界面布局,添加了输入值的错误处理
def open_encryption_window():
"""
打开加密操作窗口,用户可输入明文、公钥参数进行加密操作,显示加密结果
"""
def encrypt_text():
"""
执行加密操作并展示加密结果
"""
try:
plaintext = int(entry_plain_text1.get("1.0", tk.END).strip()) # 获取并转换明文输入为整数,去除首尾空白字符
e = int(entry_plain_text2.get("1.0", tk.END).strip()) # 获取并转换公钥e输入为整数
n = int(entry_plain_text3.get("1.0", tk.END).strip()) # 获取并转换n输入为整数
ciphertext = pow(plaintext, e, n)
messagebox.showinfo("加密结果", ciphertext)
except ValueError:
messagebox.showerror("输入错误", "请确保输入的明文、公钥e和n都是有效的整数!")
encryption_window = open_new_window("加密操作")
encryption_window.geometry("400x300")
# 明文输入框
lbl_plain_text1 = tk.Label(encryption_window, text="请输入明文:")
entry_plain_text1 = tk.Text(encryption_window, width=40, height=2, wrap=tk.WORD)
lbl_plain_text2 = tk.Label(encryption_window, text="请输入公钥e:")
entry_plain_text2 = tk.Text(encryption_window, width=40, height=2, wrap=tk.WORD)
lbl_plain_text3 = tk.Label(encryption_window, text="请输入n:")
entry_plain_text3 = tk.Text(encryption_window, width=40, height=2, wrap=tk.WORD)
lbl_plain_text1.pack(pady=5)
entry_plain_text1.pack(pady=5)
lbl_plain_text2.pack(pady=5)
entry_plain_text2.pack(pady=5)
lbl_plain_text3.pack(pady=5)
entry_plain_text3.pack(pady=5)
# 加密按钮,点击时调用encrypt_text函数进行加密操作
btn_encrypt = tk.Button(encryption_window, text="加密", command=encrypt_text)
btn_encrypt.pack(pady=10)
# 解密操作相关函数及界面布局,同样添加了输入值的错误处理
def open_decryption_window():
"""
打开解密操作窗口,用户可输入密文、私钥参数进行解密操作,显示解密结果
"""
def decrypt_text():
"""
执行解密操作并展示解密结果
"""
try:
ciphertext = int(entry_plain_text1.get("1.0", tk.END).strip()) # 获取并转换密文输入为整数
d = int(entry_plain_text2.get("1.0", tk.END).strip()) # 获取并转换私钥d输入为整数
n = int(entry_plain_text3.get("1.0", tk.END).strip()) # 获取并转换n输入为整数
message = pow(ciphertext, d, n)
messagebox.showinfo("解密结果", message)
except ValueError:
messagebox.showerror("输入错误", "请确保输入的密文、私钥d和n都是有效的整数!")
decryption_window = open_new_window("解密操作")
decryption_window.geometry("400x300")
# 密文输入框
lbl_plain_text1 = tk.Label(decryption_window, text="请输入密文:")
entry_plain_text1 = tk.Text(decryption_window, width=40, height=2, wrap=tk.WORD)
lbl_plain_text2 = tk.Label(decryption_window, text="请输入私钥d:")
entry_plain_text2 = tk.Text(decryption_window, width=40, height=2, wrap=tk.WORD)
lbl_plain_text3 = tk.Label(decryption_window, text="请输入n:")
entry_plain_text3 = tk.Text(decryption_window, width=40, height=2, wrap=tk.WORD)
lbl_plain_text1.pack(pady=5)
entry_plain_text1.pack(pady=5)
lbl_plain_text2.pack(pady=5)
entry_plain_text2.pack(pady=5)
lbl_plain_text3.pack(pady=5)
entry_plain_text3.pack(pady=5)
# 解密按钮,点击时调用decrypt_text函数进行解密操作
btn_encrypt = tk.Button(decryption_window, text="解密", command=decrypt_text)
btn_encrypt.pack(pady=10)
# 同态运算相关函数及界面布局,添加了输入值的错误处理
def homomorphic_operation():
"""
打开同态运算窗口,用户可输入两个密文和n进行同态乘法运算,显示运算结果
"""
def homophic_calculate():
"""
执行同态乘法运算并展示结果
"""
try:
cipher1 = int(entry_plain_text1.get("1.0", tk.END).strip()) # 获取并转换第一个密文输入为整数
cipher2 = int(entry_plain_text2.get("1.0", tk.END).strip()) # 获取并转换第二个密文输入为整数
n = int(entry_plain_text3.get("1.0", tk.END).strip()) # 获取并转换n输入为整数
multi_cipher = (cipher1 * cipher2) % n
save_text.insert(tk.END, multi_cipher)
save_text.insert(tk.END, ",")
except ValueError:
messagebox.showerror("输入错误", "请确保输入的密文和n都是有效的整数!")
calculate_window = open_new_window("同态操作")
calculate_window.geometry("400x400")
lbl_plain_text1 = tk.Label(calculate_window, text="请输入密文1:")
entry_plain_text1 = tk.Text(calculate_window, width=40, height=2, wrap=tk.WORD)
lbl_plain_text2 = tk.Label(calculate_window, text="请输入密文2:")
entry_plain_text2 = tk.Text(calculate_window, width=40, height=2, wrap=tk.WORD)
lbl_plain_text3 = tk.Label(calculate_window, text="请输入n:")
entry_plain_text3 = tk.Text(calculate_window, width=40, height=2, wrap=tk.WORD)
lbl_plain_text1.pack(pady=5)
entry_plain_text1.pack(pady=5)
lbl_plain_text2.pack(pady=5)
entry_plain_text2.pack(pady=5)
lbl_plain_text3.pack(pady=5)
entry_plain_text3.pack(pady=5)
btn_calculate = tk.Button(calculate_window, text="计算", command=homophic_calculate)
btn_calculate.pack(pady=10)
save_text = tk.Text(calculate_window, width=40, height=3, wrap=tk.WORD)
save_text.pack(pady=5)
# 创建按钮
btn_generate_key_pair = tk.Button(root, text="随机生成密钥对,默认公钥指数e = 65537", command=generate_key_pair_and_show, width=40, height=2)
btn_encrypt_operation = tk.Button(root, text="加密操作", command=open_encryption_window, width=20, height=2)
result_text = tk.Text(root, width=40, height=2, wrap=tk.WORD)
btn_decrypt_operation = tk.Button(root, text="解密操作", command=open_decryption_window, width=20, height=2)
btn_homomorphic_operation = tk.Button(root, text="同态运算", command=homomorphic_operation, width=20, height=2)
# 按钮布局
btn_generate_key_pair.pack(pady=10)
result_text.pack(padx=10, pady=10)
btn_encrypt_operation.pack(pady=10)
btn_decrypt_operation.pack(pady=10)
btn_homomorphic_operation.pack(pady=10)
# 运行主循环
root.mainloop()