2011-12-16 27 views
17

私の検索で見つけられなかったモジュールがあり、次のようなコードを書くことができますか?このようなコードを書こうとする理由は重要ではありません。私が後にしているのは、パブリックとプライベートのバイトキーを生成し、それらのキーを使ってデータを簡単にエンコードしてデコードする簡単なAPIを持つコードです。標準ライブラリを使用したPythonでのプライベート/パブリック暗号化

import module, os 

method, bits, data = 'RSA', 1024, os.urandom(1024) 
public, private = module.generate_keys(method, bits) 

assert isinstance(public, bytes) and isinstance(private, bytes) 
assert module.decode(module.encode(data, private), public) == data 
assert module.decode(module.encode(data, public), private) == data 

利用可能と思われるほとんどのものは、パッケージをダウンロードする必要があり、Python 2.xでのみ動作します。また、PEMファイルやその他の種類の証明書で動作するライブラリを見つけることも非常に一般的です。私はそのようなファイルに対処し、その場で公開鍵と秘密鍵を生成し、メモリ内のデータをすばやく処理する必要はありません。

+1

は、私が理想的な解決策を知っていないもう一つの例ですが、あなたは常にこれらのライブラリのサポートのいずれかの場合は知っていますコマンドライン – TJD

答えて

30

公開鍵暗号化は標準ライブラリにありません。 PyPiにいくつかのサードパーティのライブラリはしかしそれのためにあります:あなたがその背後にある数学に興味があるなら

、Pythonは実験することが容易になります:

code = pow(msg, 65537, 5551201688147)    # encode using a public key 
plaintext = pow(code, 109182490673, 5551201688147) # decode using a private key 

鍵の生成はもう少し複雑です。次に、urandomをエントロピーのソースとして使用して、鍵の生成をメモリ内で行う方法の簡単な例を示します。コードはPy2.6とPy3.x両方の下で実行されます:2.4.1のようにPythonの3の

import random 

def gen_prime(N=10**8, bases=range(2,20000)): 
    # XXX replace with a more sophisticated algorithm 
    p = 1 
    while any(pow(base, p-1, p) != 1 for base in bases): 
     p = random.SystemRandom().randrange(N) 
    return p 

def multinv(modulus, value): 
    '''Multiplicative inverse in a given modulus 

     >>> multinv(191, 138) 
     18 
     >>> 18 * 138 % 191 
     1 

    ''' 
    # http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm 
    x, lastx = 0, 1 
    a, b = modulus, value 
    while b: 
     a, q, b = b, a // b, a % b 
     x, lastx = lastx - q * x, x 
    result = (1 - lastx * modulus) // value 
    return result + modulus if result < 0 else result 

def keygen(N): 
    '''Generate public and private keys from primes up to N. 

     >>> pubkey, privkey = keygen(2**64) 
     >>> msg = 123456789
     >>> coded = pow(msg, 65537, pubkey) 
     >>> plain = pow(coded, privkey, pubkey) 
     >>> assert msg == plain 

    ''' 
    # http://en.wikipedia.org/wiki/RSA 
    prime1 = gen_prime(N) 
    prime2 = gen_prime(N) 
    totient = (prime1 - 1) * (prime2 - 1) 
    return prime1 * prime2, multinv(totient, 65537) 
+1

を経由してのgpgを呼び出すためにPythonのsubprocessモジュールを使用して戻って落ちる可能性上記のような単純なAPIとPython 3.xで動作する両方のAPI? –

+3

RSA Pythonリンクには、あなたが探しているものの多くを含む純粋なPythonコードが含まれています。探しているAPIと正確に一致するように少し修正する必要があります。 APSNのレシピ、powの例、PyCryptoはPython 3でうまく動作します。 –

+0

こんにちは@RaymondHettinger。私はここで説明したように、このalgoをjavaに実装したかったのです。しかし、私はPythonが 'pow(code、pub、pri)で簡単に何をするのかは、javaで計算することはほとんど不可能であることが分かります。私はsthが足りないと思う。あなたは私にsthをお勧めしますか? (さえありません、答えに感謝します:)) –

2

はここ

import random 


# RSA Algorithm 



ops = raw_input('Would you like a list of prime numbers to choose from (y/n)? ') 
op = ops.upper() 

