SSL and TLS

ইন্টারনেটে ডাটা আদান-প্রদান সুরক্ষিত রাখার মূলভিত্তি হলো SSL/TLS (Secure Sockets Layer / Transport Layer Security) প্রোটোকল। তুমি যখন কোনো HTTPS ওয়েবসাইটে প্রবেশ করো, তখন তোমার ব্রাউজার এবং সার্ভার একে অপরের সাথে নিরাপদে যোগাযোগ স্থাপনের জন্য যে প্রক্রিয়াটি সম্পন্ন করে, তাকেই SSL/TLS Handshake বলা হয়।

এই প্রক্রিয়ার মাধ্যমে ক্লায়েন্ট এবং সার্ভার একে অপরের পরিচয় যাচাই করে এবং ডাটা এনক্রিপ্ট করার জন্য একটি গোপন 'সেশন কি (Session Key)' তৈরি করে। এটি নিশ্চিত করে যে ডাটা এনক্রিপ্টেড থাকবে এবং কেউ Man-in-the-Middle (MITM) অ্যাটাক করতে পারবে না।

SSL/TLS Handshake কীভাবে কাজ করে?

এই হ্যান্ডশেক প্রক্রিয়াটি মূলত কয়েকটি ধাপে সম্পন্ন হয়। এখানে ক্লাসিক্যাল TLS 1.2 এর মেকানিজমটি তুলে ধরা হলো:

১. Client Hello ও Server Hello (প্রাথমিক যোগাযোগ)

প্রথমেই, ক্লায়েন্ট (তোমার ব্রাউজার) সার্ভারের সাথে একটি সংযোগ স্থাপনের চেষ্টা করে।

  • Client Hello: ক্লায়েন্ট সার্ভারকে একটি ম্যাসেজ পাঠায়, যেখানে ক্লায়েন্টের সমর্থিত TLS ভার্সন (যেমন: TLS 1.2, TLS 1.3), সমর্থিত Cipher Suites (যেমন: AES, RSA, ECDHE) এবং একটি Random Value (পরবর্তীতে Session Key তৈরির জন্য) থাকে।

  • Server Hello: সার্ভার এই ম্যাসেজ পেয়ে তার সমর্থিত অপশনগুলো থেকে একটি TLS ভার্সন ও Cipher Suite নির্বাচন করে ক্লায়েন্টকে জানায় এবং নিজের একটি Random Value পাঠায়।

২. Certificate Exchange ও Authentication (পরিচয় যাচাই)

সার্ভার যে আসল এবং বিশ্বস্ত, তা প্রমাণ করার জন্য সার্ভার তার SSL Certificate ক্লায়েন্টের কাছে পাঠায়। এই সার্টিফিকেটে সার্ভারের Public Key, ডোমেইনের নাম এবং Certificate Authority (CA) এর ডিজিটাল সিগনেচার থাকে। ক্লায়েন্ট (ব্রাউজার) তখন যাচাই করে দেখে সার্টিফিকেটটি কোনো বিশ্বস্ত CA দ্বারা ইস্যু করা কি না এবং এর মেয়াদ আছে কি না।

বাস্তব উদাহরণ: তুমি কোনো অফিসে প্রবেশ করতে চাইলে গার্ডকে যেমন তোমার আইডি কার্ড দেখাও, এটিও ঠিক সেরকম। এখানে ব্রাউজার হলো গার্ড, আর সার্ভারের SSL Certificate হলো তার আইডি কার্ড।

৩. Session Key Generation (গোপন চাবি তৈরি)

SSL/TLS হ্যান্ডশেকের সবচেয়ে আকর্ষণীয় দিক হলো এটি Asymmetric এবং Symmetric উভয় এনক্রিপশনের সুবিধা ব্যবহার করে।

  • সার্ভারের পাঠানো Public Key ব্যবহার করে ক্লায়েন্ট একটি গোপন কোড (Premaster Secret) এনক্রিপ্ট করে সার্ভারকে পাঠায়।

  • সার্ভার তার নিজের কাছে সযত্নে রাখা Private Key দিয়ে সেটি ডিক্রিপ্ট করে।

  • এখন ক্লায়েন্ট এবং সার্ভার উভয়ের কাছেই Client Random, Server Random এবং Premaster Secret থাকে। এগুলো ব্যবহার করে তারা স্বাধীনভাবে একটি অভিন্ন Session Key (Symmetric Key) তৈরি করে নেয়।

