Course-এর সূচি

2.8

TLS 1.2 বনাম TLS 1.3 Handshake, আর Mutual TLS

দুটো handshake-এর প্রতিটা message, forward secrecy, 0-RTT, আর service-গুলো কীভাবে একে অপরের কাছে নিজের পরিচয় প্রমাণ করে।

45 মিনিট পড়া + Animation

টিপস: ডটেড-আন্ডারলাইন করা যেকোনো শব্দে ট্যাপ বা Hover করলে তার অর্থ দেখবে।

এই Lesson শেষে তুমি পারবে

  • TLS 1.2 Handshake একটা একটা Message ধরে (ClientHello থেকে Finished) বোঝাতে, আর প্রতিটা Message কী প্রমাণ করে তা বলতে।
  • RSA Key Transport কেন বাদ গেল আর Forward Secrecy কীসের হাত থেকে বাঁচায়, সেটা ব্যাখ্যা করতে।
  • TLS 1.3 Handshake বোঝাতে: প্রথম Message-এই Key Share, HKDF Key Schedule, কী কী Encrypt হয়, HelloRetryRequest, পাঁচটা Cipher Suite আর কোন কোন জিনিস বাদ পড়েছে।
  • TCP + TLS 1.2, TCP + TLS 1.3, QUIC, Resumption আর 0-RTT-এ কত Round Trip লাগে গুনতে, আর 0-RTT কেন শুধু Idempotent Request-এর জন্য নিরাপদ তা বলতে।
  • SNI, Encrypted Client Hello, ALPN আর Post-quantum Hybrid Key Share বোঝাতে, আর লক্ষণ দেখে Handshake-এর চেনা ব্যর্থতাগুলো ধরতে।
  • Load Balancer-এ TLS Termination, Re-encryption আর Passthrough-এর মধ্যে বাছতে।
  • Mutual TLS শুরু থেকে শেষ বোঝাতে: CertificateRequest, Client Certificate, SPIFFE পরিচয়, স্বল্পমেয়াদি Certificate আর Rotation, Sidecar বনাম Ambient Mesh, আর কখন API Key বা JWT-র বদলে mTLS নেবে।

#এই Lesson কোথায় বসে

Lesson ১.৯-এ তুমি পুরো ছবিটা দেখেছ: TLS গোপনীয়তা, অখণ্ডতা আর পরিচয় প্রমাণ দেয়; TLS 1.3-এ এক Round Trip লাগে; Browser Certificate-এর নাম, তারিখ আর Chain যাচাই করে; 0-RTT Replay হতে পারে; HSTS HTTPS-এ বাধ্য করে। Lesson ২.৭-এ শিখেছ ইট-পাথরগুলো: Symmetric আর Asymmetric Key, ECDHE, Signature, Certificate, CA আর Chain of Trust। Lesson ১.১২-এ Zero Trust-এর অংশ হিসেবে mTLS-এর সাথে পরিচয় হয়েছে।

এবার এই টুকরোগুলো জোড়া লাগিয়ে Handshake-এর ভেতরটা খুলব। TLS Handshake হলো সেই প্রক্রিয়া, যেখানে Client আর Server কোন Cryptographic Algorithm চালাবে তা ঠিক করে, পরিচয় যাচাই করে, আর Encryption-এর জন্য একটা নিরাপদ Symmetric Session Key বানায়। যে Version-ই হোক, প্রতিটা Handshake-কে এই চারটা কাজ করতেই হয়:

লক্ষ্যকেন দরকারTLS 1.2 কী দিয়ে করেTLS 1.3 কী দিয়ে করে
Version আর Algorithm-এ একমত হওয়াদুই পাশকে একই Cipher-এ কথা বলতে হবেClientHello-র তালিকা → ServerHello-র পছন্দএকই, সাথে supported_versions
এমন Key-তে একমত হওয়া যা আর কেউ জানে নাসব Data এগুলো দিয়েই Encrypt হবেServerKeyExchange + ClientKeyExchange (ECDHE)দুই Hello-তেই key_share
Server-এর পরিচয় প্রমাণ (চাইলে Client-এরও)নইলে হয়তো আক্রমণকারীর সাথেই কথা বলছCertificate + ServerKeyExchange-এর SignatureCertificate + CertificateVerify
প্রমাণ করা যে কেউ Handshake-এ হাত দেয়নিআক্রমণকারী Hello থেকে শক্ত Option মুছে দিতে পারতFinished (সব Message-এর ওপর Key দেওয়া Hash)Finished, আর প্রতিটা Key Transcript-এর সাথে বাঁধা

দুই Version একই লক্ষ্যে পৌঁছায়; TLS 1.3 শুধু এক Round Trip আগে পৌঁছায়, আর পথে অনেক বেশি কিছু লুকিয়ে রাখে।

#TLS 1.2, একটা একটা Message ধরে

TLS 1.2-এ (RFC 5246, ২০০৮) TCP-র পরে Application Data চলার আগে দুটো Round Trip লাগে। নোটে এটা চারটা তীর দিয়ে আঁকা; এখানে আসল সব Message দেখো।

TLS 1.2 Handshake, একটা একটা Message ধরে

TCP আগেই চালু। মাঝের Recorder প্রতিটা Byte কপি করে রাখে, একদিন Decrypt করার আশায়।

পরিস্থিতি

স্বাভাবিক TLS 1.2 Handshake: অস্থায়ী (Ephemeral) Elliptic-curve Key Exchange আর RSA Certificate (TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)।

Client192.0.2.10
Recorderপথের মাঝে
shop.example.com198.51.100.20:443
ClientHello
ধাপ 1 / 11
1

Client পাঠায় তার সবচেয়ে উঁচু Version (1.2), ৩২ Byte-এর Client Random, পছন্দের ক্রমে Cipher Suite-এর তালিকা, আর কিছু Extension: SNI (shop.example.com), ALPN (h2, http/1.1), কোন কোন Group চলে (x25519, P-256) আর কোন Signature Algorithm চলে।

  1. ১. ClientHello (Client → Server)

    Client পাঠায় তার সবচেয়ে উঁচু Version, ৩২ Byte-এর একটা Client Random, পছন্দের ক্রমে তার Cipher Suite-গুলো, আর কিছু Extension: SNI (Hostname), ALPN (h2, http/1.1), কোন কোন Elliptic-curve Group সে চালায় আর কোন Signature Algorithm সে মানে।

  2. ২. ServerHello, Certificate, ServerKeyExchange, ServerHelloDone (Server → Client)

    চারটা Message মিলে একটা চালান। ServerHello একটা Cipher Suite বেছে নেয়, সাথে ৩২ Byte-এর Server Random। Certificate হলো Chain, আগে Leaf, আর এটা যায় Encrypt ছাড়াই। ServerKeyExchange-এ থাকে Server-এর একদম নতুন, অস্থায়ী ECDHE Public Key, দুটো Random-সহ Certificate-এর Private Key দিয়ে Sign করা; এতে প্রমাণ হয় Key-টা Certificate-এর মালিকেরই, আর এই Session-এরই। ServerHelloDone বলে “এবার তোমার চাল”। Server এখনো Finished পাঠাতে পারে না: Client-এর Key Share সে এখনো দেখেনি।

  3. ৩. Client যাচাই করে, হিসাব করে

    Client Chain, Hostname আর তারিখ যাচাই করে (Lesson ২.৭), নিজের একটা অস্থায়ী Key Pair বানায়, আর দুজনের ECDHE মান হিসাব করে: এটাই Pre-master Secret। একটা Pseudorandom Function (PRF) এটাকে দুটো Random-এর সাথে মিশিয়ে ৪৮ Byte-এর Master Secret বানায়, তারপর সেখান থেকে একটা Key Block বের হয়: প্রতিটা দিকের জন্য আলাদা Encryption Key (আর Initialisation Vector)।

  4. ৪. ClientKeyExchange, ChangeCipherSpec, Finished (Client → Server)

    ClientKeyExchange-এ থাকে Client-এর অস্থায়ী Public Key, যাতে Server-ও একই Secret হিসাব করতে পারে। ChangeCipherSpec মানে “এর পরের Record থেকে আমি Encrypt করব”। Finished হলো প্রথম Encrypt করা Message: এ পর্যন্ত সব Handshake Message-এর ওপর একটা Key দেওয়া Hash।

  5. ৫. ChangeCipherSpec, Finished (Server → Client)

    Server Client-এর Finished মিলিয়ে দেখে, তারপর নিজেরটা পাঠায়। কেউ যদি Hello বদলে দিত, ধরো শক্ত Cipher Suite-গুলো মুছে দুর্বল একটা চাপিয়ে দিত, তাহলে দুই পাশের Hash আলাদা হতো আর Handshake ব্যর্থ হতো। এবার Application Data চলে।

