수색…


소개

암호화는 보안 목적으로 사용됩니다. IDEA 암호화 MODE CTR을 사용하는 Python의 암호화 / 암호 해독에 대한 예는 그리 많지 않습니다. 이 문서의 목표 :

스테이션 간 통신에서 RSA 디지털 서명 구성표를 확장하고 구현합니다. 메시지의 무결성을 위해 해싱을 사용하면 SHA-1입니다. 간단한 키 전송 프로토콜을 생성합니다. IDEA 암호화로 키 암호화. 블록 암호 모드는 카운터 모드입니다.

비고

사용 된 언어 : Python 2.7 (링크 다운로드 : https://www.python.org/downloads/ )

사용 된 라이브러리 :

* PyCrypto (링크 다운로드 : https://pypi.python.org/pypi/pycrypto )

* PyCryptoPlus (링크 다운로드 : https://github.com/doegox/python-cryptoplus )

라이브러리 설치 :

PyCrypto : 파일의 압축을 풉니 다. 디렉토리로 이동하여 창에 대해 linux (alt + ctrl + t) 및 CMD (shift + 마우스 오른쪽 버튼 + 명령 프롬프트 선택 열기) 터미널을 엽니 다. 그 후에 python setup.py install (Windows OS에서 Python Environment가 올바르게 설정되었는지 확인하십시오)

PyCryptoPlus : 마지막 라이브러리와 동일합니다.

작업 구현 : 작업은 두 부분으로 분리됩니다. 하나는 핸드 셰이크 프로세스이고 다른 하나는 통신 프로세스입니다. 소켓 설정 :

  • 공용 키와 해시 키를 생성하고 공개 키를 해싱 할 때 소켓을 설정해야합니다. 소켓을 설정하려면 "import socket"을 사용하여 다른 모듈을 가져온 다음 IP 주소와 포트를 사용자가 소켓에서 가져와 연결 (클라이언트의 경우) 또는 바인딩 (서버의 경우)해야합니다.

    ----------고객 입장에서----------

      server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
      host = raw_input("Server Address To Be Connected -> ")
      port = int(input("Port of The Server -> "))
      server.connect((host, port))
    

    ----------서버 측---------

      try:
      #setting up socket
      server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)     
      server.bind((host,port))
      server.listen(5)
      except BaseException: print "-----Check Server Address or Port-----"
    

    "socket.AF_INET, socket.SOCK_STREAM"을 사용하면 accept () 함수 및 메시징 기본 사항을 사용할 수 있습니다. 그 대신 "socket.AF_INET, socket.SOCK_DGRAM"을 사용할 수도 있지만 그 시간에는 setblocking (value)을 사용해야합니다.

핸드 쉐이크 프로세스 :

  • (CLIENT) 첫 번째 작업은 공개 키와 개인 키를 만드는 것입니다. 비공개 및 공개 키를 만들려면 일부 모듈을 가져와야합니다. 그들은 다음과 같습니다 : Crypto import Random과 Crypto.PublicKey import RSA에서. 키를 만들려면 몇 줄의 간단한 코드를 작성해야합니다.
random_generator = Random.new().read
        key = RSA.generate(1024,random_generator) 
        public = key.publickey().exportKey()

random_generator는 " Crypto import Random "모듈 에서 파생됩니다. 키는 " Crypto.PublicKey import RSA " 에서 파생됩니다.이 RSA 는 임의의 문자를 생성하여 1024의 개인 키를 생성합니다. Public은 이전에 생성 된 개인 키에서 공개 키를 내보내고 있습니다.

  • (CLIENT) 공개 키와 개인 키를 생성 한 후에 SHA-1 해시를 사용하여 서버로 보내도록 공개 키를 해시해야합니다. SHA-1 해시를 사용하려면 "import hashlib"을 작성하여 다른 모듈을 가져와야합니다. 공개 키를 해시하기 위해 두 줄의 코드를 작성했습니다.

      hash_object = hashlib.sha1(public) 
      hex_digest = hash_object.hexdigest()
    

여기서 hash_object와 hex_digest는 변수입니다. 그런 다음 클라이언트는 hex_digest와 public을 서버에 보내고 Server는 클라이언트에서 가져온 해시와 공개 키의 새 해시를 비교하여 확인합니다. 새 해시와 클라이언트의 해시가 일치하면 다음 절차로 이동합니다. 클라이언트에서 보낸 대중이 문자열 형식이므로 서버 측에서 키로 사용할 수 없습니다. 이를 방지하고 문자열 공개 키를 RSA 공개 키로 변환하려면 server_public_key = RSA.importKey(getpbk) 를 작성해야합니다. 여기서 getpbk는 클라이언트의 공개 키입니다.

  • (SERVER) 다음 단계는 세션 키를 만드는 것입니다. 여기서는 "os"모듈을 사용하여 16 비트 길이의 키를 제공하는 임의의 키 "key = os.urandom (16)"을 만든 다음 해당 키를 "AES.MODE_CTR"로 암호화하고 다시 해시했습니다 SHA-1 :

     #encrypt CTR MODE session key
     en = AES.new(key_128,AES.MODE_CTR,counter = lambda:key_128) encrypto = en.encrypt(key_128)
     #hashing sha1
     en_object = hashlib.sha1(encrypto)
     en_digest = en_object.hexdigest()
    

따라서 en_digest가 세션 키가됩니다.

  • (SERVER) 핸드 쉐이크 프로세스의 마지막 부분은 클라이언트에서 가져온 공개 키와 서버 측에서 생성 한 세션 키를 암호화하는 것입니다.

     #encrypting session key and public key
     E = server_public_key.encrypt(encrypto,16)
    

암호화 한 후 서버는 문자열을 클라이언트에 전달합니다.

  • (클라이언트) 서버에서 (공개 및 세션 키)의 암호화 된 문자열을 가져온 후 클라이언트는 공개 키와 함께 이전에 생성 된 개인 키를 사용하여 암호를 해독합니다. 암호화 된 (공개 키와 세션 키)가 문자열 형식이므로 eval ()을 사용하여 키로 다시 가져와야합니다. 암호 해독이 완료되면 양측이 동일한 키를 사용하고 있음을 확인하므로 핸드 쉐이크 프로세스도 완료됩니다. 해독하려면 다음 단계를 따르세요.

     en = eval(msg)
     decrypt = key.decrypt(en)
     # hashing sha1
     en_object = hashlib.sha1(decrypt) en_digest = en_object.hexdigest()
    

나는 SHA-1을 출력물에서 읽을 수 있도록 여기에 사용했다.

통신 프로세스 :

통신 프로세스의 경우 IDEA 암호화 MODE_CTR에 대한 KEY로 양쪽 세션 키를 사용해야합니다. 양측은 세션 키를 사용하여 IDEA.MODE_CTR로 메시지를 암호화하고 해독합니다.

  • (암호화) IDEA 암호화를 위해서는 크기와 카운터가 16 비트이어야하며 호출 가능해야합니다. 카운터는 MODE_CTR에서 필수입니다. 우리가 암호화하고 해시 한 세션 키는 이제 IDEA 암호화의 제한 키를 초과하는 40의 크기입니다. 따라서 우리는 세션 키의 크기를 줄여야합니다. 줄이기 위해 함수 문자열 [value : value]에 내장 된 일반 파이썬을 사용할 수 있습니다. 여기서 값은 사용자의 선택에 따라 임의의 값이 될 수 있습니다. 여기서는 키에서 0에서 16까지의 값을 취할 "키 [: 16]"을 수행했습니다. 이 변환은 키 [1:17] 또는 키 [16 :]와 같은 여러 가지 방법으로 수행 할 수 있습니다. 다음 부분은 처리를 위해 3 개의 인수를 취할 IDEA.new ()를 작성하여 새로운 IDEA 암호화 함수를 작성하는 것입니다. 첫 번째 인수는 KEY이고, 두 번째 인수는 IDEA 암호화 모드 (우리의 경우 IDEA.MODE_CTR)이고 세 번째 인수는 반드시 호출 가능 함수 인 counter =가 될 것입니다. 카운터 =는 함수에 의해 리턴 될 문자열의 크기를 보유합니다. counter =를 정의하려면 합리적인 값을 사용해야합니다. 이 경우, 람다를 정의하여 KEY의 크기를 사용했습니다. 람다를 사용하는 대신에 카운터 =에 임의의 값을 생성하는 Counter.Util을 사용할 수 있습니다. Counter.Util을 사용하려면 암호 모듈에서 카운터 모듈을 가져와야합니다. 따라서 코드는 다음과 같습니다.

      ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key)
    

IDEA 암호화 변수로 "ideaEncrypt"를 정의한 후에 내장 된 암호화 기능을 사용하여 모든 메시지를 암호화 할 수 있습니다.

eMsg = ideaEncrypt.encrypt(whole)
#converting the encrypted message to HEXADECIMAL to readable eMsg =         
eMsg.encode("hex").upper()

이 코드 세그먼트에서 전체는 암호화 될 메시지이고 eMsg는 암호화 된 메시지입니다. 메시지를 암호화 한 후 읽을 수 있도록 HEXADECIMAL로 변환하고 upper ()는 대문자로 만드는 내장 함수입니다. 그런 다음이 암호화 된 메시지는 암호 해독을 위해 반대 스테이션으로 전송됩니다.

  • (해독)

암호화 된 메시지를 해독하려면 동일한 인수와 동일한 키를 사용하여 다른 암호화 변수를 만들어야하지만 이번에는 변수가 암호화 된 메시지를 해독합니다. 마지막 시간과 동일한 코드입니다. 그러나 메시지를 해독하기 전에 16 진수의 메시지를 해독해야합니다. 암호화 부분에서 16 진수로 암호화 된 메시지를 읽을 수 있도록 인코딩했기 때문입니다. 따라서 전체 코드는 다음과 같습니다.

decoded = newmess.decode("hex")
ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key) 
dMsg = ideaDecrypt.decrypt(decoded)