৪. Secure Communication (নিরাপদ যোগাযোগ শুরু)

Session Key তৈরি হয়ে যাওয়ার পর Asymmetric এনক্রিপশনের কাজ শেষ। এরপর থেকে ক্লায়েন্ট এবং সার্ভারের মধ্যে যাবতীয় ডাটা আদান-প্রদান এই Session Key (Symmetric Encryption) ব্যবহার করে অত্যন্ত দ্রুতগতিতে এনক্রিপ্ট ও ডিক্রিপ্ট করা হয়।

কোড ইমপ্লিমেন্টেশন (Python)

পাইথনে ssl মডিউল ব্যবহার করে ক্লায়েন্ট এবং সার্ভারের মধ্যে কীভাবে SSL সংযোগ হয় তার একটি উদাহরণ নিচে দেওয়া হলো।

Python SSL Server:

import ssl
import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 8443))
server_socket.listen(5)

# Configuring SSL context for the server
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile="server.crt", keyfile="server.key")

print("SSL Server is running on port 8443...")

while True:
    conn, addr = server_socket.accept()
    secure_conn = context.wrap_socket(conn, server_side=True)
    
    print(f"Connection established with {addr}")
    secure_conn.send(b"Hello, Secure Python World!")
    secure_conn.close()

Python SSL Client:

import ssl
import socket

# Creating default context (verifies certificates by default)
context = ssl.create_default_context()

with socket.create_connection(('localhost', 8443)) as client_socket:
    with context.wrap_socket(client_socket, server_hostname="localhost") as secure_client:
        print("Secure connection established!")
        print("Server says:", secure_client.recv(1024).decode())

কোড ইমপ্লিমেন্টেশন (Java)

জাভাতে SSLSocket এবং SSLServerSocket ব্যবহার করে সহজেই সিকিউর কমিউনিকেশন করা যায়।

Java SSL Server:

import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLServerSocket;
import java.net.Socket;
import java.io.PrintWriter;

public class SSLServerDemo {
    public static void main(String[] args) {
        try {
            // Note: KeyStore must be configured via JVM arguments or code
            // System.setProperty("javax.net.ssl.keyStore", "server.jks");
            // System.setProperty("javax.net.ssl.keyStorePassword", "password");

            SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
            SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(8443);
            
            System.out.println("SSL Server is running on port 8443...");

            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("Connection established with " + socket.getInetAddress());
                
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                out.println("Hello, Secure Java World!");
                socket.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Java SSL Client:

import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.SSLSocket;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class SSLClientDemo {
    public static void main(String[] args) {
        try {
            // Note: TrustStore must be configured to trust the self-signed cert
            // System.setProperty("javax.net.ssl.trustStore", "client.jks");
            // System.setProperty("javax.net.ssl.trustStorePassword", "password");

            SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
            SSLSocket socket = (SSLSocket) factory.createSocket("localhost", 8443);
            
            // Explicitly start the handshake
            socket.startHandshake();
            System.out.println("Secure connection established!");

            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println("Server says: " + in.readLine());
            
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

কেন SSL/TLS Handshake এত গুরুত্বপূর্ণ?

  • Confidentiality (ডাটা এনক্রিপশন): সেশন কি ব্যবহার করে আদান-প্রদান করা সমস্ত ডেটা এনক্রিপ্ট করা হয়, ফলে নেটওয়ার্কে আড়িপেতে কেউ ডেটা পড়তে পারে না।

  • Authentication (সার্ভারের পরিচয় যাচাই): ফিশিং ওয়েবসাইট থেকে ইউজারকে রক্ষা করে। ব্রাউজার নিশ্চিত হয় যে সে সঠিক সার্ভারের সাথেই যোগাযোগ করছে।

  • Integrity (ডেটার অখণ্ডতা): ট্রানজিটে থাকা অবস্থায় কেউ ডেটার কোনো পরিবর্তন (Tampering) করলে তা সাথে সাথে ধরা পড়ে যায়।

বর্তমানে TLS 1.3 ব্যাপকভাবে ব্যবহৃত হচ্ছে। এটি TLS 1.2 এর চেয়ে অনেক বেশি ফাস্ট, কারণ এটি হ্যান্ডশেক প্রসেসকে ছোট করে এনেছে (1-RTT - One Round Trip Time), যা সিস্টেমের পারফরম্যান্স ও ল্যাটেন্সি উল্লেখযোগ্যভাবে উন্নত করে।