খরচ: TCP-র ১টার ওপর TLS-এর জন্য ২টা Round Trip। Browser False Start দিয়ে নিজের Finished-এর ঠিক পরেই প্রথম Request পাঠিয়ে দিত (ECDHE Suite-এ এক Round Trip বাঁচাত), কিন্তু Protocol-এর হিসাবে দুটোই।

#RSA Key Transport বনাম ECDHE: Forward Secrecy

TLS 1.2-এ আরও সহজ একটা Key Exchange চলত, RSA Key Transport: Client নিজেই Pre-master Secret বানায়, আর Certificate-এর ভেতরের Server-এর RSA Public Key দিয়ে Encrypt করে পাঠিয়ে দেয়। ServerKeyExchange নেই। এটা কাজ করে, বহু বছর এটাই ডিফল্ট ছিল। ওপরের Animation-এর দ্বিতীয় Scenario চালাও, সমস্যাটা দেখবে।

সবকিছু ঝুলে আছে একটাই দীর্ঘস্থায়ী Key-এর ওপর। আক্রমণকারী আজ Encrypt করা Traffic রেকর্ড করে রাখল, আর পরে কোনোদিন Private Key চুরি করল (একটা Breach, চুরি যাওয়া Backup, ২০১৪-র Heartbleed-এর মতো Memory ফাঁসের Bug, কিংবা আদালতের আদেশ)। তখন সে জমানো প্রতিটা ClientKeyExchange খুলে প্রতিটা Session-এর Secret বের করবে, আর বছরের পর বছরের Traffic পড়ে ফেলবে। ECDHE-তে প্রতিটা Handshake নতুন Key Pair বানায়, কাজ শেষে মুছে ফেলে; Certificate-এর Key শুধু Sign করে। পরে সেটা চুরি করলে আক্রমণকারী ভবিষ্যতে Server সেজে বসতে পারে, কিন্তু অতীত Decrypt করতে পারে না। এই গুণের নাম Forward Secrecy।

RSA Key Transport-এ Padding-oracle আক্রমণও হয়েছে (Bleichenbacher ১৯৯৮ সালে, ২০১৭ সালে আবার নতুন রূপে)। তাই TLS 1.3 এটা বাদ দিয়েছে: TLS 1.3-এর প্রতিটা Handshake অস্থায়ী Diffie-Hellman দিয়ে।

#TLS 1.2-এর একটা Cipher Suite পড়া

TLS 1.2-এর Suite-এর নামে একসাথে চারটা সিদ্ধান্ত গোঁজা থাকে:

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256-এর অংশমানে
ECDHEKey Exchange: অস্থায়ী Elliptic-curve Diffie-Hellman (Forward Secrecy)
RSAপরিচয় প্রমাণ: Certificate-এ RSA Key, যা ECDHE-র মানগুলো Sign করে
AES_128_GCMমূল Cipher: ১২৮ bit Key-এর AES, GCM Mode-এ; এটা AEAD, মানে Encrypt আর যাচাই একসাথে
SHA256Key বানানোর PRF-এ যে Hash চলে

এমন শত শত জোড়া Register করা ছিল, তার অনেকগুলোই দুর্বল (Export-grade, RC4, 3DES, আলাদা MAC-সহ CBC)। TLS 1.2 Server শক্ত করার বড় একটা অংশ হলো এই তালিকার বেশিরভাগটা মুছে ফেলা।

#TLS 1.3: এক Round Trip, প্রায় পুরোটাই Encrypt করা

TLS 1.3 (RFC 8446, ২০১৮) অপ্রয়োজনীয় ধাপ ফেলে দিয়ে এক Round Trip-এ (1-RTT) Handshake শেষ করে, তাতে Latency অনেক কমে। কৌশলটা প্রথম Message-এ: Server কোন Key Exchange Group নেবে, Client সেটা অনুমান করে, আর সাথে সাথেই নিজের Key Share পাঠিয়ে দেয়।

TLS 1.3 Handshake: এক Round Trip, প্রায় পুরোটাই Encrypt করা

{বন্ধনী}-র ভেতরের Message Handshake Key দিয়ে Encrypt করা; [বন্ধনী] মানে Application Data। TCP আগেই চালু।

পরিস্থিতি

Client192.0.2.10
shop.example.com198.51.100.20:443
ClientHello + key_share
ধাপ 1 / 9
1

একটা Message-এই সব: supported_versions (1.3, 1.2), তিনটা Cipher Suite, X25519MLKEM768-এর একটা key_share আর X25519-এর একটা, SNI, ALPN আর Signature Algorithm। Key Share এখনই পাঠানোই হলো সেই Round Trip বাঁচানোর কৌশল।

  1. ১. ClientHello + key_share (Client → Server)

    supported_versions-এ থাকে 1.3 আর 1.2 (পুরোনো Version Field-টা 1.2-তেই আটকে রাখা হয়েছে, যাতে আধাখেঁচড়া Middlebox আটকে না দেয়), তিন-চারটা Cipher Suite, যে Group-গুলোর ওপর বাজি ধরছে তাদের প্রত্যেকটার একটা করে key_share (আজকের Browser পাঠায় X25519MLKEM768 আর X25519), SNI, ALPN আর Signature Algorithm।

  2. ২. ServerHello + key_share (Server → Client)

    Server Version, Suite আর একটা Group বাছে, আর নিজের Share ফেরত পাঠায়। এবার দুই পাশই Shared Secret হিসাব করতে পারে। এটাই শেষ খোলা (Plaintext) Handshake Message।

  3. ৩. {EncryptedExtensions}, {CertificateRequest}, {Certificate}, {CertificateVerify}, {Finished} (Server → Client)

    একই চালান, Handshake Key দিয়ে Encrypt করা। EncryptedExtensions-এ থাকে এমন উত্তর যা খোলা রাখার দরকার নেই (যেমন বেছে নেওয়া ALPN Protocol)। CertificateRequest আসে শুধু Mutual TLS-এ। Certificate এখন Encrypt করা, তাই পথে বসে কেউ জানতে পারে না কোন Certificate গেল। CertificateVerify হলো এ পর্যন্ত পুরো Handshake-এর Hash-এর ওপর একটা Signature, যা প্রমাণ করে Private Key Server-এর কাছেই আছে, আর ঠিক এই Session-এর জন্যই। Finished হলো Transcript-এর ওপর Key দেওয়া Hash। Server চাইলে এখনই Data পাঠানো শুরু করতে পারে (“0.5-RTT” Data)।

  4. ৪. {Finished} + প্রথম Request (Client → Server)

    Client সব যাচাই করে Finished পাঠায়, আর একই চালানে প্রথম HTTP Request। Handshake-এর পরে Server পরের বার Resume করার জন্য এক বা একাধিক NewSessionTicket পাঠায়।

#Key Schedule: HKDF