이러한 프로세스는 암호화 및 암호 해독을 위해 서버 및 클라이언트 측에서 수행됩니다.

서버 측 구현

import socket
import hashlib
import os
import time
import itertools
import threading
import sys
import Crypto.Cipher.AES as AES
from Crypto.PublicKey import RSA
from CryptoPlus.Cipher import IDEA

#server address and port number input from admin
host= raw_input("Server Address - > ")
port = int(input("Port - > "))
#boolean for checking server and port
check = False
done = False

def animate():
    for c in itertools.cycle(['....','.......','..........','............']):
        if done:
            break
        sys.stdout.write('\rCHECKING IP ADDRESS AND NOT USED PORT '+c)
        sys.stdout.flush()
        time.sleep(0.1)
    sys.stdout.write('\r -----SERVER STARTED. WAITING FOR CLIENT-----\n')
try:
    #setting up socket
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind((host,port))
    server.listen(5)
    check = True
except BaseException:
    print "-----Check Server Address or Port-----"
    check = False

if check is True:
    # server Quit
    shutdown = False
# printing "Server Started Message"
thread_load = threading.Thread(target=animate)
thread_load.start()

time.sleep(4)
done = True
#binding client and address
client,address = server.accept()
print ("CLIENT IS CONNECTED. CLIENT'S ADDRESS ->",address)
print ("\n-----WAITING FOR PUBLIC KEY & PUBLIC KEY HASH-----\n")

