Python Language
클라이언트와 서버 간의 소켓 및 메시지 암호화 / 암호 해독
수색…
소개
암호화는 보안 목적으로 사용됩니다. 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()