所以我在 qt 设计器中使用 gui 在 python 中对 RSA 进行编程,但无法找出我的解密函数出了什么问题。 我首先将消息分成块。块大小基于 log2(n)。之后我取出一个块,将每个字符转换为 ASCII 值,然后转换为二进制值。如果字符的二进制值小于 11,我会在左侧添加零,然后将二进制块转换为十进制形式。现在我使用 cipher = message^e mod n 加密每个块并打印加密块。 为了解密,我从加密消息中取出每个块并使用 message = cipher^d mod n,然后获取块的二进制值并检查是否有足够的字符用于除以 11,如果没有,则在开头添加零。现在我将块分成每 11 个字符的部分,并获取每个部分的十进制值,然后将其转换为 ASCII 字符。
当使用 message = cipher^d mod n 解密消息的一部分时,问题就开始了,因为它返回的值与加密之前不同
import binascii
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import QtGui, uic
import random
import sympy
import math
qtCreatorFile = "RSAGUI.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class MyApp(QMainWindow, Ui_MainWindow):
def keys_gen(self):
p = random.randint(1, 100)#10 ** 18, 10 ** 19 - 1
while not sympy.isprime(p):
p = random.randint(1, 100)#10 ** 18, 10 ** 19 - 1
q = random.randint(1, 100)#10 ** 18, 10 ** 19 - 1
while not sympy.isprime(q) and q != p:
q = random.randint(1, 100)#10 ** 18, 10 ** 19 - 1
n = p * q
euler = (p - 1) * (q - 1)
e = random.randint(2, euler)
while math.gcd(e, euler) != 1:
e = random.randint(2, euler)
d = sympy.mod_inverse(e, euler)
self.lineEditNPublic.setText(str(n))
self.lineEditE.setText(str(e))
self.lineEditNPrivate.setText(str(n))
self.lineEditD.setText(str(d))
def text_to_num(self, text):
num = ""
for char in text:
char_bin = bin(ord(char))[2:]
num += char_bin.rjust(11, '0')
num = int(num, 2)
return num
def num_to_text(self, num):
num_bin = bin(num)[2:]
if len(num_bin) % 11 != 0:
zeros = 11 - (len(num_bin) % 11)
num_bin = num_bin.rjust(len(num_bin) + zeros, '0')
num_bin_parts = [num_bin[i:i + 11] for i in range(0, len(num_bin), 11)]
text = ""
for part in num_bin_parts:
part_decimal = int(part, 2)
text += chr(part_decimal)
return text
def encrypt(self):
text = self.plainTextEditDDecrypted.toPlainText()
n = int(self.lineEditNPublic.text())
e = int(self.lineEditE.text())
text_encrypted = ""
block_size = math.floor(math.log2(n))
block_size_counter = 0
block = ""
for ch in text:
block_size_counter += 1
block += ch
if (block_size_counter % block_size) == 0 or block_size_counter == len(text):
block = self.text_to_num(block)
block = pow(block, e, n)
text_encrypted += str(block) + ","
block = ""
if text_encrypted[-1] == ",":
text_encrypted = text_encrypted[:-1]
self.plainTextEditDEncrypted.setPlainText(str(text_encrypted))
def decrypt(self):
numbers = str(self.plainTextEditEEncrypted.toPlainText())
n = int(self.lineEditNPrivate.text())
d = int(self.lineEditD.text())
text = ""
number_list = [int(num) for num in numbers.split(",")]
for number in number_list:
number = pow(number, d, n)
text += self.num_to_text(number)
self.plainTextEditEDecrypted.setPlainText(text)
def delete_encrypt(self):
self.plainTextEditDDecrypted.setPlainText("")
self.plainTextEditDEncrypted.setPlainText("")
def delete_decrypt(self):
self.plainTextEditEEncrypted.setPlainText("")
self.plainTextEditEDecrypted.setPlainText("")
def __init__(self):
QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.pushButtonEncrypt.clicked.connect(self.encrypt)
self.pushButtonDelete1.clicked.connect(self.delete_encrypt)
self.pushButtonDecrypt.clicked.connect(self.decrypt)
self.pushButtonDelete2.clicked.connect(self.delete_decrypt)
self.pushButtonKeyGenerate.clicked.connect(self.keys_gen)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
我尝试使用较低的键值,以防 math.pow 函数出现问题
代码以位为单位计算块大小,但代码随后在字符上使用该块大小。目前尚不清楚为什么每个字符的大小都是 11 位,对于它们来说更有意义,例如大小为 7 或 8 位。但是,如果字符大小为 11 位,那么您需要的块大小为 log_2(n) / 11,而不是 log_2(n) / 11(顺便说一下,也称为 log_256)。