#client's message(Public Key)
getpbk = client.recv(2048)

#conversion of string to KEY
server_public_key = RSA.importKey(getpbk)

#hashing the public key in server side for validating the hash from client
hash_object = hashlib.sha1(getpbk)
hex_digest = hash_object.hexdigest()

if getpbk != "":
    print (getpbk)
    client.send("YES")
    gethash = client.recv(1024)
    print ("\n-----HASH OF PUBLIC KEY----- \n"+gethash)
if hex_digest == gethash:
    # creating session key
    key_128 = os.urandom(16)
    #encrypt CTR MODE session key
    en = AES.new(key_128,AES.MODE_CTR,counter = lambda:key_128)
    encrypto = en.encrypt(key_128)
    #hashing sha1
    en_object = hashlib.sha1(encrypto)
    en_digest = en_object.hexdigest()

    print ("\n-----SESSION KEY-----\n"+en_digest)

    #encrypting session key and public key
    E = server_public_key.encrypt(encrypto,16)
    print ("\n-----ENCRYPTED PUBLIC KEY AND SESSION KEY-----\n"+str(E))
    print ("\n-----HANDSHAKE COMPLETE-----")
    client.send(str(E))
    while True:
        #message from client
        newmess = client.recv(1024)
        #decoding the message from HEXADECIMAL to decrypt the ecrypted version of the message only
        decoded = newmess.decode("hex")
        #making en_digest(session_key) as the key
        key = en_digest[:16]
        print ("\nENCRYPTED MESSAGE FROM CLIENT -> "+newmess)
        #decrypting message from the client
        ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key)
        dMsg = ideaDecrypt.decrypt(decoded)
        print ("\n**New Message**  "+time.ctime(time.time()) +" > "+dMsg+"\n")
        mess = raw_input("\nMessage To Client -> ")
        if mess != "":
            ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key)
            eMsg = ideaEncrypt.encrypt(mess)
            eMsg = eMsg.encode("hex").upper()
            if eMsg != "":
                print ("ENCRYPTED MESSAGE TO CLIENT-> " + eMsg)
            client.send(eMsg)
    client.close()
