2017-02-15 500 views
0

我正在爲我的一個類做一個項目。教授讓我們在不使用加密庫的情況下製作RSA加密/解密程序(全部從頭開始)。所以我得到我的p,q,n,phi,e和d,一切都很好。我遇到的問題是試圖加密它。我採取每個字符的ASCII條例並使用我的e和n加密。但是,我返回的數字遠遠超出範圍,無法重新轉換爲ASCII字符。我怎樣才能把這個數字改成一個字符,並且以後還能用我的私鑰解密它?以下是我的粗略代碼:RSA加密/解密:轉換爲字符串

import random 

def generatePrimes(): 
    prime = False 
    while prime == False: 
     n = random.randint(10000, 100000) #generates random integer between 10,000 and 100,000 
     if n % 2 != 0: #checks if integer is divisible by 2 
      for x in range(3, int(n ** 0.5), 2): #starts at 3, increments by 2 to check if integer is divisible by anything 
       if n % x == 0: 
        break #if integer divides a number x and has no remainder, it isn't prime and the loop breaks 
       else: 
        prime = True #a prime number is found 

    return n #returns prime number 



def findE(n, pn): 
    factor = True 
    while factor == True: 
     e = random.randint(3, 35) #creates random integer from 2 to p(n), but keeps it small for ease of use 
     if n % e != 0: #checks if integer is divisible by n 
      factor = False #if remainder is not 0, the integer isn't divisible by n. if remainer is 0, the loop restarts to choose another number 

    return e 



def findD(e, pn): 
    d = pow(e, pn - 2, pn) #calculates d 

    return d 



def encryption(): 
    p = generatePrimes() #creates random prime number for p 
    q = generatePrimes() #creates random prime number for q 
    n = p * q #finds n by multiplying p and q 
    pn = (p - 1) * (q - 1) #finds p(n) 
    e = findE(n, pn) #creates e such that 1 < e < p(n) 
    d = findD(e, pn) #creates d 

    print('n =', n) 
    print('e =', e) 
    print('d =', d) 

    print('Keys have been created.') 
    message = input('Enter the message you wish to encrypt:') 

    newMessage = '' #creates new string that the encrypted message will be put into 
    for x in message: 
     x = ord(x) #converts character into ASCII reference number 
     x = (x ** e) % n #encrypts using rsa algorithm 
     x = chr(x) 
     newMessage += x #places new character into the encrypted string 

    print('Here is your encrypted message:') 
    print(newMessage) 


def decryption(): 
    n = int(input('Enter in a value for n:')) 
    d = int(input('Enter in a value for d:')) 

    newMessage = [] 
    message = input('Enter the message you wish to decrypt:') 
    for x in message: 
     x = ord(x) 
     x = (x ** d) % n 
     x = chr(x) 
    newMessage += x 

    print('Here is your decrypted message:') 
    print(newMessage) 
+0

在附註中,編寫自己的加密算法在實際應用程序中非常糟糕。與回答這個問題無關,但我只想幫助理解程序化世界中的良好原則。 –

回答

1

您不得單獨加密字符串中的每個字符。您必須將整個字符串編碼爲單個數字,然後對該數字執行rsa加密。解碼時必須相反。 RSA具有標準的字符序列可以有多長時間,應該如何編碼和填充。 (見PKCS1或OAEP)

順便說一句你的findE功能有缺陷。沒有人關心,如果n%e==0,但epn必須是coprime。最簡單的是爲e選擇一個不太小的素數,如e==65537。它不一定是隨機的。

+0

我的教授告訴我們,e不能是n的一個因子,所以我檢查n%e == 0。我將如何將整個字符串編碼爲單個數字? –

2

通常,對於這種類型的玩具RSA實現,每個字符都是單獨加密的。現在加密將產生一個介於零和N之間的值,即模數。

編碼此值的最簡單方法是始終確保它的大小爲dLen小數,其中dLen是顯示模數N所需的小數位數。您可以通過爲零位數前綴來執行此操作,直到值爲合適的大小。然後,解密,讀取dLen字符,將其轉換爲數字,並使用私鑰執行模冪運算。

對於實際的RSA加密(例如RSA-OAEP)也會發生同樣的情況。這裏加密的結果被轉換爲保持模量所需的相同數量的字節。這個功能被稱爲I2OSP。上面的實現可以讓你練習實現這樣的功能。


Tamas當然是正確的,當他解釋說 - 在現實生活中 - 這不是如何加密字符串。您將使用混合密碼系統,而不是使用分組密碼來加密明文(轉換爲字節)。

+0

當然,只要它合適,你也可以把幾個字符放在一起。首先將它們編碼爲字節(例如,使用ASCII),然後將結果字節轉換爲整數。 –

+0

但是當解密時,你會如何確定哪個整數對應哪個字母?例如。 15會是「o」還是「ae」? –

+0

也沒有。你會期望與'x = ord(x)#converts字符到ASCII參考號碼(考慮單個字符)相同的字符值。當然,你不應該使用'x = chr(x)',因爲這會在加密後丟棄信息。 –