TLS 1.2 Master Secret থেকে একবারেই সব Key বানাত। TLS 1.3 HKDF (HMAC-ভিত্তিক Key Derivation) দিয়ে ধাপে ধাপে একটা শিকল বানায়, আর প্রতিটা ধাপে এ পর্যন্ত Handshake Message-গুলোর একটা Hash মেশায় (এর নাম Transcript):

PSK (বা শূন্য) ──► Early Secret ──► client_early_traffic_secret          (0-RTT Data)
                        │
ECDHE Shared ──────► Handshake Secret ──► Client/Server Handshake Traffic Secret
                        │                                 (EncryptedExtensions … Finished)
                        ▼
                   Master Secret ──► Client/Server Application Traffic Secret
                                 ──► Resumption Secret  (→ পরের বারের Ticket)
                                 ──► Exporter Secret    (TLS-এর ওপর বানানো Protocol-এর জন্য)

Interview-এর জন্য তিনটা ফল মনে রাখো। Key প্রতিটা দিক আর প্রতিটা ধাপের জন্য আলাদা, তাই এক ধাপের Bug আরেক ধাপ খুলে দেয় না। প্রতিটা Key Transcript-এর ওপর নির্ভর করে বলে কোথাও হাত দিলেই সব Key বদলে যায়, আর Handshake সোজা ব্যর্থ হয়। আর লম্বা Connection নতুন Handshake ছাড়াই KeyUpdate Message দিয়ে Key সামনে এগিয়ে নিতে পারে।

#HelloRetryRequest: অনুমান ভুল হলে

Client যদি শুধু এমন Group-এর Share পাঠায় যা Server নেবে না, কিন্তু তালিকায় এমন একটা রাখে যা Server চালায়, তাহলে Server উত্তর দেয় HelloRetryRequest দিয়ে (বিশেষ একটা নির্দিষ্ট Random-ওয়ালা ServerHello): “আমাকে P-256-এর Share দাও”। Client দ্বিতীয় একটা ClientHello পাঠায়, নতুন Share ছাড়া হুবহু আগেরটার মতো, আর Handshake এগিয়ে যায়। খরচ একটা বাড়তি Round Trip। ওপরের দ্বিতীয় Scenario চালিয়ে দেখো।

এজন্যই Client দুটো Share পাঠায়, আর এজন্যই Browser প্রথমে যা অনুমান করে (আজ X25519MLKEM768 আর X25519), Server-এর সেটা চালানো উচিত। HelloRetryRequest-এ একটা Cookie-ও থাকতে পারে; Flood-এর মধ্যে Server তাহলে কোনো State না রেখে অপেক্ষা করতে পারে, যতক্ষণ না Client প্রমাণ দেয় যে সে নিজের Address-এ Packet পায়।

#TLS 1.3-এর Cipher Suite

TLS 1.3-এ Suite-এর নামে থাকে শুধু AEAD Cipher আর Hash। Key Exchange আলাদাভাবে ঠিক হয় (supported_groups, key_share), Signature-ও (signature_algorithms)। Suite আছে মাত্র পাঁচটা:

Suiteমন্তব্য
TLS_AES_128_GCM_SHA256বাধ্যতামূলক; সবচেয়ে বেশি চলে
TLS_AES_256_GCM_SHA384লম্বা Key; সরকারি নিয়মে প্রায়ই চায়
TLS_CHACHA20_POLY1305_SHA256Software-এ দ্রুত; AES Hardware ছাড়া ফোনে এটাই পছন্দ
TLS_AES_128_CCM_SHA256ছোট IoT Device-এর জন্য
TLS_AES_128_CCM_8_SHA256IoT-র জন্য ছোট Tag; “Recommended না” হিসেবে চিহ্নিত

ভুল Config করার মতো দুর্বল কিছু আর বাকি নেই: প্রতিটা Suite AEAD, প্রতিটা Key Exchange অস্থায়ী।

#TLS 1.3 কী কী বাদ দিল, আর কেন

বাদ গেছেকেন
RSA Key Transport আর Static Diffie-HellmanForward Secrecy নেই; Padding-oracle আক্রমণ
আলাদা MAC-সহ CBC Mode-এর CipherPadding-oracle আর Timing আক্রমণ (Lucky 13 আর আরও কিছু)
RC4, 3DES, Export Cipher, MD5 আর SHA-1 Signatureভাঙা বা খুব দুর্বল
CompressionResponse-এর আকার দেখে গোপন তথ্য ফাঁস হতো (CRIME আক্রমণ)
Renegotiationআক্রমণ আর জটিলতার উৎস; জায়গা নিয়েছে KeyUpdate আর Handshake-পরবর্তী পরিচয় প্রমাণ
নিজের বানানো Diffie-Hellman GroupServer দুর্বল Group বাছত; এখন শুধু নাম দেওয়া, যাচাই করা Group
ChangeCipherSpec (আসল Message হিসেবে)Key বদল এখন নিজে থেকেই বোঝা যায়; পুরোনো Middlebox-কে শান্ত রাখতে শুধু একটা নকল কপি যায়
আলাদা আলাদা ব্যবস্থা হিসেবে Session ID আর Ticketএকসাথে মিশে হয়েছে Pre-shared Key (PSK)

আরও দুটো সুরক্ষার নাম জানা দরকার। Downgrade সুরক্ষা: 1.3 জানা Server যদি শেষে 1.2-তে কথা বলে, সে নিজের Random-এর শেষ ৮ Byte-এ একটা নির্দিষ্ট চিহ্ন লিখে দেয়; 1.3 জানা Client সেটা দেখলে বোঝে আক্রমণকারী Hello থেকে 1.3 মুছে দিয়েছে, আর থেমে যায়। Middlebox-এর সাথে মানিয়ে চলা: TLS 1.3 Handshake-কে সাজিয়ে TLS 1.2-এর Session Resumption-এর মতো দেখানো হয়, কারণ মাপার মতো সংখ্যক Firewall নতুন কিছু দেখলেই ভেঙে পড়ত। TLS 1.0 আর 1.1 আনুষ্ঠানিকভাবে বাতিল (RFC 8996, ২০২১); আজ Browser-এর বেশিরভাগ Connection TLS 1.3-এ, আর TLS 1.2 টিকে আছে পুরোনো Client, IoT আর Enterprise System-এ।

নিজেকে যাচাই করোপ্রশ্ন

TLS 1.3 Handshake-এ Network-এর কোনো নজরদার সবশেষে কোন Message-টা খোলা অবস্থায় পড়তে পারে?

#Round Trip গোনা

Round Trip-এর দৌড়: দুটো Handshake পাশাপাশি

দুটো লেন একই মুহূর্তে, একই ১০০ ms-এর পথে শুরু করে। প্রতিটা ধাপ আধা Round Trip, মানে ৫০ ms। দেখো, কোন লেনের Request কখন অবশেষে বের হতে পারে।

পরিস্থিতি

লেন A: TCP + TLS 1.2। লেন B: TCP + TLS 1.3। একদম নতুন Connection, কিছুই আগে থেকে জমা নেই।

Client ATCP + TLS 1.2
Server A
Client BTCP + TLS 1.3
Server B
SYNSYN

Race-এর ঘড়ি (১০০ ms Round Trip)

লেনকত Round Trip গেলঘড়ি
A: TLS 1.200 → 50 ms
B: TLS 1.300 → 50 ms
ধাপ 1 / 8
1

দুই Client-ই TCP Handshake শুরু করে। TLS-এর আগে একটা চালু Byte Stream লাগে, তাই TLS-এর Version যা-ই হোক, এই Round Trip দুই লেনকেই দিতে হয়।

দৌড়ে যা দেখলে, নিচের টেবিলেও তা-ই। ১০০ ms Round Trip-এ একদম নতুন Connection-এর খরচ:

ব্যবস্থাRequest-এর আগে কত Round TripResponse আসে (১০০ ms RTT)২০০ ms RTT-তে
TCP + TLS 1.2৩৪০০ ms৮০০ ms
TCP + TLS 1.3২৩০০ ms৬০০ ms
TCP + TLS 1.3, HelloRetryRequest৩৪০০ ms৮০০ ms
TCP + TLS 1.3, PSK Resumption২ (Certificate নেই, সস্তা)৩০০ ms৬০০ ms
TCP + TLS 1.3, 0-RTT১ (শুধু TCP)২০০ ms৪০০ ms
QUIC (ভেতরে TLS 1.3)১২০০ ms৪০০ ms
QUIC-এ 0-RTT০১০০ ms২০০ ms
আবার ব্যবহার করা Connection০১০০ ms২০০ ms

“Response আসে”-তে Request-এর নিজের এক Round Trip ধরা আছে। DNS আর কোনো Redirect থাকলে সেটা আলাদা যোগ হবে।

আর কীসে সময় যায়। CPU এখন খুব কমই আটকায়: X25519 Key Exchange-এ লাগে কয়েক দশ Microsecond, ECDSA P-256 Signature-এও কয়েক দশ Microsecond, RSA-2048 Signature-এ মোটামুটি এক Millisecond (ব্যস্ত Server ECDSA Certificate পছন্দ করে মূলত এজন্যই)। আকার বেশি গুরুত্বপূর্ণ: ৩–৫ KB-এর Certificate Chain আর ১–২ KB-এর Post-quantum Key Share-কে TCP-র প্রথম Congestion Window-তে (প্রায় ১৪ KB) আঁটতে হবে; ফোলানো Chain বা RSA-4096 Key Server-এর চালানকে সেই সীমা পার করিয়ে আরেকটা Round Trip যোগ করতে পারে। Certificate Compression (RFC 8879) এখানে সাহায্য করে। সবচেয়ে বড় হাতিয়ার হলো Handshake একেবারেই না করা: Keep-alive, Connection Pool, Resumption, আর ব্যবহারকারীর কাছের Edge-এ TLS শেষ করা, যাতে Round Trip-টাই ২০০-র বদলে ১০ ms হয়।

#Session Resumption আর 0-RTT

Resumption আর 0-RTT Early Data, আর Replay কেন গুরুত্বপূর্ণ

Client-এর কাছে গতকালের একটা Ticket আছে। আক্রমণকারী Packet রেকর্ড করে আবার পাঠাতে পারে, কিন্তু Decrypt করতে পারে না।

পরিস্থিতি

Client192.0.2.10
আক্রমণকারীরেকর্ড করে, আবার পাঠায়
Edge Serverbank.example.com
ClientHello + pre_shared_key + key_share
ধাপ 1 / 3
1

Ticket-টা Pre-shared Key হিসেবে দেওয়া হয়, সাথে একটা “Binder” (একটা HMAC, যা প্রমাণ করে Secret-টা সত্যিই Client-এর কাছে আছে) আর একটা নতুন Key Share। Browser psk_dhe_ke Mode চালায়: PSK আর সাথে নতুন ECDHE, এতে Forward Secrecy থেকে যায়।

TLS 1.2-এ Resume করার দুটো উপায় ছিল। Session ID-তে Server সাম্প্রতিক Session-গুলোর একটা Cache রাখে; Load Balancer-এর পেছনে Client প্রায়ই এমন Server-এ গিয়ে পড়ে যার কাছে সেটা নেই। Session Ticket-এ (RFC 5077) Server Session-এর অবস্থাটা একটা Ticket Key দিয়ে Encrypt করে Client-কেই দিয়ে দেয়, নিজে কিছু রাখে না; বহরের প্রতিটা Server-কে সেই Ticket Key ভাগ করে নিতে হয়। ছোট (Abbreviated) Handshake-এ লাগে ১ Round Trip, Certificate বাদ। দুর্বল জায়গা: TLS 1.2-এ Resume করা Session-এ নতুন Key Exchange হয় না, তাই Ticket Key চুরি হলে ওই Key-এর অধীনে Resume হওয়া সব রেকর্ড করা Session খুলে যায়। Ticket Key কয়েক ঘণ্টা পরপর বদলাও, শুধু Memory-তে রাখো।

TLS 1.3 দুটোকে মিলিয়ে বানিয়েছে Pre-shared Key (PSK)। আগের বারের NewSessionTicket দেওয়া হয় pre_shared_key-এ, সাথে একটা Binder (একটা HMAC, যা প্রমাণ করে Secret-টা Client-এর কাছে আছে)। Browser যে psk_dhe_ke Mode চালায় তাতে নতুন একটা ECDHE Exchange-ও যোগ হয়, তাই Resumption-এও Forward Secrecy থাকে। Ticket সর্বোচ্চ ৭ দিন বাঁচে।

0-RTT Early Data আরেক ধাপ এগোয়: আগে এসেছে এমন Client Handshake শেষ হওয়ার আগেই, একদম প্রথম চালানে Encrypt করা Data পাঠিয়ে দেয়। Early Data Encrypt হয় এমন Key দিয়ে, যা আসে শুধু Ticket থেকে। এর দুটো দাম আছে:

১. Replay। প্রথম চালানে Server-এর দেওয়া কিছুই নেই, তাই আক্রমণকারী এটা রেকর্ড করে আবার পাঠাতে পারে, একই Server-এ বা অন্য Edge Server-এ, আর সেটা ঠিকঠাক Decrypt হবে। TLS এটা কিছুটা কমাতে পারে (একবার-ব্যবহারের Ticket, সাম্প্রতিক ClientHello-র Cache, ছোট সময়সীমা), কিন্তু ছড়ানো একটা বিশাল বহরে পুরোপুরি থামাতে পারে না।

২. Early Data-র নিজের কোনো Forward Secrecy নেই: এটা শুধু Ticket-এর Secret-এর ওপর নির্ভর করে।

তাই নিয়ম হলো: 0-RTT নাও শুধু নিরাপদ, Idempotent Request-এর জন্য (একটা Page-এর GET, দামের তালিকা, Static File)। যা কিছু অবস্থা বদলায়, তার জন্য Server Early Data প্রত্যাখ্যান করে, 425 Too Early উত্তর দেয় (RFC 8470), অথবা Early-Data: 1 Header দিয়ে Origin-এ পাঠায় যাতে Origin সিদ্ধান্ত নেয়; Client তখন Handshake-এর পরে আবার পাঠায়। nginx-এ ডিফল্ট হলো ssl_early_data off; যে CDN 0-RTT দেয়, সাধারণত শুধু GET Request-এর জন্য দেয়।

#যে Extension-গুলো Handshake-এর চেহারা ঠিক করে: SNI, ECH আর ALPN

SNI, Encrypted Client Hello আর ALPN: প্রথম Message কী ঠিক করে দেয়

একটাই IP Address, 203.0.113.10, shop.example.com আর blog.example.org দুটোই চালায়, প্রত্যেকের নিজের Certificate।

পরিস্থিতি

Client192.0.2.10
Wi-Fi-র নজরদারশুধু খোলা লেখা দেখে
Shared Server203.0.113.10:443
ClientHello: SNI = shop.example.com
ধাপ 1 / 4
1

Hostname যায় ClientHello-র server_name Extension-এ, কারণ HTTP-র Host Header যাবে Handshake-এর পরে, Encrypt হয়ে।

SNI (Server Name Indication)। একটা IP Address হাজারটা HTTPS সাইট চালাতে পারে, কিন্তু HTTP-র Host Header আসে Handshake-এর পরে। তাই Client ClientHello-র server_name Extension-এ Hostname বসিয়ে দেয়, আর Server মিলে যাওয়া Certificate বাছে। Client যদি কোনো SNI না পাঠায় (কিছু পুরোনো HTTP Library, IP দিয়ে Connect করা Health Check), Server শুধু তার ডিফল্ট Certificate দেখাতে পারে, আর Client নাম না মেলার Error-এ আটকে যায়; কড়া Server এর বদলে unrecognized_name Alert পাঠায়। SNI খোলা লেখা, তাই TLS 1.3-এও পথের যে কেউ জানে তুমি কোন সাইটে যাচ্ছ।

ECH (Encrypted Client Hello)। সাইট নিজের DNS HTTPS Record-এ একটা ECH Public Key প্রকাশ করে (Lesson ১.৮)। Client আসল ClientHello (আসল SNI আর ALPN-সহ) Encrypt করে, আর সেটা মুড়ে দেয় একটা বাইরের ClientHello-তে, যার SNI হলো Provider-এর একটা সাধারণ Public নাম। ২০২৩ থেকে Chrome আর Firefox এটা চালায়, বড় CDN-ও দেয়। সাইট লুকায় কেবল তখনই, যখন অনেক সাইট Provider-এর একই Address ভাগ করে; নিজস্ব IP হলে Address-ই সাইট ধরিয়ে দেয়। নাম দেখে ছাঁকতে কিছু Network ECH বন্ধ রাখে।

ALPN (Application-Layer Protocol Negotiation)। Client কিছু Protocol প্রস্তাব করে (h2, http/1.1; QUIC-এ h3), আর Server Handshake-এর ভেতরেই একটা বাছে, তাই আলাদা কোনো Round Trip খরচ হয় না। কোনোটাই না মিললে কড়া Server উত্তর দেয় no_application_protocol। চেনা উদাহরণ gRPC: তার HTTP/2 লাগে, অথচ সামনের Proxy শুধু HTTP/1.1 জানে।

#Post-quantum Key Exchange

ভবিষ্যতের কোনো বড় Quantum Computer X25519 আর RSA ভাঙতে পারবে। Signature-এর গুরুত্ব শুধু Handshake-এর মুহূর্তে, কিন্তু Key Exchange-এর গুরুত্ব যতদিন Data গোপন থাকা দরকার ততদিন: আক্রমণকারী এখন জমিয়ে রেখে পরে Decrypt করতে পারে। তাই Browser আগে Key Exchange নিয়েই এগিয়েছে।

X25519MLKEM768 Group পুরোনো X25519-কে মেশায় ML-KEM-768-এর সাথে; ML-KEM হলো Lattice-ভিত্তিক Key-encapsulation পদ্ধতি, NIST ২০২৪ সালে যেটার মানদণ্ড ঠিক করেছে (FIPS 203)। Shared Secret দুটোর ওপরই নির্ভর করে, তাই যেকোনো একটা টিকে থাকলেই Connection নিরাপদ। Chrome ২০২৪ সালে এটা ডিফল্ট করেছে, Firefox পেছনে পেছনে এসেছে, Apple ২০২৫-এর Operating System-এ যোগ করেছে, আর OpenSSL 3.5 (২০২৫) ডিফল্টভাবেই এটা দেয়; বড় CDN Browser Traffic-এর বড় একটা অংশে ইতিমধ্যে এটাই চালায়।

দাম হলো আকার: শুধু Client-এর ML-KEM Share-ই ১১৮৪ Byte, Server-এর উত্তর ১০৮৮, তাই ClientHello বেড়ে হয় প্রায় ১.৮ KB, লাগে দুটো TCP Segment। কিছু পুরোনো Middlebox Hello-টা এক Packet-এ আশা করত, তারা এটা ফেলে দিয়েছে; লক্ষণ হিসেবে দেখা যায় ঝুলে থাকা, কোনো TLS Error না (নিচের ব্যর্থতার Animation-এর তৃতীয় Scenario)। Certificate আর তার Signature এখনো পুরোনো ধাঁচের; Post-quantum Signature আকারে বড়, সেগুলো এখনো ধীরে ধীরে চালু হচ্ছে।

#TLS কোথায় শেষ হয়: Termination, Re-encryption, Passthrough

TLS কোথায় শেষ হয়: Termination, Re-encryption আর Passthrough

একই Client, একই Backend; Load Balancer বসানোর তিনটা উপায়। নিচের টেবিলে দেখো Load Balancer কী কী দেখতে পায়।

পরিস্থিতি

Certificate থাকে Load Balancer-এর কাছে, সে-ই Decrypt করে। Backend পায় সাধারণ HTTP।

Backend (Private Subnet)
Client192.0.2.10
Load Balancershop.example.com
Backend 110.0.1.11
Backend 210.0.1.12
🔒 TLS 1.3

Load Balancer কী দেখে

SNI

shop.example.com

Method + Path

POST /api/cart

Header, Cookie

সব পড়া যায়

ধাপ 1 / 3
1

Client-এর TLS Handshake শেষ হয় Load Balancer-এ, shop.example.com-এর Certificate আর Private Key তার কাছেই।

ModeCertificate কোথায় থাকেLoad Balancer কী করতে পারেভেতরের Trafficসাধারণত কোথায়
Termination (Offload)Load Balancer-এLayer 7-এর সব: Path আর Host দেখে Routing, Header যোগ, WAF, Cache, Compressionসাধারণ HTTPবেশিরভাগ Web App, AWS ALB, nginx বা CDN-এর পেছনে
Re-encryption (Bridging)Public Cert Load Balancer-এ, Internal Cert Backend-এLayer 7-এর সবদ্বিতীয় একটা TLS Session দিয়ে Encrypt করাCompliance (Card বা স্বাস্থ্যের তথ্য), Zero Trust
Passthroughশুধু Backend-এশুধু SNI বা Port দেখে Routing; Path, Header, WAF, Cache কিছুই নাশুরু থেকে শেষ পর্যন্ত Encrypt করাEnd-to-end Client mTLS, এমন Load Balancer যাকে Key দিয়ে বিশ্বাস করা যায় না, HTTP না এমন Protocol

কীভাবে বাছবে। শুরু করো Edge-এ Termination দিয়ে: Certificate এক জায়গায় থাকে, Crypto-র বোঝা নামে, Routing নমনীয় হয়। ভেতরের Network-ও Encrypt রাখতে হলে Re-encryption যোগ করো; আজকাল এটাই স্বাভাবিক প্রত্যাশা। Passthrough নাও শুধু তখন, যখন Backend-কে নিজেকেই Client-এর TLS দেখতে হবে (End-to-end mTLS), বা Load Balancer-কে কখনোই Key দেওয়া যাবে না; তখন Layer 7-এর সুবিধা হারাবে, আর Client-এর IP আনতে হবে Proxy Protocol দিয়ে। AWS-এ ALB Terminate করে (আর HTTPS Target-এ আবার Encrypt করতে পারে); NLB TLS Listener দিয়ে Terminate করতে পারে, বা TCP Listener দিয়ে Passthrough।

Client mTLS যদি Load Balancer-এ যাচাই হয়, Backend আর Certificate দেখতে পায় না, তাই Load Balancer যাচাই করা পরিচয়টা একটা Header-এ পাঠায় (Envoy-তে x-forwarded-client-cert, AWS ALB-তে X-Amzn-Mtls-Clientcert)। Client-এর পাঠানো এমন যেকোনো Header Load Balancer-কে মুছে ফেলতে হবে, আর Backend-কে শুধু Load Balancer-এর Traffic নিতে হবে; নইলে Backend পর্যন্ত পৌঁছাতে পারে এমন যে কেউ যেকোনো পরিচয় দাবি করতে পারবে।

#HSTS আর Preload তালিকা, সংক্ষেপে