else:
    print ("\n-----PUBLIC KEY HASH DOESNOT MATCH-----\n")

클라이언트 측 구현

import time
import socket
import threading
import hashlib
import itertools
import sys
from Crypto import Random
from Crypto.PublicKey import RSA
from CryptoPlus.Cipher import IDEA

#animating loading
done = False
def animate():
    for c in itertools.cycle(['....','.......','..........','............']):
        if done:
            break
        sys.stdout.write('\rCONFIRMING CONNECTION TO SERVER '+c)
        sys.stdout.flush()
        time.sleep(0.1)

#public key and private key
random_generator = Random.new().read
key = RSA.generate(1024,random_generator)
public = key.publickey().exportKey()
private = key.exportKey()

#hashing the public key
hash_object = hashlib.sha1(public)
hex_digest = hash_object.hexdigest()

#Setting up socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

#host and port input user
host = raw_input("Server Address To Be Connected -> ")
port = int(input("Port of The Server -> "))
#binding the address and port
server.connect((host, port))
# printing "Server Started Message"
thread_load = threading.Thread(target=animate)
thread_load.start()

time.sleep(4)
done = True

def send(t,name,key):
    mess = raw_input(name + " : ")
    key = key[:16]
    #merging the message and the name
    whole = name+" : "+mess
    ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key)
    eMsg = ideaEncrypt.encrypt(whole)
    #converting the encrypted message to HEXADECIMAL to readable
    eMsg = eMsg.encode("hex").upper()
    if eMsg != "":
        print ("ENCRYPTED MESSAGE TO SERVER-> "+eMsg)
    server.send(eMsg)
def recv(t,key):
    newmess = server.recv(1024)
    print ("\nENCRYPTED MESSAGE FROM SERVER-> " + newmess)
    key = key[:16]
    decoded = newmess.decode("hex")
    ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key)
    dMsg = ideaDecrypt.decrypt(decoded)
    print ("\n**New Message From Server**  " + time.ctime(time.time()) + " : " + dMsg + "\n")

while True:
    server.send(public)
    confirm = server.recv(1024)
    if confirm == "YES":
        server.send(hex_digest)

    #connected msg
    msg = server.recv(1024)
    en = eval(msg)
    decrypt = key.decrypt(en)
    # hashing sha1
    en_object = hashlib.sha1(decrypt)
    en_digest = en_object.hexdigest()

    print ("\n-----ENCRYPTED PUBLIC KEY AND SESSION KEY FROM SERVER-----")
    print (msg)
    print ("\n-----DECRYPTED SESSION KEY-----")
    print (en_digest)
    print ("\n-----HANDSHAKE COMPLETE-----\n")
    alais = raw_input("\nYour Name -> ")

    while True:
        thread_send = threading.Thread(target=send,args=("------Sending Message------",alais,en_digest))
        thread_recv = threading.Thread(target=recv,args=("------Recieving Message------",en_digest))
        thread_send.start()
        thread_recv.start()

        thread_send.join()
        thread_recv.join()
        time.sleep(0.5)
    time.sleep(60)
    server.close()


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow