2011-12-16 4 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에 대한 몇 가지 타사 라이브러리하지만 있습니다

, 파이썬은 쉽게 실험 할 수 있습니다 :

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의 파이썬 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를 호출하는 파이썬 하위 프로세스 모듈을 사용하여 다시 떨어질 수 위에서 보여준 간단한 API와 파이썬 3.x에서 실행되는 간단한 API 모두? –

+3

RSA Python 링크에는 찾고있는 것의 대부분을 포함하는 순수한 파이썬 코드가 있습니다. 찾고있는 API와 정확히 일치시키기 위해 약간 수정해야 할 것입니다. APSN recipes, pow examples, PyCrypto는 Python 3에서 잘 작동합니다. –

+0

안녕하세요 @RaymondHettinger. 나는 당신이 여기서 설명한 것처럼이 algo를 java에 구현하려고했다. 하지만 파이썬이'pow (code, pub, pri) '로 쉽게하는 일은 자바로 계산하는 것이 거의 불가능하다는 것을 알 수 있습니다. 나는 내가 실종 된 것 같아. 나에게 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} 
관련 문제