Lesson ১.৯-এ HSTS দেখেছ: Strict-Transport-Security Header পেলে Browser নিজে থেকেই সাইটটার জন্য HTTPS ব্যবহার করে, আর Certificate Error-কে কড়া ব্যর্থতা বানিয়ে দেয়। প্রথম ভিজিট তবু খোলা থাকে, সেটা সারায় Preload তালিকা। hstspreload.org-এ জায়গা পেতে সাইটকে বৈধ Certificate দিতে হয়, একই Host-এ HTTP থেকে HTTPS-এ Redirect করতে হয়, আর includeSubDomains ও preload-সহ অন্তত এক বছরের max-age পাঠাতে হয়। তালিকা থেকে নাম সরাতে মাসের পর মাস লাগে, তাই আগে ছোট max-age দিয়ে চালু করো। Handshake-এর দিক থেকে HSTS-এর লাভ হলো, সাধারণ HTTP-র Redirect-টা উঠে যায়; প্রথম নিরাপদ Byte-এর আগে আরেকটা Round Trip বাঁচে।

#যখন Handshake ব্যর্থ হয়

Production-এ যখন Handshake ব্যর্থ হয়

তিনটা ব্যর্থতা যা Browser-এ চট করে Test করলে ধরা পড়ে না। মাঝের জন হলো পথে যা-ই বসে আছে: Firewall, Proxy বা Load Balancer।

পরিস্থিতি

Certificate Renew করার পরে Server-এ শুধু Leaf Certificate বসানো হয়েছে, পুরো Chain না।

Mobile Appবা curl, Java
Middleboxপুরোনো Firewall
shop.example.com198.51.100.20:443
ClientHello
ধাপ 1 / 3
1

স্বাভাবিক Handshake শুরু।

Handshake ব্যর্থ হলে শেষ হয় একটা TLS Alert দিয়ে, আর তার নাম সাধারণত বলে দেয় কোথায় খুঁজতে হবে:

লক্ষণ (Alert বা Error)সাধারণ কারণসমাধান
certificate_expired (৪৫), NET::ERR_CERT_DATE_INVALIDRenewal ব্যর্থ, বা Client-এর ঘড়ি ভুলRenewal স্বয়ংক্রিয় করো, মেয়াদ শেষের অনেক আগে Alert; NTP দিয়ে সময় মেলাও
এক ধরনের Device-এ শুধু “এখনো বৈধ না”Device ভুল ঘড়ি নিয়ে চালু হয়েছে (Battery-চালিত ঘড়ি নেই)প্রথম TLS Call-এর আগে সময় মেলাও
curl, Java, App-এ unable to get local issuer certificate; Browser-এ ঠিকServer শুধু Leaf পাঠায়, Intermediate নাপুরো Chain বসাও; openssl s_client দিয়ে Test করো
শুধু কিছু Client থেকে Hostname মেলে নাSNI নেই, তাই ডিফল্ট Certificate যাচ্ছেClient যেন SNI পাঠায়; IP দিয়ে করা Check-এ প্রত্যাশিত নাম বলে দাও
protocol_version (৭০)Client খুব পুরোনো (TLS 1.0/1.1), বা Server-এর সর্বনিম্ন খুব উঁচুClient আপগ্রেড করো; Server-এর সর্বনিম্ন TLS 1.2 রাখো
handshake_failure (৪০), “no shared cipher”মিলে যাওয়া Cipher Suite বা Group নেইClient ঠিক করো; মূল Endpoint-এ দুর্বল Suite বন্ধ রাখো
no_application_protocol (১২০)ALPN মেলে না, যেমন HTTP/1.1-only Proxy-র পেছনে gRPC (h2)Proxy বা Load Balancer-এ h2 চালু করো
unknown_ca (৪৮)অন্য পাশ যাকে বিশ্বাস করে না এমন CA-র Certificate (ভুল Environment, Private CA বসানো নেই)ঠিক CA Bundle বসাও; যাচাই বন্ধ করে কখনো “সমাধান” কোরো না
certificate_required (১১৬)Server Client Certificate চায়, কিন্তু কিছু আসেনি (mTLS)Client Certificate Mount করো; Client Library সেটা পাঠায় কি না দেখো
ClientHello-র পরে ঝুলে থাকা বা Reset, কোনো Alert নেইকোনো Middlebox বড় Post-quantum ClientHello ফেলে দিচ্ছে, বা MTU-র সমস্যাMiddlebox আপডেট করো; MTU আর Fragmentation দেখো

#Mutual TLS (mTLS)

সাধারণ TLS/HTTPS-এ শুধু Client Server-এর পরিচয় যাচাই করে (One-way Authentication): Server প্রমাণ করে সে shop.example.com, আর TLS-এর স্তরে Client অচেনাই থাকে, পরে Password বা Token দিয়ে Login করে। Mutual TLS (mTLS)-এ Server আর Client দুজনেই একে অপরের Certificate যাচাই করে (Two-way Authentication)।

[ One-way TLS / সাধারণ HTTPS ]
Client ── Server-এর Certificate যাচাই ──►  Server

[ Mutual TLS (mTLS) ]
Client ── Server-এর Certificate যাচাই ──►  Server
Client ◄── Client-এর Certificate যাচাই ──  Server

Mutual TLS: দুই পাশই Certificate দেখায়

Orders Service Payments Service-কে Call করে। দুজনের কাছেই কোম্পানির Private CA থেকে পাওয়া স্বল্পমেয়াদি Certificate।

পরিস্থিতি

orders (Client)spiffe://example.com/ns/shop/sa/orders
payments (Server)payments.shop.svc
ClientHello + key_share
ধাপ 1 / 9
1

একদম সাধারণ TLS 1.3 ClientHello। এতে “আমার Certificate আছে” বলা থাকে না: চাইবে কি না, সেটা Server ঠিক করে।

#কীভাবে কাজ করে

  1. ১. সাধারণ TLS-এর মতোই Server তার Certificate পাঠায়

    Handshake শুরু হয় হুবহু সাধারণ Handshake-এর মতো।

  2. ২. Server Client-এর Certificate চায় (CertificateRequest)

    বাড়তি ধাপ হিসেবে Server পাঠায় CertificateRequest, যাতে লেখা থাকে কোন Signature Algorithm আর চাইলে কোন CA সে মানে।

  3. ৩. Client নিজের Certificate আর Private Key দিয়ে Sign করা প্রমাণ পাঠায়

    Client পাঠায় নিজের Certificate আর একটা CertificateVerify: নিজের Private Key দিয়ে Handshake Transcript-এর ওপর একটা Signature। Key কখনো Client ছেড়ে যায় না, যায় শুধু Key থাকার প্রমাণ। TLS 1.3-এ দুটোই Encrypt করা; TLS 1.2-এ Client Certificate খোলা অবস্থায় যেত, ফলে Client কে, সেটা সবাই দেখতে পেত।

  4. ৪. Server যাচাই করে, তবেই Connection মঞ্জুর

    Server তার Client CA Bundle দিয়ে Chain, তারিখ আর Signature মিলিয়ে দেখে। কোনো একটা না মিললে একটা Alert দিয়ে Handshake শেষ: certificate_required (Certificate নেই), unknown_ca (ভুল CA), certificate_expired, বা bad_certificate। তারপর আসে আলাদা একটা ধাপ, যেটা মানুষ ভুলে যায়: Authorisation (অনুমতি)। বৈধ Certificate বলে Call করছে কে; সে কী করতে পারবে, তা এখনো একটা নিয়মকে ঠিক করতে হয় (ওপরের শেষ Scenario)।

