【问题标题】:Python - RSA decryption does not return original message (very simple, short program)Python - RSA解密不返回原始消息(很简单,短程序)
【发布时间】:2017-12-11 18:26:06
【问题描述】:

所以我正在尝试创建一个非常简单的 RSA 加密/解密程序,我只加密/解密 int 数字。除一个问题外,一切正常。有时我的解密号码(消息)与我的原始号码(我需要加密和解密的消息)不匹配。每当我输入的数字(消息)接近我的“n”变量中的数字(n=p*q,其中 p 和 q 是质数)时,这似乎就会发生。我现在浏览了 Stackoverflow,发现 RSA 算法无法正确解密大于“n”的消息。但在我的情况下,它无法解密接近“n”的消息。如果 n=35 并且我的输入数字(要加密/解密的数字)是 32,则尽管 32 低于 35(但适用于 31、30 ......),但程序不会正确地将其解密回 32。为什么?

代码:

import math

def isPrime(n):
    if n>=2:
        for m in range(2, int(math.sqrt(n)+1)):
            if n%m == 0:
                return False
        return True
    else:
        return False   

def gcd(x, y):
    while y != 0:
        (x, y) = (y, x % y)
    return x


def phi(n):
    amount = 0
    for k in range(1, n + 1):
        if gcd(n, k) == 1:
            amount += 1
    return amount

def findPubE(n, phiN):
    for e in range(3, n, 2):
        if gcd(e,phiN)==1:
            return e
    else:
        raise AssertionError("cannot find 'e'")


def multiplicative_inverse(a, b):
    """Returns a tuple (r, i, j) such that r = gcd(a, b) = ia + jb
    """
    # r = gcd(a,b) i = multiplicitive inverse of a mod b
    #      or      j = multiplicitive inverse of b mod a
    # Neg return values for i or j are made positive mod b or a respectively
    # Iterateive Version is faster and uses much less stack space
    x = 0
    y = 1
    lx = 1
    ly = 0
    oa = a  # Remember original a/b to remove
    ob = b  # negative values from return results
    while b != 0:
        q = a // b
        (a, b) = (b, a % b)
        (x, lx) = ((lx - (q * x)), x)
        (y, ly) = ((ly - (q * y)), y)
    if lx < 0:
        lx += ob  # If neg wrap modulo orignal b
    if ly < 0:
        ly += oa  # If neg wrap modulo orignal a
    # return a , lx, ly  # Return only positive values
    return lx

def encrypt(m,e,n):
    return (m^(e)) % n

def decrypt(M, d):
    return M^(d)




def main():
    p=int(input("Input first prime number (p): "))
    q=int(input("Input second prime number (q): "))
    n=p*q
    print("n = ",n)
    msg= int(input("Input message: "))
    assert msg < n
    phiN=(p-1)*(q-1)
    e = findPubE(n,phiN)
    d = multiplicative_inverse(e,phiN)
    encryptedMsg = encrypt(msg,e,n)
    decryptedMsg = decrypt(encryptedMsg,d)



    assert isPrime(p) and isPrime(q)

    print("phi(n) = ",phiN)
    print("e = ",e)
    print("d = ",d)
    print("Encrypted message: ",encryptedMsg)
    print("Decrypted message: ",decryptedMsg)


main()

【问题讨论】:

  • ^not python 中的求幂运算符,** 是。无论如何,模幂运算应该简单地使用内置 pow 函数的三参数版本。 ^ 是异或运算符。 (32^5)%35 等于 pow(32, 5, 35) 只是一个有趣的巧合。
  • 啊,哈哈。好的。自从我使用 Python 以来已经有很长时间了,所以我只是假设 '^' 是“强大的”符号。但是其余的代码看起来不错,对吧?
  • 不,不是。如果您有 encrypt(m, e, n) 方法,那么您的解密方法应该类似于 decrypt(M, d, n)
  • @JamesKPolk 为什么我需要在解密方法中添加“n”作为参数?解密的消息是 M^d(其中 M 是我的加密消息)。解密消息的完整定义是:M^d = m^(ed) = m mod n(其中 M 是我的加密消息,m 是原始消息)。
  • 解密后的消息不是M^d,是M^d mod n。

标签: python encryption cryptography rsa


【解决方案1】:

解决了!我在代码中犯了两个小错误。第一个是我认为“^”符号在 Python 中的意思是“to the power of”(正确的符号是“**”),第二个是我忘记在我的行中添加“mod n” decrypt() 函数(所以return M**(d) % n 而不是return M^(d))。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-22
    • 2021-03-04
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    相关资源
    最近更新 更多