[실습] 소켓 프로그래밍 예제
Network Programming == Socket Programming
TCP 소켓 통신 과정
- 서버에서는 socket(), bind(), listen(), accept()순으로 함수들을 호출하여 리스닝 소켓을 생성한다. 리스닝 소켓을 클라이언트의 접속을 대기하는 역활을 한다.
- 클라이언트가 연결되면 accept()에서 새로운 소켓을 리턴하여 클라이언트와 통신시 사용하도록 한다.
- 클라이언트는 connect() 함수를 호출하여 서버에 연결을 시도한다. 이때부터 3-way 핸드세이크를 시작한다. 핸드 세이크는 네트워크를 통해 양쪽이 연결되는 것을 보장하므로 중요하다. 클라이언트가 서버에 도달할 수 있으며 그 반대도 마찬가지이다.
- 연결이 완료된 후, 서버와 클라이언트는 send() 함수와 recv() 함수를 호출하여 데이터를 주고 받는다.
- 클라이언트가 연결 종료 메시지를 전송하거나 소켓을 닫으면 서버는 클라이언트와 통신을 위해 사용한 소켓을 닫는다.
[예제1] 간단한 메세지 전송
1) 메세지 전송 클라이언트
client.py
import socket
ip = '127.0.0.1'
port = 4444
c = socket.socket()
c.connect((ip, port))
fd = open('plain', 'rb')
c.sendall(fd.read())
c.close()
2) 메세지 받는 서버
server.py
import socket
ip = '127.0.0.1'
port = 4444
s = socket.socket()
s.bind((ip, port))
s.listen(1)
client, address = s.accept()
print("Connected by", address)
recv_msg = b''
while True:
data = client.recv(1024)
if not data:
client.close()
break
recv_msg += data
print(len(recv_msg), recv_msg)
s.close()
[예제4] clientAES.py, serverAES.py
clientDES.py, serverDES.py 파일 처럼 이전에 작성된 모듈을 import 해서 사용하지 않고 socket 프로그램밍을 사용하고 AES 알고리즘을 사용하여 만들었다.
clientAES.py
###!/usr/bin/python3
import sys
import os
import socket
from Crypto.Cipher import AES
from Crypto.Hash import SHA256 as SHA
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
def main():
infile = 'file.in'
keytext = 'abc123'
key = convert_strkey_to_binkey(keytext)
iv = get_random_bytes(16)
encmsg = from_infile_to_encmsg(infile, key, iv)
sendmsg = iv + encmsg
host = '127.0.0.1'
port = 7979
send_msg_to_server(host, port, sendmsg)
def send_msg_to_server(ip, port, msg):
try:
c = socket.socket()
c.connect((ip, port))
except Exception as e:
print("Error:", e)
sys.exit(3)
else:
c.sendall(msg)
finally:
c.close()
def from_infile_to_encmsg(file, k , i):
# input : file(file), b'k', b'i'
# output: b'encmsg'
# functions:
# * file(text) -> msg -> Encrytion -> encmsg
if os.path.exists(file):
fd = open(file, 'rb')
binmsg = fd.read()
cipher = AES.new(k, AES.MODE_CBC, i)
encmsg = cipher.encrypt(pad(binmsg, 16))
else:
print("Error: File(%s) not found" % file)
sys.exit(2)
return encmsg
def convert_strkey_to_binkey(ktext):
# input : str(ktext)
# output: bin(keyhash)
# functions:
hash = SHA.new(ktext.encode())
keyhash = hash.digest()[:16]
return keyhash
if __name__ == '__main__':
main()
serverAES.py
###!/usr/bin/python3
import os
import sys
import socket
from Crypto.Cipher import AES
from Crypto.Hash import SHA256 as SHA
from Crypto.Util.Padding import pad, unpad
def main():
outfile = 'file.out'
keytext = 'abc123'
key = convert_strkey_to_binkey(keytext)
# print(key)
host = '127.0.0.1'
port = 7979
encmsg = recv_encmsg(host, port)
iv = encmsg[:16]
encmsg = encmsg[16:]
# print(iv, encmsg)
from_encmsg_to_outfile(encmsg, key, iv, outfile)
def from_encmsg_to_outfile(msg, k,i, file):
# input : b'msg', b'k', b'i', file(file)
# output:?(file(filename))
# functions :
# * encmsg -> Decryption -> decmsg -> File
if os.path.exists(file):
print("File(%s) exists" % file)
choice =input("Selecting (C)ontinue, (Q)uit :")
if not choice.lower().startswith('c'):
return
cipher = AES.new(k, AES.MODE_CBC, i)
decmsg = unpad(cipher.decrypt(msg), 16)
fd = open(file, 'w')
fd.write(decmsg.decode())
fd.close()
def recv_encmsg(ip, port):
# input : str(ip), int(port)
# output: recvdata
# functions:
# * socket -> recvdata ->
try:
s = socket.socket()
s.bind((ip, port))
s.listen(1)
client, address = s.accept()
print("Connected by", address)
except Exception as e:
print("Error:", e)
sys.exit(2)
else:
recvdata = b''
while True:
data = client.recv(1024)
if not data:
client.close()
break
recvdata += data
finally:
s.close()
return recvdata
def convert_strkey_to_binkey(ktext):
# input : str(ktext)
# output: bin(keyhash)
# functions:
hash = SHA.new(ktext.encode())
keyhash = hash.digest()[:16]
return keyhash
if __name__ == '__main__':
main()
[정리]
1)
msg -> E(msg) -> encmsg
encmsg -> D(encmsg) -> decmsg2)
File(p) -> msg -> E(msg) -> encmsg -> File(C)
File(C) -> encmsg -> D(encmsg) -> decmsg -> File(P)
3)
msg -> E(msg) -> encmsg -> 메세지 전송
메세지 수신 -> encmsg -> D(encmsg) -> decmsg
File(p) -> msg -> E(msg) -> encmsg -> 메세지 전송
메세지 수신 -> encmsg -> D(encmsg) -> decmsg -> File(p)
'현대 암호학' 카테고리의 다른 글
[현대 암호학] 06-3. 정수론 (0) | 2021.06.28 |
---|---|
[현대 암호학] 06. 공개 키 암호 - 1. 키 배송 문제 / 2. 공개 키 암호 (0) | 2021.06.28 |
[현대 암호학] 05. 실습(4) (0) | 2021.06.24 |
[현대 암호학] 05. 실습(3) (0) | 2021.06.24 |
[현대 암호학] 05. 실습(2) (0) | 2021.06.23 |