#কোথায় ব্যবহার হয়

  • Microservice। ভেতরের Service-to-service Traffic নিরাপদ রাখতে, সাধারণত Istio বা Linkerd-এর মতো Kubernetes Service Mesh নিজে থেকেই করে।
  • Zero Trust। প্রতিটা Workload আর Device-এর পরিচয় প্রমাণ করা, Network-এর “ভেতরে” আছে বলেই কাউকে বিশ্বাস না করা (Lesson ১.১২; Zero Trust-এর নকশা Chapter ৩৩-এ)।
  • Financial আর B2B API। Bank, Payment Gateway আর Open Banking API প্রায়ই Partner-দের Client Certificate দেখাতে বলে, কখনো OAuth Token-কেও সেই Certificate-এর সাথে বেঁধে দেয় (OAuth আসবে Chapter ৩৪–৩৫-এ)।
  • Device। IoT Device কারখানাতেই বসানো একটা Certificate দিয়ে নিজের Cloud-এ পরিচয় দেয়।

#Service-এর পরিচয়: SPIFFE আর SPIRE

একটা Service-এর Certificate-এ এমন একটা নাম লাগে, যা তোমার নিয়মের কাছে অর্থ বহন করে। SPIFFE হলো সেই নামের একটা খোলা মানদণ্ড: spiffe://example.com/ns/shop/sa/orders-এর মতো একটা URI (আগে Trust Domain, তারপর একটা Path; Istio Namespace আর Service Account ব্যবহার করে)। এটা থাকে একটা SVID-এ, সাধারণত একটা X.509 Certificate, যার URI SAN-এ ID বসানো। SPIRE হলো মূল বাস্তবায়ন: একটা Server যা পরিচয় Sign করে, আর প্রতিটা Node-এ একটা Agent, যে Workload-কে যাচাই করে (কোন Kubernetes Service Account, কোন Node, কোন Process), তারপর Local Socket দিয়ে তাকে Certificate দেয়। Istio আর Linkerd নিজেদের CA থেকে SPIFFE ধাঁচের পরিচয় দেয়।

#স্বল্পমেয়াদি Certificate আর Rotation

ভেতরের mTLS Certificate ইচ্ছে করেই স্বল্পমেয়াদি: SPIRE-এ ডিফল্ট এক ঘণ্টা, Istio আর Linkerd-এ ২৪ ঘণ্টা। তাহলে চুরি যাওয়া Key কাজে লাগে কয়েক ঘণ্টা, এক বছর না, আর Revocation তালিকার দরকার প্রায় থাকে না। দাম হলো, Renewal হয়ে যায় জরুরি পথ: Proxy মোটামুটি অর্ধেক মেয়াদে Renew করে, আর বাকি মেয়াদের চেয়ে বেশি সময় CA-তে পৌঁছানো না গেলে সব Call একসাথে ব্যর্থ হয় (Mesh Animation-এর শেষ Scenario)। CA-কে High Availability-তে চালাও, Renewal ব্যর্থ হলে আর Certificate-এর বয়স বাড়লে Alert দাও, আর এমন মেয়াদ বাছো যা CA-র সবচেয়ে খারাপ যে Outage তুমি সারাতে পারো তার চেয়ে লম্বা।

Client Certificate-এর জন্য Private CA ব্যবহার করো। Public CA Domain নামের জামিন দেয়, তোমার Service-এর না; আর ২০২৬ সাল জুড়ে Public Web CA-গুলো Client-authentication EKU-ওয়ালা Certificate দেওয়াই বন্ধ করছে (Chrome Root Program-এর নিয়ম), তাই Public Web Certificate-এর ওপর বানানো mTLS ভেঙে যায়।

#Service Mesh: Sidecar বনাম Ambient

Service Mesh-এ mTLS: পরিচয়, Proxy আর Rotation

Application-গুলো Local Proxy-র সাথে সাধারণ HTTP-তে কথা বলে; Proxy-গুলো Mesh CA-র Certificate দিয়ে mTLS করে।

পরিস্থিতি

প্রতিটা Pod-এর নিজের একটা Proxy Container (Istio-তে Envoy, Linkerd-এ linkerd2-proxy)।

Mesh CASPIRE বা istiod
orders App
Proxy A
Proxy B
payments App
SVID …/sa/ordersSVID …/sa/payments
ধাপ 1 / 4
1

চালু হওয়ার সময় প্রতিটা Proxy CA-কে প্রমাণ দেয় সে কোন Workload হিসেবে চলছে (Kubernetes Service Account, Node-এর প্রমাণ), আর পায় একটা স্বল্পমেয়াদি Certificate, যার URI SAN-এ তার SPIFFE ID। Private Key Pod-এর ভেতরেই তৈরি হয়, কখনো বাইরে যায় না।

Sidecar Mesh-এ প্রতিটা Pod পায় নিজের একটা Proxy (Istio-তে Envoy, Linkerd-এ linkerd2-proxy)। Application Localhost-এর সাথে সাধারণ HTTP-তে কথা বলে; Proxy-রা mTLS করে, নিয়ম খাটায়, Retry করে, Metric জমায়। Application-এ কোনো TLS Code লাগে না, কিন্তু প্রতিটা Pod-কে একটা Proxy-র Memory আর CPU গুনতে হয়, দুই পাশে একটা করে বাড়তি ধাপ, আর Proxy আপগ্রেড করলে Pod Restart হয়।

Ambient (Sidecar ছাড়া) Mode-এ, যা Istio-তে ২০২৪ সালের শেষ থেকে সবার জন্য চালু, প্রতি Node-এ একটা ভাগ করা Proxy (ztunnel) প্রতিটা Pod-এর নিজের পরিচয়ে mTLS Tunnel-এ Traffic বয়, আর Layer 4-এর নিয়ম খাটায়; দরকার হলে শুধু সেখানে একটা Waypoint Proxy Layer 7-এর নিয়ম যোগ করে। Cilium-ও Node-স্তরের এমন একটা ব্যবস্থা দেয়। একই নিশ্চয়তা, অনেক কম Proxy। Mesh-এর নকশা আর তার দরদাম আসবে Chapter ৩৩ আর ৪৬-এ।

#mTLS বনাম API Key বনাম JWT

API KeyJWT (Bearer Token)mTLS
কী পাঠানো হয়Header-এ একটা গোপন StringClaim আর মেয়াদসহ Sign করা একটা Tokenশুধু Private Key থাকার একটা প্রমাণ
ধরা পড়লে বা Log-এ উঠলেRotate না করা পর্যন্ত ব্যবহারযোগ্যমেয়াদ শেষ না হওয়া পর্যন্ত ব্যবহারযোগ্যPrivate Key ছাড়া অকেজো
কাকে চেনায়একটা Application বা Accountএকজন User বা Service, Claim-সহ (Role, Scope)একটা Workload বা Device (Certificate-এর Subject, SPIFFE ID)
স্তরApplication (HTTP)Application (HTTP)Transport (TLS)
TLS শেষ করা Proxy পার হয়?হ্যাঁহ্যাঁনা: Proxy-কে পরিচয়টা এগিয়ে দিতে হয়
পরিচালনাদেওয়া সহজ; সব জায়গায় Rotate করা কঠিনএকটা Signing Key আর Issuer লাগেCA, Certificate দেওয়া, Rotation, Trust Bundle লাগে
কোথায় সবচেয়ে ভালোসাধারণ Public API, ব্যবহার মাপাService-জুড়ে End User-এর পরিচয়Service-to-service, Partner, Device

এরা প্রতিদ্বন্দ্বী না। Production-এ চেনা একটা নকশা হলো Workload-এর পরিচয়ের জন্য mTLS (কোন Service Call করছে), আর End User-এর জন্য JWT (কার হয়ে Call করছে); OAuth তো Token-কে Client Certificate-এর সাথে বেঁধেও দিতে পারে, যাতে চুরি যাওয়া Token অন্য কোথাও অকেজো (Chapter ৩৪–৩৫)।

