为什么我的 RSA 中的 python 解密不起作用

问题描述 投票:0回答:1

所以我在 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 函数出现问题

python python-3.x cryptography rsa
1个回答
0
投票

代码以位为单位计算块大小,但代码随后在字符上使用该块大小。目前尚不清楚为什么每个字符的大小都是 11 位,对于它们来说更有意义,例如大小为 7 或 8 位。但是,如果字符大小为 11 位,那么您需要的块大小为 log_2(n) / 11,而不是 log_2(n) / 11(顺便说一下,也称为 log_256)。

© www.soinside.com 2019 - 2024. All rights reserved.