2017-02-15 26 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

文字列内のすべての文字を別々に暗号化してはいけません。文字列全体を1つの数値でエンコードし、その数値に対してrsa暗号化を実行する必要があります。復号化中に逆も同じことが行われなければならない。 RSAには文字シーケンスの長さ、文字コードのエンコード方法、パディング方法の基準があります。 (PKCS1またはOAEPを参照)

Btw findE機能に欠陥があります。 n%e==0の場合は誰も気にしませんが、epnは共起しなければなりません。最も簡単なのはeのように小さすぎない素数をe==65537のように選択することです。ランダムである必要はありません。

+0

私の教授は、eはnの因子ではないことを教えてくれました。そのため、n%e == 0をチェックしました。文字列全体を1つの数字にエンコードする方法は? –

2

一般的に、この種のおもちゃRSA実装の場合、各文字は別々に暗号化されます。今度は、暗号化はゼロとNとの間の値、すなわちモジュラスをもたらす。

おそらく、この値を符号化する最も簡単な方法は、dLenがモジュラスNを表示するのに必要な小数のdLenの小数であることを常に確認することです。これは、値が0になるまで0桁の接頭辞正しいサイズ。次に、解読するために、dLen文字を読み取り、それを数値に変換し、秘密鍵でべき乗剰余演算を実行します。

実際のRSA暗号化(RSA-OAEPなど)でも同じことが起こります。ここで、暗号化の結果は、モジュラスを保持するために必要とされる同じ番号のバイトに変換されます。この機能はI2OSPと呼ばれます。上記の実装は、このような機能の実装を練習させます。


Tamasはもちろん、現実には文字列を暗号化する方法ではないことを説明しても間違いありません。ブロック暗号でプレーンテキスト(バイトに変換)を暗号化する代わりに、ハイブリッド暗号システムを使用します。

+0

もちろん、それが合う限り、いくつかの文字を一緒に取ることもできます。まずバイトを(たとえばASCIIを使用して)バイトにエンコードし、結果のバイトを整数に変換します。 –

+0

しかし、解読するときにどのような整数がどの文字に対応しているかはどうでしょうか?例えば。 15は "o"か "ae"でしょうか? –

+0

どちらもありません。あなたは、 'x = ord(x)#文字をASCII参照番号に変換するのと同じ文字の値を期待するでしょう(単一の文字を考慮して)。もちろん、 'x = chr(x)'は暗号化の後に情報を捨てるので、使用しないでください。 –

関連する問題