#System Design-এ TLS

  • TLS 1.3 পছন্দ করো; পুরোনো Client-এর জন্য TLS 1.2 রাখো শুধু ECDHE আর AEAD Suite দিয়ে; 1.0 আর 1.1 বন্ধ।
  • Connection আবার ব্যবহার করো (Keep-alive, Pool, HTTP/2 আর HTTP/3)। সবচেয়ে দ্রুত Handshake হলো যেটা করতেই হয় না।
  • Edge-এ Terminate করো, ব্যবহারকারীর কাছে, আর Edge থেকে Origin পর্যন্ত চালু, আবার Encrypt করা Connection রাখো।
  • Resumption চালু, Ticket Key বদলানো আর বহরে ভাগ করা; 0-RTT শুধু Idempotent Path-এ, যদি আদৌ রাখো।
  • Handshake-এর CPU কমাতে ECDSA Certificate (বা ECDSA আর RSA দুটোই); Chain ছোট আর সম্পূর্ণ রাখো।
  • Edge-এ X25519MLKEM768 চালাও; দেখে নাও তোমার Middlebox দুই Packet-এর ClientHello পার হতে দেয় কি না।
  • Certificate স্বয়ংক্রিয় করো আর তাদের বয়স নজরে রাখো; বেশিরভাগ TLS Outage হয় মেয়াদ, হারানো Intermediate, নয়তো ঘড়ির কারণে।
  • ভেতরে: Private CA থেকে আসা, স্বল্পমেয়াদি, নিজে থেকে Rotate হওয়া Certificate দিয়ে mTLS, সাথে প্রতিটা Service-এর জন্য Authorisation-এর নিয়ম।

#নিজে করে দেখো

# পুরো TLS 1.3 Handshake-এর খুঁটিনাটি: Version, Cipher, Group, Certificate Chain
openssl s_client -connect example.com:443 -servername example.com -brief </dev/null

# জোর করে TLS 1.2 চালাও, পুরোনো ধাঁচের Cipher Suite-এর নাম দেখো
openssl s_client -connect example.com:443 -servername example.com -tls1_2 -brief </dev/null

# Post-quantum Hybrid Group চাও (OpenSSL 3.5 বা নতুন)
openssl s_client -connect example.com:443 -servername example.com -groups X25519MLKEM768 -brief </dev/null

# SNI ছাড়া: Shared Server ডিফল্ট হিসেবে কোন Certificate দেয় দেখো
openssl s_client -connect example.com:443 -noservername </dev/null | openssl x509 -noout -subject

# Server যে পুরো Chain পাঠায় তা দেখো (Certificate গোনো)
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null

# Resumption: একটা Session রেখে দাও, তারপর আবার ব্যবহার করো ("Reused, TLSv1.3")
openssl s_client -connect example.com:443 -servername example.com -sess_out /tmp/s.pem </dev/null
openssl s_client -connect example.com:443 -servername example.com -sess_in /tmp/s.pem </dev/null | grep -i reused

# প্রতিটা ধাপের সময়: TCP Connect বনাম TLS Handshake
curl -so /dev/null -w "tcp %{time_connect}  tls %{time_appconnect}\n" https://example.com

# Client-এর দিক থেকে Mutual TLS
curl --cert client.crt --key client.key --cacert internal-ca.pem https://api.internal.example.com/health

Wireshark-এ ClientHello দেখতে tls.handshake.type == 1 Filter দাও, আর server_name, supported_versions, key_share দেখো (X25519MLKEM768-এর Share ১২০০ Byte-এর বেশি)। একটা TLS 1.2 Capture, যেখানে Certificate Message পড়া যায়, তার সাথে একটা TLS 1.3 Capture মিলিয়ে দেখো, যেখানে ServerHello-র পরে সবই “Application Data”।

#সারসংক্ষেপ

এই Lesson-এর জন্য নোটের সারসংক্ষেপের সারিগুলো, খুঁটিনাটি যোগ করে:

বিষয়সারকথা
TLS 1.2 বনাম 1.3TLS 1.2-এ লাগে ২ RTT (ClientHello; ServerHello, Certificate, ServerKeyExchange, ServerHelloDone; ClientKeyExchange, ChangeCipherSpec, Finished; ChangeCipherSpec, Finished)। TLS 1.3-এ ১ RTT (ClientHello-তেই Key Share, ServerHello-র পরে সব Encrypt করা), আর Resumption-এ 0-RTT Early Data চলে, যা নিরাপদ শুধু Idempotent Request-এর জন্য।
mTLSClient আর Server দুজনেই একে অপরের Certificate যাচাই করে (CertificateRequest, Client-এর Certificate আর CertificateVerify)। ব্যবহার হয় Microservice-এর মধ্যে, Zero Trust-এ, আর Financial ও B2B API-তে, Private CA থেকে আসা স্বল্পমেয়াদি Certificate দিয়ে।

মূল কথাগুলো

  • প্রতিটা Handshake-কে Algorithm-এ একমত হতে হয়, Key-তে একমত হতে হয়, Server-এর (আর mTLS-এ Client-এরও) পরিচয় প্রমাণ করতে হয়, আর প্রমাণ করতে হয় Transcript কেউ বদলায়নি (Finished)।
  • TLS 1.2: ২ RTT। ClientHello → ServerHello, Certificate (খোলা), ServerKeyExchange (Sign করা ECDHE Key), ServerHelloDone → ClientKeyExchange, ChangeCipherSpec, Finished → ChangeCipherSpec, Finished। Pre-master → Master Secret (দুটো Random-সহ PRF) → Key Block।
  • RSA Key Transport-এ Forward Secrecy নেই: পরে চুরি যাওয়া Key রেকর্ড করা Traffic খুলে দেয়। ECDHE এটা সারায়; TLS 1.3 শুধু অস্থায়ী Key Exchange চালাতে দেয়।
  • TLS 1.3: ১ RTT। ClientHello-তেই Key Share; ServerHello-র পরে সব Encrypt করা (EncryptedExtensions, Certificate, CertificateVerify, Finished); Transcript-এর সাথে বাঁধা HKDF Key Schedule; HelloRetryRequest-এ একটা Round Trip বাড়ে; মাত্র ৫টা AEAD Suite; RSA Key Exchange, CBC, RC4, Compression আর Renegotiation বিদায়।
  • Resumption: 1.2-এ Session ID আর Ticket, 1.3-এ PSK (Forward Secrecy-র জন্য সাথে ECDHE)। 0-RTT প্রথম চালানেই Data পাঠায়, কিন্তু Replay হতে পারে: শুধু Idempotent Request, বাকিদের জন্য 425 Too Early।
  • SNI Certificate বাছে আর খোলা লেখা; ECH একটা সাধারণ নামের পেছনে সেটা লুকায়; ALPN Handshake-এর ভেতরেই h2/http/1.1/h3 বাছে। X25519MLKEM768 হলো ডিফল্ট Hybrid Post-quantum Key Exchange, এতে ClientHello হয় প্রায় ১.৮ KB।
  • Termination দেয় Layer 7-এর সুবিধা, ভেতরে খোলা লেখা; Re-encryption ভেতরেও Encrypt করে; Passthrough End-to-end TLS রাখে কিন্তু Layer 7 হারায়। HSTS Preload প্রথম সাধারণ HTTP Request-টাও তুলে দেয়।
  • চেনা ব্যর্থতা: মেয়াদ শেষ, ঘড়ির গরমিল, হারানো Intermediate, SNI নেই, Version বা Cipher না মেলা, ALPN না মেলা, অচেনা CA, Client Certificate নেই, বড় Hello ফেলে দেওয়া Middlebox।
  • mTLS: CertificateRequest → Client-এর Certificate + CertificateVerify → Server যাচাই করে, তারপর অনুমতি দেয়। স্বল্পমেয়াদি Certificate-এ SPIFFE ID, নিজে থেকে Rotate হয়; Sidecar বা Ambient Mesh কাজটা করে দেয়। Service-এর জন্য mTLS আর User-এর জন্য JWT একসাথে চালাও।