if op == 'Y': 
    print """\n 2  3  5  7  11  13  17  19  23  29 
31  37  41  43  47  53  59  61  67  71 
73  79  83  89  97 101 103 107 109 113 
127 131 137 139 149 151 157 163 167 173 
179 181 191 193 197 199 211 223 227 229 
233 239 241 251 257 263 269 271 277 281 
283 293 307 311 313 317 331 337 347 349 
353 359 367 373 379 383 389 397 401 409 
419 421 431 433 439 443 449 457 461 463 
467 479 487 491 499 503 509 521 523 541 
547 557 563 569 571 577 587 593 599 \n""" 
    rsa() 
else: 
    print "\n" 
    rsa() 

def rsa(): 
    # Choose two prime numbers p and q 
    p = raw_input('Choose a p: ') 
    p = int(p) 

while isPrime(p) == False: 
    print "Please ensure p is prime" 
    p = raw_input('Choose a p: ') 
    p = int(p) 

q = raw_input('Choose a q: ') 
q = int(q) 

while isPrime(q) == False or p==q: 
    print "Please ensure q is prime and NOT the same value as p" 
    q = raw_input('Choose a q: ') 
    q = int(q) 

# Compute n = pq 
n = p * q 

# Compute the phi of n 
phi = (p-1) * (q-1) 

# Choose an integer e such that e and phi(n) are coprime 
e = random.randrange(1,phi) 

# Use Euclid's Algorithm to verify that e and phi(n) are comprime 
g = euclid(e,phi) 
while(g!=1): 
    e = random.randrange(1,phi) 
    g = euclid(e,phi) 

# Use Extended Euclid's Algorithm 
d = extended_euclid(e,phi) 

# Public and Private Key have been generated 
public_key=(e,n) 
private_key=(d,n) 
print "Public Key [E,N]: ", public_key 
print "Private Key [D,N]: ", private_key 

# Enter plain text to be encrypted using the Public Key 
sentence = raw_input('Enter plain text: ') 
letters = list(sentence) 

cipher = [] 
num = "" 

# Encrypt the plain text 
for i in range(0,len(letters)): 
    print "Value of ", letters[i], " is ", character[letters[i]] 

    c = (character[letters[i]]**e)%n 
    cipher += [c] 
    num += str(c) 
print "Cipher Text is: ", num 

plain = [] 
sentence = "" 

# Decrypt the cipher text  
for j in range(0,len(cipher)): 

    p = (cipher[j]**d)%n 

    for key in character.keys(): 
     if character[key]==p: 
      plain += [key] 
      sentence += key 
      break 
print "Plain Text is: ", sentence 

# Euclid's Algorithm 
def euclid(a, b): 
    if b==0: 
    return a 
else: 
    return euclid(b, a % b) 

# Euclid's Extended Algorithm 
def extended_euclid(e,phi): 
    d=0 
    x1=0 
    x2=1 
    y1=1 
    orig_phi = phi 
    tempPhi = phi 

while (e>0): 
    temp1 = int(tempPhi/e) 
    temp2 = tempPhi - temp1 * e 
    tempPhi = e 
    e = temp2 

    x = x2- temp1* x1 
    y = d - temp1 * y1 

    x2 = x1 
    x1 = x 
    d = y1 
    y1 = y 

    if tempPhi == 1: 
     d += phi 
     break 
return d 

# Checks if n is a prime number 
def isPrime(n): 
    for i in range(2,n): 
    if n%i == 0: 
     return False 
return True 

character = {"A":1,"B":2,"C":3,"D":4,"E":5,"F":6,"G":7,"H":8,"I":9,"J":10, 
    "K":11,"L":12,"M":13,"N":14,"O":15,"P":16,"Q":17,"R":18,"S":19, 
    "T":20,"U":21,"V":22,"W":23,"X":24,"Y":25,"Z":26,"a":27,"b":28, 
    "c":29,"d":30,"e":31,"f":32,"g":33,"h":34,"i":35,"j":36,"k":37, 
    "l":38,"m":39,"n":40,"o":41,"p":42,"q":43,"r":44,"s":45,"t":46, 
    "u":47,"v":48,"w":49,"x":50,"y":51,"z":52, " ":53, ".":54, ",":55, 
    "?":56,"/":57,"!":58,"(":59,")":60,"$":61,":":62,";":63,"'":64,"@":65, 
    "#":66,"%":67,"^":68,"&":69,"*":70,"+":71,"-":72,"_":73,"=":74} 
関連する問題