Professional Documents
Culture Documents
KTLT-L03-nhóm4-báo Cáo
KTLT-L03-nhóm4-báo Cáo
Lời đầu tiên, nhóm chúng em xin chân thành gửi lời cảm ơn đến thầy Nguyễn
Mạnh Thắng – giảng viên khoa An toàn thông tin trường Học viện Kỹ thuật Mật
Mã
đã tạo điều kiện cũng như cung cấp kiến thức, đồng thời đưa ra những lời khuyên
cần thiết để chúng em có thể hoàn thành đề tài này.
Trong thế giới kết nối mạng ngày nay, việc truyền dữ liệu qua mạng internet
thông qua socket programming đã trở thành một phần không thể thiếu của
cuộc sống hàng ngày và hoạt động kinh doanh. Socket programming cung cấp
khả năng thiết lập kết nối giữa các thiết bị mạng từ xa, cho phép truyền dữ
liệu một cách linh hoạt và hiệu quả. Tuy nhiên, điều quan trọng cần nhớ là
việc truyền dữ liệu qua mạng internet không chỉ đem lại lợi ích mà còn mở ra
nhiều rủi ro về an ninh thông tin.
Trong một thế giới mà tin tặc luôn tìm cách tìm kiếm lỗ hổng để tấn công hệ
thống, việc bảo vệ dữ liệu trở nên cực kỳ quan trọng. Socket programming,
với tính linh hoạt và mạnh mẽ của nó, không nằm ngoài tầm ngắm của những
kẻ tấn công này. Bất kỳ lỗ hổng nào trong ứng dụng có thể được lợi dụng để
xâm nhập vào hệ thống, đánh cắp dữ liệu quan trọng hoặc thậm chí là gây hại
cho hệ thống.
Bài báo cáo này sẽ đề cập đến những thách thức và giải pháp trong việc đảm
bảo an toàn trong socket programming. Bài này sẽ nói về các biện pháp bảo
mật cơ bản và nâng cao, từ việc sử dụng mã hóa dữ liệu đến cơ chế xác thực
và kiểm soát truy cập. Bằng cách hiểu rõ về những nguy cơ tiềm ẩn và áp
dụng các kỹ thuật bảo mật phù hợp, người dùng có thể xây dựng những ứng
dụng mạng an toàn và tin cậy, đóng góp vào sự phát triển bền vững của
internet và nền kinh tế số.
Hy vọng rằng bài báo cáo này sẽ giúp độc giả có cái nhìn sâu sắc hơn về vấn
đề an ninh mạng và truyền dữ liệu qua socket, đồng thời cung cấp cái nhìn về
các biện pháp bảo mật hiện đại và tiên tiến nhất để đối phó với những thách
thức đó.
CHƯƠNG I – GIỚI THIỆU VỀ SOCKET PROGRAMING
1.1. Tổng quan về Socket và mục đích của Socket Programing
1.1.1. Tổng quan
a. Socket và lập trình Socket
Socket là một điểm cuối của liên kết giao tiếp hai chiều (two-way
communication) giữa hai chương trình đang chạy trên mạng. Nó hoạt động như
một cánh cửa kết nối, cung cấp khả năng truyền dữ liệu giữa các chương trình
với nhau.
Lập trình Socket là một mô hình lập trình cho phép giao tiếp giữa các tiến trình
(ứng dụng/chương trình) qua mạng. Nó cho phép các tiến trình chạy trên các
máy
tính khác nhau trao đổi dữ liệu.
b. Cấu trúc
Socket được định nghĩa trong hệ điều hành bằng một cấu trúc, được xem như
điểm nối để hai chương trình giao tiếp với nhau. Cấu trúc của socket có 5
trường,
gồm:
− Family: xác định họ địa chỉ socket sử dụng (IPv4, IPv6,...).
− Protocol: chỉ định giao thức cụ thể được sử dụng (thường được gán = 0).
− Local Socket Address và Remote Socket Address: là địa chỉ socket của
− Đầu tiên, máy chủ A sẽ khởi tạo kết nối bằng cách gửi gói tin SYN đến máy
chủ đích. Gói tin này chứa một số ngẫu nhiên(ví dụ:100) đánh dấu sự bắt đầu
của số thứ tự
cho dữ liệu mà máy chủ A sẽ truyền.
− Máy chủ đích nhận gói SYN của A, sau đó nó sẽ phản hồi lại bằng gói SYN
là số thứ tự của của máy A tăng thêm 1 (VD: 101), và gói ACK là số của máy
server (VD: 200). (số xác nhận)
− Máy chủ A sau khi nhận được 2 gói ACK và SYN từ máy chủ đích, cũng sẽ
gửi lại một gói ACK xác nhận là số thứ tự của máy đích tăng thêm 1 (VD:
102).
Sau khi 3 bước được thực hiện, kênh truyền giữa 2 máy đã được tạo và nó sẽ
duy
trì liên tục cho đến khi kết thúc quá trình truyền tin. Để đi vào chi tiết hơn, hình
sau sẽ nói về cơ chế hoạt động của Stream Socket:
− Bước 1: Client sẽ tạo ra 1 socket có chức năng gửi yêu cầu kết nối với Server.
Còn Server sẽ tạo 1 socket có chức năng lắng nghe và chấp nhận các yêu cầu
kết nối từ phía Client. Quá trình tạo sẽ sử dụng hàm socket(). Sau đó, hai bên
sẽ gán địa chỉ đích và Port cho socket của mình.
− Bước 2: Socket ở phía Client sẽ gửi đi gói tin SYN như một yêu cầu kết nối
bằng hàm connect(), trong khi socket ở Server sẽ lắng nghe yêu cầu bằng
hàm listen(). Khi “bắt” được yêu cầu từ phía Client, nó sẽ chấp nhận kết nối
bằng hàm accept().
− Bước 3: Server sẽ tạo một socket mới có chức năng truyền và nhận dữ liệu.
Sau đó, Client và Server sẽ trao đổi các gói tin ACK và SYN như đã trình
bày ở trên qua socket này, tiếp theo chúng mới truyền và nhận dữ liệu của
nhau qua hàm send() và recv().
− Bước 4: Sau khi quá trình trao đổi dữ liệu hoàn tất, tài nguyên trên socket sẽ
được giải phóng bằng hàm close(). Tuy nhiên socket không bị xóa hoàn toàn,
mà sẽ có thể tái sử dụng nhằm tối ưu hiệu suất và tài nguyên của Server.
Có thể thấy được, mỗi loại socket đều có ưu điểm, hạn chế, cũng như các ứng
dụng đặc thù của riêng mình. Nhưng chung quy lại, chúng đều phục vụ một mục
đích chung là trao đổi dữ liệu qua Internet.
1.3. Các ứng dụng của lập trình Socket
Lập trình Socket được sử dụng rộng rãi và có nhiều ứng dụng trong các lĩnh vực
khác nhau, bao gồm:
Giao tiếp Client-Server: Lập trình socket được sử dụng rộng rãi để cho phép
giao tiếp giữa máy khách và máy chủ trong môi trường mạng. Máy chủ lắng
nghe
các kết nối đến ở các port cụ thể, trong khi máy khách kết nối với máy chủ, cho
phép chúng trao đổi dữ liệu và thực hiện nhiều tác vụ khác nhau như truyền tệp,
truy cập từ xa và nhắn tin.
Web Server và Client: Máy chủ web, chứa các trang web và phục vụ trang
web
cho các máy khách (trình duyệt web), sử dụng lập trình socket để xử lý yêu cầu
và phản hồi HTTP. Tương tự, các máy khách (trình duyệt) sử dụng socket để
giao
tiếp với các máy chủ khi truy xuất trang web, gửi yêu cầu HTTP và nhận phản
hồi.
Ứng dụng chat: Lập trình socket cho phép giao tiếp thời gian thực trong các
ứng dụng trò chuyện, cho phép người dùng gửi và nhận tin nhắn ngay lập tức.
Các máy chủ quản lý kết nối từ nhiều client và phân phối tin nhắn giữa chúng,
tạo
điều kiện cho trò chuyện một-một hoặc trò chuyện nhóm.
Trò chơi trực tuyến đa người chơi: Lập trình socket rất quan trọng cho việc
phát
triển các trò chơi trực tuyến đa người chơi, nơi người chơi tương tác thời gian
thực với nhau. Các máy chủ sử dụng socket để quản lý kết nối của người chơi,
xử
lý logic trò chơi và đồng bộ hóa trạng thái trò chơi trên nhiều client, cho phép
trải
nghiệm chơi game có tính cộng tác và cạnh tranh.
Truy cập và điều khiển từ xa: Lập trình socket tạo điều kiện cho việc truy
nhập
và kiểm soát máy tính và các thiết bị từ xa qua mạng. Các ứng dụng desktop từ
xa và bộ giả lập terminal sử dụng socket để thiết lập kết nối giữa một thiết bị
client và một hệ thống từ xa, cho phép người dùng truy cập và quản lý tài
nguyên
từ xa. Các hệ thống phân tán: Lập trình socket đóng một vai trò quan trọng trong
việc xây dựng các hệ thống phân tán, nơi nhiều thành phần độc lập giao tiếp với
nhau qua mạng. Các ứng dụng phân tán như cơ sở dữ liệu phân tán, hệ thống tệp
phân tán và các trang tính phân tán phụ thuộc vào socket để giao tiếp giữa các
tiến trình và trao đổi dữ liệu.
IoT: Trong các hệ thống IoT, các thiết bị tương tác với nhau và với các máy
chủ tập trung để thu thập dữ liệu, giám sát môi trường và điều khiển các đối
tượng
vật lý. Lập trình socket tạo điều kiện cho việc giao tiếp giữa các thiết bị IoT,
cổng
thông tin và máy chủ đám mây, cho phép truyền dữ liệu thời gian thực, thu thập
dữ liệu cảm biến và quản lý thiết bị.
Giám sát và quản lý mạng: Lập trình socket được sử dụng trong các công cụ
giám sát và quản lý mạng để thu thập thống kê, giám sát lưu lượng và quản lý
các
thiết bị mạng. Các công cụ này sử dụng socket để giao tiếp với các thiết bị
mạng,
thu thập thông tin và thực hiện các nhiệm vụ cấu hình.
Truyền dữ liệu: Các ứng dụng truyền tập tin như FTP và SCP sử dụng lập
trình
socket để truyền tập tin giữa các client và máy chủ một cách an toàn. Socket cho
phép truyền dữ liệu đáng tin cậy và hỗ trợ các tính năng như xác minh tính toàn
vẹn của tập tin và tiếp tục truyền tập tin bị gián đoạn.
Thu thập dữ liệu: Có thể sử dụng lập trình socket để tạo các kết nối mạng tới
các cổng TCP hoặc UDP trên server mục tiêu và xác định trạng thái của các
cổng
đó (mở, đóng hoặc được lọc). Bằng cách sử dụng socket, người dùng có thể thiết
lập các kết nối mạng và gửi các gói tin đến máy chủ để kiểm tra xem cổng có
sẵn
hay không. Điều này cho phép hacker xác định được thông tin ban đầu của mục
tiêu để khai thác các lỗ hổng và thực hiện tấn công. Bên cạnh đó, lập trình
socket
cũng giúp người quản trị mạng đánh giá được độ an toàn của hệ thống để đưa ra
những giải pháp khắc phục, phòng chống xâm nhập.
1.4. Các thư viện và ngôn ngữ hỗ trợ lập trình Socket
1.4.1. Các ngôn ngữ hỗ trợ lập trình Socket
Lập trình Socket chính là cốt lõi của lập trình mạng, do đó hiện nay có rất nhiều
các ngôn ngữ lập trình phổ biến hỗ trợ lập trình socket, dưới đây là một số ví
dụ:
-C/C++: là ngôn ngữ phổ biến nhất cho lập trình socket. Nó cung cấp hiệu suất
cao và khả năng kiểm soát chi tiết cho các lập trình viên. Các thư viện hỗ trợ lập
trình socket gồm: Thư viện Winsock dành cho hệ điều hành Windows; Thư viện
Berkeley sockets dành cho hệ điều hành Unix/Linux và thư viện Libevent – thư
viện đa nền tảng hỗ trợ nhiều giao thức mạng và các tính năng nâng cao.
-Java: Java là ngôn ngữ lập trình hướng đối tượng phổ biến khác hỗ trợ lập
trình
socket. Java cung cấp khả năng di động cao và dễ sử dụng. Các thư viện hỗ trợ
lập trình socket gồm: java.net.Socket: Cung cấp các lớp cơ bản để tạo kết nối
socket và gửi/nhận dữ liệu; java.nio.channels.SocketChannel: Cung cấp các lớp
hiệu suất cao hơn cho lập trình socket không đồng bộ.
-Go: Go là ngôn ngữ lập trình mới nổi được thiết kế cho hiệu suất cao và khả
năng đồng bộ. Go là lựa chọn tốt cho việc phát triển các ứng dụng socket có yêu
cầu cao.
Thư viện hỗ trợ lập trình socket là net, có chức năng cung cấp các lớp cơ bản để
tạo kết nối socket và gửi/nhận dữ liệu.
-JavaScript: JavaScript được sử dụng chủ yếu cho phát triển web, nhưng nó
cũng
có thể được sử dụng để lập trình socket. Các thư viện hỗ trợ lập trình socket
gồm
WebSocket – cung cấp giao thức cho phép truyền dữ liệu hai chiều giữa máy
chủ
và trình duyệt web và thư viện Socket.IO – thư viện hỗ trợ lập trình socket thời
gian thực cho các ứng dụng web.
-Python: Python là ngôn ngữ lập trình đơn giản và dễ học, phù hợp cho việc
phát
triển các ứng dụng socket đơn giản. Python sử dụng một số thư viện để lập trình
socket như: Thư viện socket – cung cấp các lớp cơ bản để tạo kết nối socket và
gửi/nhận dữ liệu; Asyncore – thư viện hỗ trợ lập trình socket không đồng bộ;
Twisted – Thư viện mạng mạnh mẽ hỗ trợ nhiều giao thức mạng và các tính
năng
nâng cao.
1.4.2. Giới thiệu module socket trong Python
Python cung cấp Module Socket giúp chúng ta dễ dàng thực hiện kết nối
Client/Server để giao tiếp với nhau. Để có thể sử dụng được, trước tiên ta phải
import module Socket vào chương trình:
Tạo một Socket:
self.connection, addr = self.node.accept() Phương thức này thiết lập chấp nhận kết nối
self.connection.send(SMS.encode()) Phương thức này dùng để gửi tin nhắn khi được kết
nối
Bảng 1.5: Một số phương thức dùng để kết nối và trao đổi thông tin.
Python hỗ trợ thu thập thông tin Server, bao gồm: tên miền, host, địa chỉ IP, …
với một số Module sau đây:
Dùng để dịch tên máy chủ thành địa chỉ IPv4. Địa chỉ
IPv4 được trả về dưới dạng chuỗi và được lưu vào biến
gethostbyname(hostname)
addr. gethostbyname() không hỗ trợ
IPv6.
connect_ex(IP address, port) Trả về giá trị 0 nếu thao tác thành công, ngược lại
sẽ trả về giá trị cho biến errno.
Bảng 1.6: Một số phương thức dùng để thu thập thông tin Server.
CHƯƠNG II – ỨNG DỤNG AN TOÀN SOCKET-PROGRAMING
2.1. Một số nguy cơ bảo mật trong Socket Programing
2.1.1. Thiếu xác thực trong quá trình bắt tay
WebSocket, một giao thức socket phổ biến cho giao tiếp thời gian thực, có một
quá trình bắt tay để thiết lập kết nối. Khác với các yêu cầu HTTP thông thường,
quá trình bắt tay này không bao gồm chức năng xác thực khách hàng. Điều này
có nghĩa là máy chủ không thể xác minh danh tính của khách hàng trong quá
trình kết nối ban đầu. Một số rủi ro tiềm ẩn như:
+ Mạo danh: Người dùng trái phép có thể mạo danh người dùng hợp pháp bằng
cách bắt chước các gói dữ liệu. Điều này có thể dẫn đến truy cập trái phép
hoặc các hành động trái phép.
+ Gian lận dữ liệu: Kẻ tấn công có thể chặn và sửa đổi dữ liệu chảy qua kết nối
socket.
2.1.2. Kênh TCP không được mã hóa
Một vấn đề khác với WebSockets là chúng có thể được sử dụng trên kênh TCP
không được mã hóa. Điều này dẫn đến tất cả các loại vấn đề được liệt kê trong
Top 10 phơi nhiễm dữ liệu nhạy cảm A6 của OWASP. Kênh TCP truyền dữ liệu
dưới dạng văn bản thuần túy, không được mã hóa. Điều này khiến nó dễ bị tấn
công bởi những kẻ nghe lén. Một số tác động mà chúng có thể làm:
+ Đánh cắp dữ liệu nhạy cảm: Thông tin đăng nhập, mật khẩu, dữ liệu tài chính
và các thông tin nhạy cảm khác có thể bị đánh cắp nếu kẻ tấn công có quyền
truy cập vào mạng.
+ Sửa đổi dữ liệu: Kẻ tấn công có thể thay đổi dữ liệu được truyền đi, dẫn đến
các hành động không mong muốn hoặc sai lệch thông tin.
+ Nghe lén giao tiếp: Kẻ tấn công có thể theo dõi toàn bộ nội dung giao tiếp
giữa các ứng dụng sử dụng kênh TCP.
2.2. Các phương pháp bảo mật
2.2.1. Xác thực người dùng
Trong lập trình Socket, việc xác thực người dùng là vô cùng quan trọng, nó
giúp đảm bảo chỉ những người dùng được ủy quyền mới có quyền truy cập tài
nguyên mạng. Qua đó, xác thực người dùng giúp đảm bảo tính toàn vẹn, tính
bảo mật và độ tin cậy của hệ thống.
Quá trình xác thực thường diễn ra như sau:
+ Người dùng kết nối đến máy chủ thông qua socket.
+ Máy chủ yêu cầu người dùng cung cấp thông tin xác thực. (VD: user và
password)
+ Người dùng gửi thông tin xác thực đến máy chủ.
+ Máy chủ kiểm tra thông tin xác thực và quyết định liệu người dùng có được
phép truy cập hay không.
+ Nếu thông tin xác thực là hợp lệ, máy chủ sẽ cho phép kết nối tiếp tục và
cung cấp các dịch vụ được yêu cầu.
Sau đây là một số phương thức xác thực người dùng trong lập trình Socket:
+ Xác thực mật khẩu (Password Authentication): Trong phương pháp này,
người dùng cần cung cấp một cặp tên đăng nhập và mật khẩu để đăng nhập
vào hệ thống. Mật khẩu thường được bảo mật bằng cách sử dụng hàm băm.
Sau đó, máy chủ sẽ kiểm tra xem cặp username và password này có hợp lệ
hay không.
+ Xác thực mã thông báo (Token-based Authentication): Người dùng đăng
nhập bằng cách cung cấp một mã thông báo (token) duy nhất. Mã thông báo
này có thể được tạo ra bằng nhiều cách khác nhau và thường có thời hạn.
(VD: JWT)
+ Xác thực chứng chỉ (Certificate Authentication): Sử dụng chứng chỉ
SSL/TLS để xác thực. Mỗi bên đều có một bộ chứng chỉ, máy chủ sẽ xác
minh xem chứng chỉ của người dùng có được ký bởi một tổ chức uy tín hay
không. Trong python, có thể sử dụng module ssl để thực hiện xác thực theo
cách này.
2.2.2. Giao thức SSL/TLS
Giao thức SSL/TLS là giao thức ở lớp Transport có tầm quan trọng cao nhất
đối với sự bảo mật của các trình ứng dụng trên Web.
SSL: Viết tắt của Security Sockets Layer, SSL là một giao thức mật mã giúp
truyền thông an toàn qua mạng máy tính. SSL được phát triển bởi Netscape,
phiên bản đầu tiên được công bố là SSL 2.0 (năm 1995), sau đó là phiên bản 3.0
(năm 1996). Tuy nhiên do có nhiều lỗ hổng nên không được phát triển nữa và
ngày nay SSL cũng ít được sử dụng hơn TLS.
TLS: Viết tắt của Transport Layer Security, TLS cũng giống như SSL là một
giao thức mật mã giúp truyền thông an toàn. TLS 1.0 được IETF phát triển năm
1999, các phiên bản tiếp theo là TLS 1.1, 1.2, 1.3.
Tóm lại, TLS là phiên bản tiếp theo và cải tiến của SSL, được phát triển để
cung cấp một môi trường bảo mật mạnh mẽ hơn cho việc truyền dữ liệu qua
mạng. Trong khi SSL vẫn tồn tại và được sử dụng trong một số trường hợp, TLS
là lựa chọn ưu tiên cho các ứng dụng và dịch vụ mới.
Trong giao thức SSL/TLS có 4 giao thức con với những chức năng cụ thể:
+ SSL Record: Giao thức này được sử dụng để chia nhỏ dữ liệu thành các
gói tin nhỏ hơn, mã hóa dữ liệu và thêm các thông tin bảo mật như mã băm, chữ
ký số, và khóa phiên trước khi gửi đi.
+ SSL Handshake: Giao thức Handshake được sử dụng để thiết lập kết nối an
toàn giữa máy khách và máy chủ, xác thực các bên và thỏa thuận các thông
tin cần thiết cho việc thiết lập kết nối bảo mật.
+ SSL Change Cipher Spec: Giao thức này được sử dụng để thông báo cho đối
phương biết rằng các thông tin được trao đổi từ bây giờ sẽ được mã hóa bằng
các thuật toán đã thỏa thuận trong giao thức Handshake.
+ SSL Alert: Giao thức này được sử dụng để thông báo về các sự kiện quan
trọng và cảnh báo liên quan đến quá trình trao đổi dữ liệu bảo mật như như
lỗi xác thực, lỗi băm, hoặc lỗi mã hóa,…
Trong 4 giao thức trên, mỗi giao thức đều có tầm quan trọng riêng, nhưng đặc
biệt phải kể đến giao thức SSL Handshake, đây được coi như là cốt lõi của giao
thức SSL.
*Giao thức SSL Handshake
Giao tiếp qua SSL luôn bắt đầu bằng SSL Handshake. Handshake SSL là một
mật mã bất đối xứng cho phép trình duyệt xác minh máy chủ web, lấy khóa
công khai và thiết lập kết nối an toàn trước khi bắt đầu truyền dữ liệu thực tế.
Hình sau minh họa các bước liên quan đến quá trình SSL Handshake:
Dĩ nhiên, khi truy cập trang web không có chứng chỉ SSL/TLS, việc cung
cấp thông tin cá nhân username và password trên trang này có nguy cơ bị người
khác bắt gói tin và đọc được nội dung bên trong, từ đó dẫn đến việc lộ các thông
tin nhạy cảm. Nhưng khi truy cập vào https://actvn.edu.vn/ thì người dùng có
thể yên tâm hơn do https là sự kết hợp của giao thức HTTP và giao thức
SSL/TLS, tức là trang web này đã có chứng chỉ SSL/TLS.
Từ những điều trên có thể thấy rằng chứng chỉ SSL/TLS có nhiều tác dụng
quan trọng. Đầu tiên, nó giúp xác thực giữa Client và Server. Ngoài ra nó còn
giúp đảm bảo tính toàn vẹn của dữ liệu bằng cách mã hóa dữ liệu nhằm đảm bảo
tính bí mật, cũng như nén dữ liệu.
.
CHƯƠNG III – THỰC NGHIỆM
3.1. Tổng Quan Mô Hình Xây Dựng Bài Toán
a) Bài toán xác thực người dùng:
Sử dụng ngôn ngữ Python để xây dựng một ứng dụng giao tiếp đơn giản
giữa thực thể là Client và Server. Trước khi muốn giao tiếp, Client phải đăng
nhập thành công bằng tên tài khoản và mật khẩu được lưu trữ ở dạng băm trong
cơ sở dữ liệu. Nếu chưa có tài khoản, Client có thể lựa chọn “Đăng ký” để tạo
tài khoản mới. Tài khoản đó bao gồm tên tài khoản và mật khẩu ở dạng băm,
nhằm tăng tính an toàn đối với các cuộc tấn công vào cơ sở dữ liệu.
b) Bài toán tăng cường tính bảo mật trong quá trình giao tiếp Client – Server :
Sử dụng module socket và ssl để xây dựng giao thức SSL/TLS trong giao
tiếp Client – Server. Client trước khi kết nối sẽ thực hiện xác thực Server qua
chứng chỉ SSL được gửi từ Server. Nếu xác thực thành công, Client sẽ thực hiện
kết nối và bắt đầu quá trình truyền/nhận thông điệp với Server.
3.2. Tiến Hành
3.2.1. Xác thực người dùng trong giao tiếp Client-Server:
*)Server:
Đầu tiên ta cần import vào các module cần thiết:
-Trong đó module sqlite3 là một thư viện cung cấp chức năng truy cập và
thao tác với cơ sở dữ liệu Sqlite
-Module hashlib là một thư viện cung cấp các hàm băm mật mã cho dữ liệu
-Module socket đã được giải thích.
Sau đó, tạo ra một socket, gán địa chỉ và port cho socket đó, rồi chuyển sang
chế độ lắng nghe bằng hàm listen(). Chấp nhận kết nối đến:
Xây dựng hàm có chức năng “Đăng ký”. Khi hàm này được gọi, Client có thể
đăng ký tài khoản mới với username và mật khẩu:
Từ dòng 18 đến 24, sau khi nhập mật khẩu, Client sẽ phải xác nhận lại mật
khẩu, nếu mật khẩu xác nhận không trùng khớp với mật khẩu đặt ban đầu, người
dùng phải nhập lại.
Từ dòng 25 đến 30, khi mật khẩu đã được xác nhận, nó sẽ được băm và thêm
vào cơ sở dữ liệu. Khi quá trình hoàn tất, một thông điệp báo thành công sẽ
được gửi tới Client.
Xây dựng hàm có chức năng “Đăng nhập”. Thông tin username và mật khẩu
được nhận từ Client:
Từ dòng 40 đến 42, mật khẩu sau khi nhận sẽ được băm, sau đó truy vấn trong
cơ sở dữ liệu.
Từ dòng 44 đến 48, kết quả phép truy vấn sẽ được gửi bằng một thông điệp tới
Client.
Cuối cùng, gửi thông điệp gồm 2 lựa chọn đến Client:
Nếu phản hồi của Client là ‘1’ (Log in), kênh chat được tạo ra để Client và
Server giao tiếp tới khi thông điệp Server nhận được là ‘exit’, kênh chat sẽ kết
thúc:
Nếu phản hồi là ‘2’ (Sign up), hàm có chức năng “Đăng ký” được gọi:
*)Client:
Import module socket, sau đó tạo socket và kết nối đến địa chỉ của Server:
Bắt đầu nhận thông điệp từ Server và gửi phản hồi, nếu lựa chọn là ‘1’ (Log
in),người dùng có thể nhập username và mật khẩu, nếu đăng nhập thành công,
kênh chat sẽ được tạo ra
Nếu lựa chọn là ‘2’ (Sign up), người dùng sẽ nhập username mật khẩu mới cho
đến khi hợp lệ và nhận được thông báo ‘Create account successful’
*)Kết Quả:
Client Server
Lúc này, thông tin tài khoản của Client đã được lưu trên cơ sở dữ liệu với mật
khẩu đã được mã hóa theo hàm băm:
- Lưu lại username cũ nếu có trước khi thực hiện set username
- Hiện ra form yêu cầu nhập username:
+/ Lưu username vào file config
+/ Nếu đối tượng là client và đã kết nối thì gửi đi username cũ của user đó
* Set Server IP/Port
- Mở một form để điền thông tin về server, mục đích tuỳ thuộc vào việc đối
tượng là server hay client
+/ Đối với server việc set ip và port để mở kết nối
+/ Đối với client thì đây là bước thiết lập thông tin về server muốn kết nối
- Thông tin về ip và port cũng sẽ được lưu lại để thuận tiện cho những lần kết
nối sau
* Set Password
- Vẫn sẽ tương tự với các thiết lập trên, điểm khác biệt là khi nhập sẽ ẩn các
kí tự nhập vào bằng các dấu *, cũng như không lưu mật khẩu vào file config
để đảm bảo không bị lộ mật khẩu khi bị tấn công
* Start server
- Tạo một context SSL/TLS mới dùng để yêu cầu xác thực từ client
- Load file cert và key được chỉ định
- Chuyển socket thành SSL/TLS ở chế độ server side
+/ Tạo một vòng lặp chỉ kết thúc khi đóng kết nối qua biến is_connected
+/ Chờ và chấp nhận một kết nối từ client. Nó trả về một list/tuple chứa 2
giá trị, gán chúng vào conn, addr (conn là socket đại diện cho kết nối thiết
lập với server, addr chứa địa chỉ IP và port của client đã kết nối
+/ Gửi thông báo lên bảng chat là có một client đã kết nối tới server
+/ Tạo một luồng mới để chạy hàm nhận tin nhắn (sẽ được đề cập sau) với
2 tham số là conn và addr
+/ Thiết lập daemon thành True, để khi server đóng thì các luồng con đang
chạy cũng sẽ dừng lại
+/ Bắt đầu chạy luồng
+/ Nếu gặp lỗi sẽ trả về thông báo lỗi và dừng việc chấp nhận kết nối
- Bắt đầu chạy luồng chấp nhận kết nối
- Thông báo rằng Server đã chạy
- Cập nhật tên server vào danh sách người dùng
- Nếu gặp lỗi sẽ trả về thông báo lỗi không thể khởi chạy server
* Stop server
- Khởi tạo biến đại diện cho đường dẫn tới cert và key
- Lấy thông tin về thư mục hiện tại (là thư mục chứa script
- Tạo đường dẫn tới 2 file cert và key, gán cho 2 biến đường dẫn khởi tạo ban
đầu
- Tạo một khoá bí mật với các tham số được chỉ định
+/ Số mũ public (mã hoá công khai)
+/ Kích thước khoá
+/ Sử dụng backend mặc định để tạo key
- Tạo thông tin chủ thể (subject) và đơn vị cấp phát (issuer) cho chứng chỉ
như quốc gia, tình thành, tổ chức,…
- Thiết lập một đối tượng cert (chứng chỉ)
+/ subject_name: Thiết lập thông tin chủ thể của cert
+/ issuer_name: Thiết lập đơn vị cấp phát cert
+/ public_key: Thiết lập public key cho cert
+/ serial_number: Thiết lập số serial (ngẫu nhiên)
- Mở file và ghi nội dung cho file cert bằng định dạng PEM
- Trả về thông báo lỗi tạo khoá thất bại khi gặp lỗi
* Connect Client
- Tạo một context SSL/TLS mới, sử dụng các thiết lập mặc định
- check_hostname = FALSE: Bỏ qua kiểm tra tên miền server (chỉ dùng trong
thử nghiệm)
- verify_mode = ssl.CERT_NONE: Bỏ qua việc xác thực chứng chỉ SSL của
server (cũng chỉ dùng trong thử nghiệm)
- Đây là một hàm để gửi các cập nhật và danh sách user cho các client đang
kết nối
- Hàm này tạo một biến lưu user list và một đoạn tin nhắn cụ thể, những từ
khoá trong đoạn tin nhắn sẽ dùng để xác định đây là một tin nhắn cập nhật
- Mã hoá tin nhắn này và gửi đi
* Gửi tin nhắn
- Tuỳ vào các hành động cụ thể thì server sẽ gửi đi các tin nhắn định dạng
khác nhau (các thông báo về username mới, một client đã disconnect hay là
một user đổi tên), nếu chỉ là đoạn chat thông thường thì sẽ gửi bằng cách
thông thường
- Nếu là client thì sẽ gửi tin nhắn được mã hoá tới server, còn ngược lại thì
server sẽ gửi tin nhắn tới toàn bộ client
- Trường hợp tin nhắn không thuộc 3 tin nhắn có định dạng để thực hiện các
chức năng thì ra in lên bảng chat, còn không thì sẽ chỉ gửi chứ không in ra
* Nhận tin nhắn
- Trước khi nhận tin, chương trình sẽ kiểm tra xem Client có đang kết nối hay
không bằng hàm kiểm tra socket và kiểm tra data nhận được
- Về hàm kiểm tra socket thì chương trình sẽ gửi đi một đoạn byte rỗng tới kết
nối được chỉ định, nếu gặp lỗi sẽ trả về False và ngược lại
- Sau khi kiểm tra kết nối (giải mã và mã hoá sẽ đề cập sau) thì sẽ đến công
đoạn kiểm tra các từ khoá trong tin nhắn để xác định tin nhắn này thuộc dạng
nào. Nếu chứa “ENCRYPTEDUSERLIST:” thì chương trình sẽ tạo user list
dựa trên tin nhắn gửi tới và cập nhật lại user list hiện tại
- Tạo khoá dẫn xuất sử dụng hàm tạo khoá dựa trên mật khẩu (PBKDF2), kết
hợp hàm băm sha256 (trước đó password được encode sang dạng byte) với
100000 lần lặp
- Salt được dùng để nối vào mật khẩu nhằm chống các cuộc tấn công
Dictionary hay Rainbow Attack
- Hàm trả về một khoá có độ dài được chỉ định bởi KEY_SIZE
- Trước hết hàm mã hoá này sẽ kiểm tra tin nhắn có ở dạng byte không, nếu
không thì sẽ chuyển nó về dạng byte
- Thiết lập mã hoá: Khởi tạo đối tượng AES sử sụng key và chế độ EAX
- Mã hoá tin nhắn thành bản mã cũng như tạo một tag (mã xác thực)
- Trả về 3 giá trị là nonce (một số ngẫu nhiên sử dụng một lần cho mã hoá
nhằm ngăn chặn Replay Attack, bản mã và tag. Dưới đây sẽ nói chi tiết về mã
hoá tin nhắn sử dụng 3 thành phần này
- salt sẽ được tạo ngẫu nhiên và có kích thước được chỉ định
- key được tạo bằng hàm dẫn xuất khoá đã đề cập trước đó
- Mã hoá tin nhắn sử dụng key -> gấn cho encrypted_data
- encrypted_data khi đó là một mảng chứa 3 giá trị nonce, ciphertext, tag, tách
chúng thành các xâu để nối với nhau cũng nhau nối với salt -> gán vào
encrypted_message
- Cuối cùng thì dùng base64 để mã hoá encrypted message -> gán vào
encrypted_messagem, đây sẽ là bản mã cuối cùng để truyền đi
* Giải mã tin nhắn
- Tham số đầu vào của hàm giải mã có encrypted_data – là mảng gòm 3 giá
trị nonce, ciphertext, tag
- Khởi tạo đối tượng AES sử dụng key, nonce lấy từ encrypted_data, chế độ
EAX
- Bản rõ sẽ được lấy từ hàm decrypt_and_verify bằng cách cung cấp bản mã
và tag, cuối cùng decode để chuyển từ dạng byte sang dạng thường
b) Thực nghiệm trên giao diện UI
* Phía server
- Chương trình sẽ không chia thành 2 file để phân biệt client và server như thông
thường mà kết hợp thành một ứng dụng duy nhất
- Giao diện chỉnh (gồm thanh menu, khung hiển thị chat, khung nhập tin nhắn,
khung hiển thị danh sách user, nút gửi tin nhắn)
- Phía server: sử dụng menu Settings để thiết lập Server name, Server IP/Port,
Password chung để kết nối
- Start Server: Khởi chạy server đồng thời tạo cert/key tại chính thư mục cuẩ
chương trình, server sẽ tự động lấy file cert và key ở thư mục ứng dụng để bọc
socket bằng một lớp bảo mật SSL/TLS. Nếu khởi chạy thành động. Lưu ý: Nếu
chưa có cert thì khi khởi chạy sẽ có thông báo lỗi không tìm được file cert/key
* Phía client
- Thực hiện các bước thiết lập thông tin tương tự phía client, đảm bảo các thông
tin quan trọng như IP/Port và Password được thiết lập tương ứng với server để
kết nối được triển khai
- Client – Connect: Thực hiện gửi yêu cầu kết nối tới server, server sẽ gửi cert
cho client. Thiết lập của client là không xác minh tính hợp lệ của chứng chỉ hay
kiểm tra tên miền nhưng trên thực tế thì việc thiết lập như vậy có thể dẫn tới
những rủi ro bảo mật (như Man-in-the-middle Attack). Ngoài lớp mã hoá được
tạo bởi giao thức SSL/TLS ra ứng dụng còn bổ sung thêm thuật toán mã hoá đã
được đề cập ở phần trước để tăng tính bảo mật cho tin nhắn
- Đây là gói tin biểu thi tương tác giữa client và server khi Client yêu cầu kết
nối:
+/ Client Hello: Client gửi lời chào tới server, gói tin này chứa các thông tin
như phiên bản TLS và bộ mã hoá mà client hỗ trợ, một số ngẫu nhiên và
extension (phần mở rộng
+/ Server Hello: Server chào lại Client. Gói tin chứa phiên bản TLS và bộ mã
hoá mà server sẽ chọn, số ngâu nhiên, extension và chứng chỉ (cert) của
server
+/ Change Cipher Spec: Thông báo cho server/client sắp sử dụng bộ mã hoá
cipher suite đã thoả thuận để mã hoá và giải mã tin nhắn
+/ Application Data: Client/Server gửi tin nhắn Application Data tới đối
phương, chứa tin nhắn/dữ liệu được mã hoá cần gửi đi
- Có thể ngắt kết nối tới server hay thậm chí dừng server bằng các tuỳ chọn
trong menu, tránh việc chỉ tắt bằng nút close của cửa sổ bởi đôi khi sẽ gặp lỗi
TÀI LIỆU THAM KHẢO
[1] https://vnpro.vn/thu-vien/tong-quan-ve-giao-thuc-ssl-tls-4024.html
[2] https://realpython.com/python-sockets/
[3] https://www.freecodecamp.org/news/socket-programming-in-python/
[4] https://www.ibm.com/docs/en/i/7.4?topic=network-client-security-in-tcpip
[5] https://snyk.io/blog/implementing-tls-ssl-python/
[6] https://github.com/vuongwyen/chat-app-using-SSL-TLS