Kriptografi kunci asimetris
Di pelajaran ini kita akan melihat kriptografi kunci asimetris yang menjadi dasar banyak interaksi jaringan aman yang ada saat ini.
Di akhir pelajaran kita akan sudah membahas:
- Apa itu kriptografi kunci asimetris
- Penggunaan kriptografi kunci asimetris, termasuk pertukaran kunci dan tanda tangan digital
- Keamanan kriptografi kunci asimetris secara umum
- Detail lebih lanjut tentang algoritma RSA, DSA, dan Elliptic Curves serta keamanannya
- Beberapa contoh kode Python yang memperlihatkan cara kerja algoritma secara praktis
- Ancaman terhadap algoritma-algoritma ini dari komputer klasik maupun kuantum
Pengantar kriptografi kunci asimetrisβ
Seperti yang kita pelajari di pelajaran sebelumnya, kriptografi kunci simetris sangat cepat dan efisien untuk melindungi informasi, tapi ada beberapa keterbatasannya:
- Semakin banyak pihak yang ingin bertukar informasi secara aman, jumlah kunci yang dibutuhkan tumbuh secara kombinatorial. Tidak ada mekanisme untuk mendistribusikan kunci-kunci ini secara aman antara pengirim dan penerima.
- Tidak ada ketentuan untuk non-repudiation. Semua pihak bisa mendekripsi atau mengenkripsi pesan tanpa cara untuk memastikan pesan telah diterima atau dari mana asalnya.
Solusi untuk kedua masalah ini disediakan oleh kriptografi kunci asimetris (AKC), yang juga dikenal sebagai kriptografi kunci publik (PKC), yang karenanya menjadi fondasi keamanan digital modern.
Kriptografi kunci asimetris (AKC) melibatkan penggunaan sepasang kunci β satu publik, satu privat. Kunci publik dan privat terhubung secara kriptografis dan biasanya dibuat secara bersamaan sebagai pasangan kunci menggunakan algoritma matematis khusus. Kunci publik, seperti namanya, dimaksudkan untuk didistribusikan secara bebas, sementara kunci privat dijaga kerahasiaannya oleh pihak yang membuat pasangan kunci tersebut. Keamanan komunikasi yang menggunakan pasangan kunci asimetris terjamin selama kunci privat tetap rahasia.

Gambar 1. Enkripsi Kunci Asimetris
AKC menawarkan beberapa fungsi berguna, seperti:
- Enkripsi dan dekripsi untuk mengaktifkan kerahasiaan komunikasi.
- Tanda tangan digital untuk memastikan keaslian, integritas, dan non-repudiation.
- Pertukaran kunci yang aman untuk memfasilitasi penggunaan kriptosistem simetris berikutnya.
Dalam aplikasi modern, AKC terutama digunakan untuk tanda tangan digital dan pertukaran kunci yang aman. Di pelajaran ini, kita memperkenalkan dua fungsi kunci ini, lalu kita membahas beberapa variasi protokol kriptografi untuk fungsi-fungsi tersebut.
Pertukaran kunci dengan kriptografi kunci asimetrisβ
Salah satu masalah mendasar dalam kriptografi adalah pertukaran kunci secara aman. Misalnya, jika dua pihak ingin menggunakan enkripsi simetris, keduanya membutuhkan kunci yang sama untuk mengenkripsi dan mendekripsi pesan. Tapi bagaimana mereka menukar kunci itu secara aman? Kriptografi kunci asimetris mengatasi ini melalui mekanisme pertukaran kunci interaktif dan non-interaktif.
Pertukaran kunci interaktifβ
Protokol pertukaran kunci interaktif mengacu pada metode di mana dua pihak bekerja sama untuk membuat kunci rahasia bersama melalui saluran komunikasi yang tidak aman. Kunci rahasia bersama ini kemudian bisa digunakan untuk tugas enkripsi dan dekripsi simetris.
Yang paling terkenal di antara protokol seperti itu adalah algoritma Diffie-Hellman (DH), yang dirancang khusus untuk memfasilitasi pertukaran kunci. Dalam protokol ini, setiap pihak menghasilkan sepasang kunci (publik dan privat) dan menyiarkan kunci publik mereka. Kemudian setiap pihak menggunakan kunci privat mereka sendiri dan kunci publik pihak lain untuk menghasilkan kunci rahasia bersama. DH menggunakan prinsip aritmatika modular untuk memastikan kedua pihak berakhir dengan rahasia bersama yang sama meskipun setiap pihak hanya memiliki akses ke kunci publik pihak lain.
Kriptosistem modern berbasis kriptografi kurva eliptik (ECC) memperluas konsep ini dengan pertukaran kunci elliptic curve Diffie-Hellman (ECDH). ECDH bekerja mirip dengan DH tapi memanfaatkan sifat-sifat kurva eliptik, menghasilkan sistem yang lebih aman dan efisien.

Gambar 2. Protokol Pertukaran Kunci
Pertukaran kunci non-interaktifβ
Tidak seperti protokol pertukaran kunci seperti DH dan ECDH, yang bersifat interaktif dan memerlukan komunikasi bolak-balik untuk menentukan kunci simetris, AKC juga menyediakan cara non-interaktif untuk menetapkan kunci rahasia bersama. Dalam skema tersebut, satu pihak menghasilkan sepasang kunci (publik dan privat) dan berbagi kunci publik dengan pihak lain. Pihak kedua ini kemudian menghasilkan kunci simetris acak, mengenkripsinya dengan kunci publik yang diterima, dan mengirimkannya kembali ke pihak pertama. Pihak pertama menggunakan kunci privat mereka untuk mendekripsi pesan yang diterima, sehingga mendapatkan kunci simetris bersama. Skema ini bersifat non-interaktif karena kunci simetris ditentukan oleh satu pihak dan hanya dikomunikasikan secara aman ke pihak lain dalam bentuk terenkripsi.
Pertimbangan penting dalam pertukaran kunci non-interaktif berkaitan dengan perbedaan panjang dalam bit antara kunci simetris yang ingin ditukar oleh para pihak dan ukuran pesan yang direkomendasikan dalam AKC. Biasanya, kunci simetris modern berkisar antara 128-256 bit, sementara kriptosistem kunci asimetris seperti RSA bekerja dengan ukuran pesan sekitar 1024-4096 bit. Oleh karena itu, saat menggunakan AKC untuk mengirimkan kunci simetris, demi keamanan kunci tersebut tetap harus dikodekan ke dalam pesan yang lebih panjang 1024-4096 bit. Ini bisa dicapai melalui dua pendekatan:
-
Pertukaran kunci berbasis padding: Dalam pendekatan ini, kunci simetris yang lebih pendek (128-256 bit) dibuat terlebih dahulu lalu skema padding yang dapat dibalik yang telah disepakati seperti OAEP digunakan untuk menyematkannya ke dalam pesan yang lebih panjang (1024-4096 bit). Pesan yang lebih panjang ini dienkripsi menggunakan AKC dan disiarkan sebagai ciphertext. Penerima pertama mendekripsi ciphertext dan kemudian menghapus padding untuk mengekstrak kunci simetris yang lebih pendek.
-
Mekanisme enkapsulasi kunci (KEM): Dengan pertukaran kunci berbasis KEM, pesan teks biasa yang panjang (1024-4096 bit) dibuat secara acak terlebih dahulu, dari mana kunci simetris yang lebih pendek (128-256 bit) bisa diekstrak menggunakan fungsi derivasi kunci (KDF) yang telah disepakati. Teks biasa yang lebih panjang dienkripsi menggunakan AKC dan disiarkan ke penerima sebagai ciphertext. Penerima mendekode ciphertext menggunakan kunci privat mereka lalu menggunakan KDF untuk mengekstrak kunci simetris yang lebih pendek (128-256 bit). Kriptosistem populer seperti RSA, dengan kemampuannya untuk mengenkripsi data secara langsung, bisa digunakan untuk mengimplementasikan KEM.

Gambar 3. Mekanisme Enkapsulasi Kunci
Tanda tangan digital dengan kriptografi kunci asimetrisβ
Tanda tangan digital adalah aplikasi lain yang kuat dari kriptografi kunci asimetris. Mereka memberikan autentikasi, integritas, dan non-repudiation yang dimungkinkan oleh fakta bahwa dalam AKC, entitas memiliki kunci privat yang unik. Ide dasar yang mendasari protokol tanda tangan adalah bahwa pengirim pesan aman akan secara tambahan menandatangani secara digital pesan menggunakan kunci privat unik mereka. Penerima kemudian akan memverifikasi tanda tangan digital menggunakan kunci publik pengirim. Dalam AKC, tanda tangan digital bisa diimplementasikan dengan menggunakan algoritma yang dirancang khusus untuk tujuan tersebut atau dengan menggunakan kriptosistem generik.

Gambar 4. Tanda tangan digital dengan kriptografi kunci asimetris
Algoritma tanda tangan digital yang didedikasikanβ
Saat ini, Standar Pemrosesan Informasi Federal AS (FIPS) untuk tanda tangan digital adalah skema khusus yang secara sederhana disebut Algoritma Tanda Tangan Digital (DSA). Agak mirip dengan protokol Diffie-Hellman, DSA menggunakan sifat aljabar dari eksponensiasi modular dan invers multiplikatif untuk pembuatan dan verifikasi tanda tangan.
Algoritma tanda tangan digital kurva eliptik (ECDSA) adalah varian ECC dari DSA, menyediakan fungsionalitas yang sama tapi dengan kunci yang jauh lebih pendek. Ini menghasilkan peningkatan efisiensi, menjadikannya pilihan populer untuk sistem dengan kendala sumber daya.
DSA dan ECDSA akan diilustrasikan lebih rinci nanti.
Skema tanda tangan digital menggunakan kriptosistem generikβ
Selain algoritma yang didedikasikan, tanda tangan digital juga bisa dibuat menggunakan kriptosistem asimetris generik, seperti RSA.
RSA, yang akan dibahas secara rinci di bagian selanjutnya, juga memanfaatkan invers multiplikatif modular dan eksponensiasi modular sebagai operasi dasar tapi menggabungkannya dalam urutan yang berbeda dari DSA. Dalam RSA, penanda tangan biasanya membuat hash dari pesan lalu mengenkripsi hash dengan kunci privatnya, menciptakan tanda tangan digital. Pihak mana pun kemudian bisa memverifikasi tanda tangan ini dengan mendekripsinya menggunakan kunci publik penanda tangan dan membandingkannya dengan pesan yang di-hash.
Aplikasi kriptografi kunci asimetrisβ
Kriptografi kunci asimetris bersifat ubiquitous dalam aplikasi teknologi digital modern. Fungsionalitas dasar AKC yang dijelaskan di atas membentuk blok bangunan banyak protokol aplikasi tingkat lebih tinggi, termasuk:
-
Komunikasi internet: Komunikasi aman melalui internet, seperti HTTPS, sangat bergantung pada kriptografi kunci asimetris. Transport Layer Security (TLS) dan pendahulunya, Secure Sockets Layer (SSL), menggunakan kriptografi kunci asimetris selama proses handshake awal untuk menetapkan kunci simetris, yang kemudian digunakan untuk sisa sesi komunikasi.
-
Autentikasi: Kriptografi kunci asimetris digunakan untuk membuat tanda tangan digital, memungkinkan suatu entitas mengautentikasi dokumen atau pesan digital sebagai berasal dari pengirim tertentu. Ini digunakan dalam banyak skenario, dari memverifikasi pembaruan perangkat lunak hingga kontrak digital yang mengikat secara hukum.
-
Enkripsi email: Protokol enkripsi email seperti PGP (Pretty Good Privacy) dan alternatif open-source-nya GPG (GNU Privacy Guard) menggunakan kriptografi kunci asimetris untuk memastikan bahwa hanya penerima yang dituju yang bisa membaca isi email.
-
Secure shell (SSH): SSH adalah protokol untuk login jarak jauh yang aman dan layanan jaringan aman lainnya melalui jaringan yang tidak aman. SSH menggunakan kriptografi kunci asimetris untuk mengautentikasi server ke klien dan, opsional, klien ke server.
-
VPN (virtual private network): Enkripsi kunci asimetris digunakan untuk menetapkan koneksi aman dalam VPN, memastikan komunikasi aman melalui jaringan publik.
-
Blockchain dan mata uang kripto: Teknologi blockchain, termasuk Bitcoin dan Ethereum, menggunakan kriptografi kunci asimetris. Misalnya, kepemilikan Bitcoin ditetapkan melalui tanda tangan digital menggunakan kriptografi kunci asimetris.
-
Otoritas sertifikat: Kriptografi kunci asimetris digunakan oleh otoritas sertifikat (CA) untuk menerbitkan dan menandatangani sertifikat digital, yang digunakan dalam komunikasi TLS, penandatanganan kode, enkripsi email, dan lainnya. Sertifikat digital mengikat kunci publik ke entitas tertentu (misalnya, seseorang atau server).

Gambar 5. Menerbitkan dan menandatangani sertifikat digital menggunakan kriptografi kunci asimetris
Keamanan kriptografi kunci asimetrisβ
Beberapa konsep kriptografi bersatu untuk mengaktifkan kriptografi kunci asimetris yang aman, termasuk:
Kerahasiaan kunci privat: Persyaratan keamanan paling dasar dari AKC adalah bahwa kunci privat tetap rahasia. Namun, karena kunci privat harus terhubung secara matematis dengan kunci publik, kerahasiaan kunci privat juga mengharuskan bahwa tidak mungkin secara komputasi untuk menurunkan kunci privat dari pengetahuan kunci publik. Skema pembuatan kunci dalam AKC mengandalkan masalah matematis yang sulit secara komputasi untuk memfasilitasi persyaratan ini.
Fungsionalitas trapdoor Dalam AKC, operasi enkripsi dan dekripsi melibatkan kunci komplementer yang berbeda dari satu pasangan kunci. Ciphertext yang dihasilkan oleh enkripsi menggunakan salah satu kunci (misalnya kunci publik) harus tidak terbaca oleh pihak ketiga sementara mudah didekripsi oleh pemegang kunci komplementer (dalam hal ini kunci privat). Dengan kata lain, enkripsi harus menyerupai sebuah fungsi satu arah trapdoor sedemikian rupa sehingga pihak ketiga tidak bisa membalik operasi dan memulihkan teks biasa tapi kunci privat menyediakan trapdoor rahasia yang memungkinkan inversi yang mudah. Algoritma AKC populer menggunakan eksponensiasi modular untuk menyiapkan perilaku fungsi satu arah trapdoor.
Keacakan: Proses pembuatan kunci juga harus memanfaatkan keacakan untuk memastikan bahwa kunci tidak dapat diprediksi, karena pola atau prediktabilitas apa pun dalam pembuatan kunci bisa dieksploitasi oleh penyerang. Keacakan juga digunakan untuk padding selama enkripsi untuk menghasilkan ciphertext yang aman secara semantis dan dalam skema tanda tangan digital untuk menghasilkan tanda tangan unik bahkan ketika pesan yang sama ditandatangani beberapa kali. Untuk alasan ini, penggunaan generator angka acak yang kuat adalah bagian penting dari AKC.
Ukuran kunci besar: Seperti halnya SKC, ukuran kunci yang besar memastikan perlindungan terhadap serangan brute force. Namun, karena ukuran kunci yang besar juga meningkatkan biaya komputasi proses enkripsi dan dekripsi, solusi optimal perlu menyeimbangkan pertimbangan keamanan dan efisiensi. Tabel berikut menunjukkan ukuran kunci tipikal untuk berbagai protokol dan aplikasi kriptografi kunci asimetris:
| Protokol | Ukuran Kunci Tipikal (dalam bit) | Aplikasi |
|---|---|---|
| RSA | 1024 (usang), 2048, 3072, 4096 | Enkripsi, tanda tangan digital |
| DSA | 1024 (usang), 2048, 3072 | Tanda tangan digital |
| DH | 2048, 3072, 4096 | Pertukaran kunci |
| ECDH | 224, 256, 384, 521 | Pertukaran kunci |
| ECDSA | 224, 256, 384, 521 | Tanda tangan digital |
Infrastruktur kunci publik: Dalam AKC, kunci privat harus dijaga kerahasiaannya oleh pemilik sementara kunci publik dibagikan. Harus ada mekanisme aman untuk mengelola dan mendistribusikan kunci publik ini antar pengguna. Infrastruktur kunci publik (PKI) menyediakan cara untuk melakukan ini menggunakan sertifikat digital. Sertifikat digital memberikan bukti identitas pemilik kunci publik dan diterbitkan oleh otoritas tepercaya seperti otoritas sertifikat (yang merupakan bagian dari PKI). Karenanya, PKI memainkan peran integral dalam keamanan aplikasi modern yang menggunakan AKC dengan memungkinkan manajemen kunci berskala besar (dengan membuat, mengelola, mendistribusikan, dan mencabut sertifikat digital).
Risiko keamanan terhadap kriptografi kunci asimetrisβ
Seperti yang diuraikan dalam tabel di atas, algoritma kunci asimetris modern seperti RSA biasanya menggunakan ukuran kunci yang jauh lebih besar daripada pasangan kunci simetris yang umum digunakan seperti AES-128. Bahkan protokol berbasis ECC (ECDH dan ECDSA) yang memiliki ukuran kunci lebih kecil menggunakan minimal setidaknya 224 bit untuk kunci. Ini pada gilirannya menyiratkan bahwa serangan brute force yang melibatkan pencarian menyeluruh di ruang kunci privat untuk mengidentifikasi kunci yang benar tidak dapat dilakukan secara komputasi di masa mendatang. Ini tetap berlaku bahkan jika komputer kuantum digunakan untuk tugas ini. Oleh karena itu, serangan terhadap AKC biasanya berfokus pada mengeksploitasi kelemahan potensial lain dari kriptosistem tertentu. Beberapa mode serangan yang terdokumentasi dengan baik menargetkan:
-
Kelemahan algoritmik dengan menggunakan sarana matematis dan komputasi yang canggih untuk melemahkan asumsi kekerasan yang digunakan untuk merumuskan algoritma kunci asimetris. Misalnya, keamanan RSA didasarkan pada kesulitan memfaktorkan bilangan prima besar, dan kemajuan komputasi terbaru telah memungkinkan faktorisasi kunci RSA 829-bit yang berhasil. Oleh karena itu, RSA 1024-bit saat ini sudah usang. Seperti yang akan dibahas nanti, risiko utama yang ditimbulkan komputer kuantum pada AKC juga masuk dalam kategori ini.
-
Keacakan yang tidak sempurna, yang dapat menyebabkan kelemahan dalam proses pembuatan kunci. Misalnya, jika generator angka acak yang digunakan untuk membuat kunci cacat dan menghasilkan kunci yang tidak benar-benar acak, penyerang mungkin bisa memprediksi kunci tersebut.
-
Cacat implementasi seperti kesalahan dalam implementasi algoritma kriptografi yang secara tidak sengaja mengungkapkan informasi tentang kunci. Misalnya, padding yang salah berpotensi mengungkapkan detail tentang kunci.
-
Side channel yang mengacu pada kebocoran informasi dari sistem fisik yang menjalankan kriptografi. Kebocoran seperti itu bisa berupa informasi waktu, konsumsi daya, atau bahkan suara, yang bisa dieksploitasi dalam apa yang disebut serangan side-channel. Misalnya, menganalisis berapa lama operasi kriptografi membutuhkan waktu untuk dijalankan dapat mengungkapkan jumlah '1' dalam kunci biner. Kebocoran yang tampaknya tidak berbahaya ini secara signifikan mempersempit ruang pencarian, mengungkap solusi potensial untuk masalah yang awalnya tampak tidak dapat diatasi.
-
Pertukaran kunci dengan mencegat kunci saat sedang dipertukarkan, seperti dalam serangan man-in-the-middle (MITM). Protokol DH rentan terhadap serangan MITM jika langkah autentikasi tambahan tidak disertakan.
-
Penyimpanan kunci dengan bertujuan mencuri kunci dari penyimpanan yang tidak aman. Ini termasuk serangan fisik seperti manipulasi atau pencurian perangkat penyimpanan.
Mengamankan kriptosistem kunci asimetris dari berbagai serangan yang mungkin terjadi adalah tugas yang signifikan yang melibatkan pertimbangan matematis, perangkat keras, perangkat lunak, logistis, dan hukum.
RSAβ
Algoritma RSA (Rivest-Shamir-Adleman) adalah salah satu kriptosistem kunci publik pertama dan banyak digunakan untuk transmisi data yang aman. Ini adalah kriptosistem serbaguna karena menyediakan operasi yang diperlukan untuk mengaktifkan enkripsi, dekripsi, tanda tangan digital, dan pertukaran kunci dalam satu kerangka kerja yang umum.
Di bagian ini, kita akan mengilustrasikan kriptografi kunci asimetris (AKC) menggunakan RSA melalui contoh-contoh sederhana.
Kita akan menggunakan skenario standar dua pihak, Alice dan Bob, yang ingin berkomunikasi secara aman menggunakan AKC.
Algoritma RSAβ
Algoritma RSA dasar melibatkan empat operasi: pembuatan kunci, distribusi kunci, enkripsi, dan dekripsi:
-
Pembuatan kunci:
Kunci publik dan privat dibuat berdasarkan prinsip matematis seputar bilangan prima, di mana menghitungnya mudah, tapi kebalikannya sulit.
Kita akan menyebut ini:
- Kunci publik:
- Kunci privat:
Perhatikan bahwa umum untuk kunci publik dan kunci privat, dan dikenal sebagai modulus. Kita akan perlu menggunakan ini nanti.
Detail matematika
- Pilih dua bilangan prima yang berbeda, dan .
- dipilih secara acak (untuk keamanan).
- Mereka harus berukuran serupa, tapi berbeda panjangnya beberapa digit, untuk mempersulit faktorisasi.
- Bilangan prima bisa dipilih secara efisien menggunakan uji primalitas.
- Hitung .
- adalah modulus untuk kunci publik dan privat.
- Hitung totient .
- Totient dimaksudkan untuk dijaga kerahasiaannya dan biasanya dibuang setelah pembuatan kunci.
- Pilih bilangan bulat sedemikian sehingga dan .
- yaitu, dan harus koprim.
- Bilangan ini membentuk eksponen kunci publik dan biasanya dipilih sebagai bilangan kecil untuk efisiensi komputasi.
- Bilangan prima sering digunakan.
- Hitung untuk memenuhi relasi kongruensi .
- Yaitu, adalah invers multiplikatif dari modulo .
- Ini lebih efisien dihitung menggunakan algoritma Euclidean yang diperluas.
- Bilangan ini adalah eksponen kunci privat.
- Kunci publik terdiri dari , dan kunci privat adalah .
-
Distribusi kunci:
- Kunci publik dipublikasikan ke mereka yang mungkin ingin mengirim pesan
- Kunci privat dijaga kerahasiaannya.
-
Enkripsi:
- Alice ingin mengirim pesan ke Bob. Dalam hal ini bilangan bulat sederhana
- Alice menggunakan kunci publik Bob untuk mengenkripsi pesan menjadi ciphertext
Detail matematika
- adalah bilangan bulat .
- , di mana adalah ciphertext.
-
Dekripsi:
- Bob menerima ciphertext
- Bob menggunakan kunci privatnya untuk mendekripsi pesan kembali menjadi pesan
Detail matematika
- .
Ini adalah garis besar dasar RSA. Dalam praktiknya, skema padding yang lebih canggih diterapkan pada teks biasa sebelum enkripsi untuk memastikan bahwa teks biasa yang sama menghasilkan ciphertext yang berbeda. Ini mencegah berbagai kemungkinan serangan terhadap implementasi RSA yang naif dan memungkinkan keamanan semantis.
Ilustrasi RSA dalam Pythonβ
Dalam sel kode berikut, kita mengilustrasikan contoh sederhana algoritma RSA menggunakan bilangan bulat kecil dan kemudian mendemonstrasikan distribusi kunci praktis dan aplikasi tanda tangan digital menggunakan pustaka Python yang mengimplementasikan RSA.
Catatan: Di bagian ini kita akan menampilkan perhitungan matematika secara detail sebagai bagian dari kode Python
Pembuatan kunci RSAβ
Mari kita telusuri contoh sederhana algoritma RSA menggunakan bilangan prima kecil.
Kita perlu bisa menghitung pembagi bersama terbesar dari dua bilangan bulat, karena itu akan diperlukan untuk menguji apakah dua bilangan bulat bersifat koprim.
Kita akan menjelaskan satu cara sederhana untuk menghitung ini, tapi jauh lebih efisien dengan bilangan bulat yang lebih besar untuk menggunakan fungsi python math.gcd.
# Added by doQumentation β required packages for this notebook
!pip install -q cryptography
import math
# Example function to compute the gcd (greatest common divisor)
def gcd(a, b):
if b == 0:
return a
else:
return gcd(b, a % b)
# let's calculate some examples using algorithm
n1 = gcd(50, 10)
n2 = gcd(99, 33)
n3 = gcd(59, 9)
# do the same with the python library call
m1 = math.gcd(50, 10)
m2 = math.gcd(99, 33)
m3 = math.gcd(59, 9)
# Confirm they are the same
assert n1 == m1
assert n2 == m2
assert n3 == m3
# They are - print out the values for explanation
print("gcd(50,10) =", m1)
print("gcd(99,33) =", m2)
print("gcd(59,9) =", m3)
Fase pertama alur kerja RSA adalah pembuatan kunci. Ini dimulai dengan memilih dua bilangan prima, yang dimaksudkan untuk dijaga kerahasiaannya oleh entitas yang membuat kunci.
# Choosing two prime numbers and keep them secret
p = 13
q = 19
print("The secret prime numbers p and q are:", p, q)
Selanjutnya, modulus , yang merupakan hasil kali dari dua prima yang dipilih, dihitung. Modulus ini akan dipublikasikan sebagai bagian dari kunci publik.
# Calculate n which is the modulus for both the public and private keys
n = p * q
print("modulus n (p*q)=", n)
Fungsi totient Euler dihitung berikutnya, karena diperlukan untuk operasi invers multiplikatif modular yang digunakan untuk menentukan kunci dalam RSA. juga dijaga kerahasiaannya dan biasanya dibuang setelah pembuatan kunci.
# Compute Euler's totient function, Ο(n) and keep it secret
phi = (p - 1) * (q - 1)
print("The secret Euler's function (totient) [phi(n)]:", phi)
Kita sekarang siap untuk menghitung kunci publik dan privat. Dalam RSA, masing-masing ditentukan oleh tuple dua bilangan bulat. Entri pertama dalam setiap tuple adalah bilangan bulat yang berbeda, dan entri kedua adalah modulus yang umum untuk kedua kunci.
Entri pertama dalam kunci publik bisa berupa bilangan bulat apa pun yang lebih besar dari 1 yang koprim dengan . Dua bilangan bulat bersifat koprim jika pembagi bersama terbesar mereka adalah 1. Jadi kita menggunakan fungsi math.gcd untuk menemukan bilangan bulat yang koprim dengan .
# Choose an integer e such that e and Ο(n) are coprime
e = 2
while e < phi:
if math.gcd(e, phi) == 1:
break
else:
e += 1
print("Public Key (e):", e)
Kunci privat membutuhkan bilangan bulat , yang merupakan invers multiplikatif dari modulo ; yaitu, memenuhi relasi kongruensi . Untuk ilustrasi sederhana ini di mana kita berurusan dengan bilangan bulat kecil, kita cukup mengulang bilangan bulat positif untuk menemukan yang sesuai. Dalam pengaturan realistis, algoritma Euclidean yang diperluas yang efisien secara komputasi digunakan untuk tujuan ini.
# Compute a value for d such that (d * e) % Ο(n) = 1
d = 1
while True:
if (d * e) % phi == 1:
break
else:
d += 1
print("Private Key (d):", d)
Kita sekarang membentuk tuple , yang masing-masing membentuk kunci publik dan privat. Kunci publik kemudian dipublikasikan, sementara kunci privat dijaga kerahasiaannya.
# Public and Private Key pair
public = (e, n)
private = (d, n)
print(f"The Public key is {public} and Private Key is {private}")
Enkripsi dan dekripsi dalam RSA menggunakan operasi eksponensiasi modular. Selanjutnya, kunci publik dan privat saling melengkapi dalam hal salah satu bisa digunakan untuk mengenkripsi pesan yang kemudian bisa didekripsi oleh yang lain.
Di sini kita mengilustrasikan kasus di mana kunci publik digunakan untuk enkripsi dan kunci privat digunakan untuk dekripsi dengan mendefinisikan fungsi Python untuk setiap operasi.
Kita kemudian mengenkripsi dan mendekripsi pesan bilangan bulat .
# Encryption function
def encrypt(plain_text):
return (plain_text**e) % n
# Decryption function
def decrypt(cipher_text):
return (cipher_text**d) % n
# Simple message to encode
msg = 9
# encrypt then decrypt
enc_msg = encrypt(msg)
dec_msg = decrypt(enc_msg)
print("Original Message:", msg)
print("Encrypted Message:", enc_msg)
print("Decrypted Message:", dec_msg)
Meskipun bilangan bulat kecil yang digunakan di atas berguna untuk dengan mudah menguraikan ide-ide inti dalam algoritma RSA, dalam aplikasi nyata RSA membutuhkan penggunaan bilangan bulat yang sangat besar. Misalnya, RSA 2048-bit melibatkan penggunaan modulus yang panjangnya 2048 bit, setara dengan bilangan bulat desimal yang sekitar 10. Angka-angka yang sangat besar ini diperlukan untuk keamanan praktis RSA.
Pertukaran kunci simetris dengan RSAβ
Seperti yang dibahas sebelumnya, AKC memungkinkan dua pihak yang ingin berkomunikasi untuk menetapkan secara aman sebuah rahasia bersama, yang bisa digunakan, misalnya, sebagai kunci rahasia untuk enkripsi simetris teks biasa dalam jumlah besar berikutnya.
Mari kita pertimbangkan skenario berikut. Alice dan Bob ingin menggunakan SKC untuk mengenkripsi dan mendekripsi pesan. Namun, sebelum proses ini bisa diinisialisasi, mereka perlu menyepakati kunci rahasia bersama. Salah satu opsi adalah satu pihak β katakanlah, Alice β menghasilkan kunci rahasia dan kemudian mengirimkannya secara aman ke Bob. Untuk mencapai transfer yang aman ini, Alice memutuskan untuk menggunakan RSA sebagai mekanisme enkapsulasi kunci (KEM).
Ini melibatkan langkah-langkah berikut:
- Pertama, Alice menghasilkan kunci simetris acak, yang ingin dia bagikan dengan Bob.
- Kemudian, Bob menghasilkan pasangan kunci asimetris dan membuat kunci publiknya tersedia di saluran yang sesuai.
- Selanjutnya, Alice menggunakan kunci publik Bob untuk mengenkripsi kunci simetris, sehingga mengenkapsulasi dalam sebuah ciphertext.
- Kemudian, Alice menyiarkan ciphertext melalui saluran yang dapat diandalkan tapi tidak harus aman.
- Akhirnya, Bob menerima ciphertext dan mendekripsinya menggunakan kunci privatnya. Dia sekarang memiliki akses ke kunci simetris yang dibuat oleh Alice.

Gambar 1. Pertukaran kunci simetris dengan RSA
Contoh pertukaran kunci berbasis padding dalam Pythonβ
Alur kerja praktis yang menggunakan RSA untuk pertukaran kunci non-interaktif berbasis padding kini diilustrasikan menggunakan pustaka Python cryptography.
Impor modul yang diperlukan dari pustaka Python cryptography. Jika diperlukan, pustaka ini bisa diinstal menggunakan perintah pip install cryptography.
Alice kemudian menghasilkan kunci rahasia acak, yang ingin dia kirimkan ke Bob.
# pip install cryptography
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
symmetric_key = Fernet.generate_key()
print(f"\nSymmetric key generated by Alice: {symmetric_key}")
Menggunakan modul rsa dari pustaka cryptography, Bob menghasilkan pasangan kunci lalu menyiarkan kunci publiknya. Siapa pun bisa mencegat kunci publik dan membaca bilangan publik yang membentuk kunci tersebut.
# Bob generates a 2048-bit RSA key pair
bob_private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
bob_public_key = bob_private_key.public_key()
print(f"Public key broadcast by Bob: {bob_public_key}")
print(f"\nPublic numbers in Bobs' public key: {bob_public_key.public_numbers()}")
Pada titik ini, kita asumsikan Alice telah menerima kunci publik yang disiarkan oleh Bob. symmetric_key Alice di atas sekarang bisa dienkripsi menggunakan kunci publik Bob untuk menghasilkan ciphertext. Dalam pengaturan realistis, Alice juga akan menggunakan metode padding tambahan seperti OAEP untuk memastikan keamanan semantis untuk komunikasinya dengan Bob.
# Encryption
ciphertext = bob_public_key.encrypt(
symmetric_key,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
),
)
print("Ciphertext:", ciphertext)
Alice kemudian menyiarkan ciphertext melalui saluran terbuka, yakin bahwa hanya Bob dengan kunci privat yang sesuai yang bisa mendekripsinya. Kita asumsikan Bob telah menerima ciphertext dan sekarang bisa mendekripsinya menggunakan kunci privat rahasianya.
# Bob decrypts ciphertext to access the symmetric key
decrypted_symmetric_key = bob_private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
),
)
print("Decrypted key:", decrypted_symmetric_key)
assert decrypted_symmetric_key == symmetric_key
Pada titik ini, Alice dan Bob keduanya memiliki akses ke kunci simetris rahasia, yang bisa mereka gunakan untuk aplikasi SKC.
Mensimulasikan Mekanisme Enkapsulasi Kunci dengan RSA dalam Pythonβ
Dalam alur kerja berikut, kita mengilustrasikan penggunaan RSA untuk mensimulasikan Mekanisme Enkapsulasi Kunci (KEM) di mana pesan rahasia acak yang cukup panjang dipertukarkan secara aman dan kemudian dikonversi menjadi rahasia bersama dengan panjang yang sesuai menggunakan KDF.
Sekali lagi Alice dan Bob ingin menetapkan rahasia bersama secara non-interaktif dan Alice adalah pihak yang menentukan rahasia mana yang digunakan.
Kita mulai dengan mengimpor beberapa pustaka Python yang diperlukan.
Bob kemudian menghasilkan pasangan kunci RSA-nya dan menyiarkan kunci publiknya.
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes
from os import urandom
# Bob's RSA key pair
private_key_Bob = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key_Bob = private_key_Bob.public_key()
print("Bob's private and public keys created")
Alice pertama-tama menghasilkan rahasia acak yang panjang dari mana rahasia bersama pada akhirnya akan diturunkan. Dalam KEM murni, rahasia yang panjang akan menjadi elemen acak dari struktur aljabar yang mendasari kriptosistem. Dalam kasus RSA 2048-bit, ini akan menjadi bilangan bulat acak modulo RSA modulus 2048-bit. Karena KEM murni seperti itu tidak memerlukan padding tambahan tapi dalam contoh ini kita hanya mensimulasikan KEM menggunakan RSA dan pustaka cryptography mengharuskan penggunaan padding saat mengenkripsi dengan RSA. Jadi kita akan menggunakan rahasia panjang yang agak lebih pendek yang tetap jauh lebih panjang dari kunci AES 256-bit standar.
Alice_long_secret = urandom(160) # A 160 byte or 1280 bit random message
print("Alice's secret created")
Selanjutnya Alice mengenkripsi rahasia panjang menggunakan kunci publik Bob dan rahasia terenkripsi dikomunikasikan ke Bob.
Alice_encrypted_secret = public_key_Bob.encrypt(
Alice_long_secret,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
),
)
print("Alice's secret encrypted")
Bob mendekripsi rahasia terenkripsi yang diterima dari Alice menggunakan kunci privatnya.
Bob_decrypted_secret = private_key_Bob.decrypt(
Alice_encrypted_secret,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
),
)
assert Alice_long_secret == Bob_decrypted_secret, "Secrets do not match!"
# if we get here they match
print("Secrets match")
Akhirnya baik Alice maupun Bob secara terpisah menerapkan Fungsi Derivasi Kunci (KDF) yang telah disepakati pada rahasia panjang untuk menurunkan kunci simetris.
Perhatikan bahwa prosesnya melibatkan protokol hashing dan penggunaan salt acak yang memastikan keunikan dan ketidakpastian kunci simetris bersama jika rahasia panjang pernah digunakan kembali (tidak disarankan). Namun salt itu sendiri tidak harus rahasia dan setelah dibuat secara acak, katakanlah oleh Alice dalam contoh ini, bisa disiarkan ke Bob bersama rahasia panjang yang terenkripsi.
Kita akan mengasumsikan bahwa baik Alice maupun Bob memiliki akses ke salt acak yang sama.
def key_derivation_function(secret, salt):
hkdf = HKDF(
algorithm=hashes.SHA256(),
length=32, # Desired key length
salt=salt,
info=None,
backend=None,
)
return hkdf.derive(secret)
common_salt = urandom(16) # Random salt accessible to both Alice and Bob
symmetric_key_Alice = key_derivation_function(Alice_long_secret, common_salt)
symmetric_key_Bob = key_derivation_function(Bob_decrypted_secret, common_salt)
assert symmetric_key_Alice == symmetric_key_Bob, "Derived keys do not match!"
print(
f"A symmetric key of length {len(symmetric_key_Alice)*8} bits was successfully derived by both Alice and Bob!"
)
Tanda tangan digital dengan RSAβ
Kita sekarang akan memperluas skenario komunikasi rahasia di atas antara Alice dan Bob ke skenario yang juga menyertakan validasi dengan bantuan tanda tangan digital.
Seperti sebelumnya, Alice akan secara rahasia mengirim pesan yang mengenkapsulasi kunci simetris ke Bob, tapi dia juga akan menandatangani pesan secara digital sehingga Bob, setelah menerima pesan, bisa memverifikasi bahwa itu Alice yang berasal darinya dan bahwa isi pesan tidak dirusak selama transmisi.
Secara lebih umum, diinginkan untuk memungkinkan validasi tanpa mengorbankan kerahasiaan di mana pihak mana pun bisa memverifikasi integritas, keaslian, dan menetapkan non-repudiation terkait komunikasi tertentu, bahkan jika pihak tersebut tidak memiliki akses ke pesan teks biasa yang sebenarnya.
Kita akan mempertimbangkan pengaturan umum ini yang kemudian melibatkan langkah-langkah berikut:
- Pertama, baik Bob maupun Alice membuat kunci publik mereka tersedia melalui saluran terbuka.
- Kemudian, Alice mengenkripsi teks biasa menggunakan kunci publik Bob, membuat ciphertext.
- Selanjutnya, Alice membuat hash dari ciphertext dengan sebuah fungsi hash dan lebih lanjut mengenkripsi ciphertext yang di-hash menggunakan kunci privatnya. Hash terenkripsi ini adalah tanda tangan.
- Kemudian, Alice kemudian mengirimkan ciphertext dan tanda tangan melalui saluran terbuka.
- Kemudian, Bob menggunakan kunci publik Alice untuk mendekripsi tanda tangan, mengungkapkan ciphertext yang di-hash.
- Selanjutnya, karena Bob juga memiliki akses ke ciphertext itu sendiri, dia menggunakan fungsi hash yang sama yang digunakan Alice untuk membuat instance kedua dari ciphertext yang di-hash. Jika yang terakhir cocok dengan yang diperoleh dengan mendekripsi tanda tangan Alice, maka pesan telah divalidasi, meskipun ciphertext itu sendiri belum didekripsi.
- Akhirnya, Bob, setelah memvalidasi pesan, mendekripsi ciphertext menggunakan kunci privatnya sendiri.

Gambar 2. Tanda tangan digital dengan RSA
Alur kerja untuk tanda tangan digital ini diilustrasikan berikutnya.
Kita sekali lagi mengimpor beberapa modul berguna dari pustaka cryptography.
Seperti sebelumnya, Alice bermaksud untuk secara aman mengirim kunci simetris ke Bob, tapi dia juga ingin menandatanganinya secara digital. Dalam hal ini, kita membutuhkan kunci publik untuk baik Alice maupun Bob. Oleh karena itu, langkah pertama adalah baik Alice maupun Bob membuat pasangan kunci mereka sendiri menggunakan RSA dan menyiarkan kunci publik mereka sendiri ke dunia.
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding, rsa
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
# Generate keys for Bob
bob_private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
bob_public_key = bob_private_key.public_key()
# Generate keys for Alice
alice_private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
alice_public_key = alice_private_key.public_key()
print("Private and Public keys generated for Bob and Alice.")
Pada langkah berikutnya, seperti sebelumnya, Alice menggunakan kunci publik Bob untuk mengenkripsi kunci simetris dan menyiapkan ciphertext.
# Alice encrypts the message using Bob's public key
ciphertext = bob_public_key.encrypt(
symmetric_key,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
),
)
print("ciphertext of symmetric key: ", ciphertext)
Pada tahap ini, alih-alih hanya menyiarkan ciphertext, Alice bermaksud untuk melampirkan tanda tangan digital ke dalamnya sehingga dia bisa membuktikan kepada Bob bahwa dia adalah pengirim pesan. Ini dilakukan dalam dua langkah:
- Buat hash dari ciphertext menggunakan algoritma hashing.
- Enkripsi hash menggunakan kunci privat Alice, yang merupakan sebuah tanda tangan.
# Alice signs the ciphertext using her private key
digest = hashes.Hash(hashes.SHA256())
digest.update(ciphertext)
hash_to_sign = digest.finalize()
signature = alice_private_key.sign(
hash_to_sign,
padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
Prehashed(hashes.SHA256()),
)
print("signature: ", signature)
Alice kemudian menyiarkan ciphertext dan tanda tangan melalui jaringan sehingga Bob bisa mencegat keduanya.
# Bob receives the ciphertext and signature
received_ciphertext = ciphertext
received_signature = signature
# Send signature and ciphertext here
print("Sending ciphertext and signature.....")
Di sisi Bob, tugas pertama adalah memverifikasi integritas dan keaslian ciphertext. Untuk melakukan ini, Bob membuat hash dari ciphertext yang diterima menggunakan algoritma hashing yang sama yang digunakan Alice.
# Bob creates a hash of the ciphertext using the same algorithm used by Alice
digest = hashes.Hash(hashes.SHA256())
digest.update(received_ciphertext)
hash_to_verify = digest.finalize()
print("hash to verify: ", hash_to_verify)
Kemudian, Bob mendekripsi tanda tangan yang diterima menggunakan kunci publik Alice. Karena Alice menggunakan kunci privatnya untuk membuat tanda tangan, Bob bisa mendekripsinya menggunakan kunci publik Alice. Tanda tangan yang didekripsi tidak lain adalah hash dari ciphertext yang dibuat di sisi Alice. Jika hash yang dibuat oleh Bob cocok dengan tanda tangan yang didekripsi, maka Bob telah memverifikasi bahwa ciphertext yang dia terima tidak dirusak dan bahwa itu Alice yang menandatangani ciphertext tersebut.
Dalam kode Python di bawah ini, operasi-operasi ini digabungkan ke dalam fungsi utilitas berguna yang disebut verify yang disediakan oleh objek yang terkait dengan kunci publik Alice.
from cryptography.exceptions import InvalidSignature
def is_signature_valid(public_key, signature, data_hash):
try:
public_key.verify(
signature,
data_hash,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH
),
Prehashed(hashes.SHA256()),
)
return True
except InvalidSignature:
return False
if is_signature_valid(alice_public_key, received_signature, hash_to_verify):
print("The signature is valid.")
else:
print("The signature is not valid.")
Setelah memverifikasi integritas dan keaslian ciphertext yang diterima, Bob kemudian bisa mendekripsinya menggunakan kunci privatnya karena Alice membuat ciphertext menggunakan kunci publik Bob.
# Bob decrypts the message using his private key
decrypted_message = bob_private_key.decrypt(
received_ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
),
)
print("Decrypted message:", decrypted_message.decode())
Dalam skenario tanda tangan digital di atas, pihak mana pun β bukan hanya Bob β bisa memverifikasi bahwa Alice adalah pengirim ciphertext karena semua orang bisa mengakses kunci publik Alice, ciphertext, dan tanda tangan digital. Selanjutnya, setelah mengirim ciphertext dan tanda tangan, Alice tidak bisa kemudian menyangkal telah melakukannya karena tanda tangan bisa didekripsi menjadi hash yang bermakna hanya menggunakan kunci publiknya. Ini menetapkan non-repudiation.
Dengan memungkinkan distribusi kunci yang aman dan mendukung non-repudiation, kriptografi kunci publik menetapkan fondasi yang kuat untuk komunikasi digital yang aman.
Membobol RSAβ
Kegunaan dan keamanan algoritma RSA yang diuraikan di atas bertumpu pada dua asumsi matematis:
-
Mencari invers perkalian modular dengan hanya memiliki akses ke secara komputasi tidak layak dilakukan.
-
Dalam konteks RSA, operasi eksponen modular berperilaku seperti fungsi trapdoor satu arah. Ketika digunakan untuk enkripsi, fungsi ini menghasilkan ciphertext yang tidak terbaca, dan tanpa akses ke kunci privat, membalikkan operasi untuk memulihkan teks biasa dari ciphertext tidaklah layak. Namun, dengan akses ke kunci privat yang bertindak sebagai trapdoor, ciphertext dapat dengan mudah didekripsi.
Serangan paling menonjol terhadap algoritma RSA bertujuan merusak asumsi 1 dengan cara memulihkan nomor kunci privat secara efisien melalui pemfaktoran modulus . Seperti yang akan diilustrasikan di bawah, mudah untuk memulihkan jika seseorang memiliki akses ke faktor prima dan dari atau totient . Ingatlah bahwa , , dan disimpan sebagai rahasia selama pembuatan kunci dan dibuang setelahnya. Pihak ketiga yang memulihkan informasi ini menggunakan komputer klasik atau kuantum pada dasarnya mengungkap kunci privat, sehingga membobol RSA. Oleh karena itu, faktorisasi prima adalah primitif komputasi kunci yang diperlukan untuk membobol RSA.
Komputasi klasik dan RSAβ
Faktorisasi prima dari bilangan bulat besar diketahui memiliki skalabilitas super-polinomial atau subeksponensial pada komputer klasik. Algoritma klasik terbaik yang diketahui untuk memfaktorkan bilangan bulat lebih besar dari adalah general number field sieve (GNFS)
Detail matematika
sebagai fungsi dari bilangan bulat yang akan difaktorkan.
Skalabilitas ini bersifat super-polinomial dalam jumlah bit yang diperlukan untuk merepresentasikan .
Oleh karena itu, faktorisasi prima dianggap tidak efisien pada komputer klasik.
Saat ini, bilangan bulat terbesar yang difaktorkan pada perangkat keras klasik berada dalam kisaran 829 bit atau 250 digit desimal. Mengingat pertumbuhan eksponensial dalam daya komputasi klasik yang telah diamati selama beberapa dekade terakhir, RSA 1024-bit tidak lagi dianggap aman dalam waktu dekat dan kini sudah tidak digunakan. Meskipun demikian, di masa mendatang yang dapat terlihat, memfaktorkan bilangan bulat 2048-bit yang besarnya berada dalam kisaran saat ini dianggap tidak layak pada sistem klasik, yang mengisyaratkan kelanjutan kegunaannya. Namun, hadirnya komputer kuantum membatalkan penilaian ini.
Algoritma kuantum Shor dan RSAβ
Algoritma kuantum yang mungkin paling terkenal saat ini adalah algoritma Shor untuk menemukan faktor prima dari bilangan bulat. Ketika diperkenalkan oleh Peter Shor pada tahun 1994, algoritma ini diakui sebagai algoritma kuantum pertama yang menawarkan percepatan super-polinomial relatif terhadap algoritma klasik pada masalah yang sangat penting secara praktis, yaitu faktorisasi prima.
Algoritma Shor dapat memfaktorkan prima dengan di mana adalah jumlah bit.
Penjelasan matematis algoritma Shor
Dalam konteks RSA, algoritma Shor bekerja dengan memanfaatkan periodisitas dari fungsi eksponensial modular dan menyediakan primitif pencarian periode kuantum yang memungkinkan faktorisasi prima yang efisien dari modulus .
Gambaran garis besar tingkat tinggi yang disederhanakan dari skema Shor secara keseluruhan untuk membobol RSA adalah sebagai berikut:
-
Diberikan modulus , yang dipublikasikan sebagai bagian dari kunci publik, pilih sebuah angka yang koprima terhadap , yaitu, . Karena kita tahu bahwa memiliki tepat dua faktor prima , hampir semua angka lebih kecil dari yang kita pilih secara acak kemungkinan besar akan koprima terhadap .
-
Setelah memilih , temukan eksponen sehingga . Ini berarti . Keberadaan sebuah eksponen sehingga kongruensi di atas terpenuhi dijamin oleh sifat periodisitas dari eksponen modular.
-
Jika genap, untuk suatu bilangan bulat . Sisi kiri dari kesamaan tersebut harus mengandung dan sebagai dua faktor primanya karena sisi kanan juga demikian. Jika ganjil, kembali ke langkah 1 dan coba pilihan yang berbeda untuk .
-
Gunakan algoritma Euclid yang diperluas untuk mencari atau . GCD yang dihitung kemungkinan besar akan mengidentifikasi salah satu faktor prima atau . Bagi dengan faktor prima ini untuk memulihkan yang lainnya.
-
Setelah diketahui, gunakan langkah-langkah dari algoritma RSA asli untuk merekonstruksi totient dan menghasilkan nomor kunci privat sebagai invers modular dari nomor kunci publik yang diketahui.
Pada Agustus 2023, Oded Regev mempublikasikan peningkatan atas versi asli Shor menggunakan pendekatan multi-dimensi yang menghasilkan . Penelitian lebih lanjut terus dilakukan, termasuk oleh Ragavan dan Vaikuntanathan di bidang ini yang mungkin meningkatkan waktu, biaya, atau jumlah qubit yang dibutuhkan. Meskipun kita tidak dapat mengatakan kapan menjalankan algoritma semacam itu terhadap enkripsi RSA dunia nyata benar-benar menjadi layak, hal tersebut semakin dekat dari waktu ke waktu.
Contoh Python yang mendemonstrasikan pembobol enkripsi RSAβ
Dalam sel kode berikut, kita mengilustrasikan contoh pencarian kunci privat hanya dengan diberikan kunci publik. Ini akan menggunakan komputasi klasik dengan brute-force, tetapi menunjukkan bagaimana algoritma Shor bisa digunakan β termasuk untuk kunci yang besar.
Di bagian ini kita akan menampilkan kalkulasi matematis secara detail sebagai bagian dari kode Python
Dalam contoh ini, kita memiliki kunci publik , dan kita akan memulihkan kunci privat.
Langkah 1: Langkah pertama adalah memilih angka yang koprima terhadap 247. Hampir semua angka yang kita tebak akan cocok. Mari pilih 6.
n = 247 # the modulus
e = 5 # public key number
a = 6 # an integer coprime to n
assert gcd(a, n) == 1
print(f"Checked {n} and {a} are coprime")
Langkah 2: Selanjutnya kita perlu menemukan periode sehingga . Dalam contoh ini, kita menghitung secara klasik menggunakan brute force, tetapi kita juga bisa menggunakan algoritma Shor pada komputer kuantum menggunakan Qiskit.
r = 0
rem = 100
while rem != 1:
r += 1
rem = (a**r) % n
print(f"period r is: {r}")
assert a**r % n == 1
print(f"Checked {a}^{r} mod {n} is 1")
Langkah 3: Karena periode adalah genap, kita dapat menghitung .
# explicitly use as integer
f1 = int(a ** (r / 2) - 1)
f2 = int(a ** (r / 2) + 1)
print(f"f1 = {f1}")
print(f"f2 = {f2}")
Langkah 4: Temukan GCD dari salah satu faktor tersebut dengan . Cukup bagi dengan faktor prima yang sudah ditemukan untuk mendapatkan faktor prima kedua.
q_found = gcd(f1, n)
print(f"One possible prime factor of n ({n}) is: {q_found}")
# explicit int (to avoid floating point)
p_found = int(n / q_found)
print(f"The second prime factor of n ({n}) is: {p_found}")
assert n == p_found * q_found
Langkah 5: Setelah memulihkan faktor prima dari sebagai dan , kita menghitung totient .
Kunci privat adalah invers modular dari nomor kunci publik .
# Compute the totient
phi_found = (p_found - 1) * (q_found - 1)
print(f"The totient is: {phi_found}")
# Recover the private key number d_found by satisfying (d_found * e) % phi_found = 1
d_found = 1
while True:
if (d_found * e) % phi_found == 1:
break
else:
d_found += 1
print("Private Key number:", d_found)
Dalam skema di atas, langkah 2 adalah operasi pencarian periode yang krusial, di mana algoritma Shor menggunakan dua primitif kuantum fundamental, yaitu transformasi Fourier kuantum dan estimasi fase kuantum. Untuk penjelasan terperinci tentang aspek kuantum dari algoritma Shor, lihat pelajaran Estimasi fase dan pemfaktoran dalam Fundamentals of Quantum Algorithms. Langkah 1 dan 3 hingga 5 melibatkan operasi yang relatif murah dan dapat dengan mudah dilakukan pada komputer klasik.
Sebagai opsional, berikut adalah panduan visual terperinci untuk mengimplementasikan algoritma Shor.
Pada komputer kuantum, algoritma Shor dapat menunjukkan skalabilitas polilogatritmik sebaik dalam hal modulus , atau skalabilitas polinomial dalam hal jumlah bit yang diperlukan untuk merepresentasikan . Ini adalah percepatan super-polinomial dibandingkan dengan algoritma GNFS klasik.
Estimasi sumber daya terbaru menunjukkan bahwa berdasarkan asumsi tertentu mengenai konfigurasi perangkat keras, beberapa puluhan ribu hingga beberapa juta qubit akan diperlukan untuk membobol RSA 2048-bit menggunakan algoritma Shor. Tidak mustahil bahwa komputer kuantum dengan beberapa puluhan ribu qubit akan tersedia dalam beberapa tahun ke depan, membuat batas bawah estimasi sumber daya dapat dicapai.
Pertukaran kunci Diffie-Hellman dan Algoritma Tanda Tangan Digitalβ
Pada bagian sebelumnya, kita membahas kriptosistem RSA, yang keamanannya didasarkan pada kesulitan komputasional dari faktorisasi prima. Di sini, kita akan membahas dua protokol kriptografi kunci asimetris yang populer, pertukaran kunci Diffie-Hellman (DH) dan Algoritma Tanda Tangan Digital (DSA), keduanya didasarkan pada masalah matematis yang berbeda, yaitu masalah logaritma diskret (DLP).
Masalah logaritma diskretβ
Dalam persamaan berikut kita perlu menemukan hanya dengan diberikan ,,
Ini diyakini sulit dilakukan dengan komputer klasik karena penggunaan aritmetika modulo, dan oleh karena itu merupakan dasar matematis yang baik untuk algoritma enkripsi.
Ini dikenal sebagai masalah logaritma diskret (DLP).
Detail matematis dari masalah logaritma diskretβ
DLP biasanya dirumuskan dalam konteks grup siklik dan dinyatakan sebagai berikut.
Pertimbangkan sebuah grup siklik yang dibangkitkan oleh elemen grup dan diberikan elemen sembarang , temukan bilangan bulat sehingga .
Di sini bilangan bulat adalah logaritma diskret. Sifat siklik dari menjamin bahwa untuk setiap , bilangan bulat yang valid ada.
Untuk kriptografi, DLP pada grup multiplikatif dari bilangan bulat modulo bilangan prima yang dilambangkan ternyata berguna. Elemen dari adalah kelas kongruensi yang diberi label dengan bilangan bulat modulo yang koprima terhadap .
Misalnya:
Operasi perkalian pada grup-grup ini hanyalah perkalian bilangan bulat biasa diikuti dengan reduksi modulo dan eksponensiasi oleh bilangan bulat hanyalah perkalian berulang sebanyak kali dan reduksi modulo .
Mari kita ilustrasikan sebuah contoh DLP pada .
Grup multiplikatif ini memiliki dua generator yang juga dikenal sebagai akar primitif. Kita akan menggunakan sebagai generator; yaitu, membangkitkan setiap elemen dari menggunakan pangkat bilangan bulat berturut-turut dari 5.
#Generate elements of (Z_7)^{x} using generator [5].
g = 5
p = 7
print(f"Using generator {g}")
for k in range(3*p):
print(f"{g}**{k} mod {p} β‘ {(g**k)%7}")
Kita melihat bahwa dalam aritmetika modulo 7, memangkatkan 5 dengan pangkat bilangan bulat berturut-turut menghasilkan setiap elemen dari tepat sekali sebelum siklus berulang tanpa batas dengan periode .
Jadi DLP pada dengan generator [5] adalah:
.
Dari output sel Python di atas kita melihat bahwa:
Dalam aritmetika bilangan real biasa, eksponensiasi adalah fungsi yang monoton dan menemukan logaritma dari bilangan apa pun ke basis apa pun secara komputasi mudah. Sebaliknya, seperti yang terlihat jelas dari contoh sederhana di atas, eksponensiasi modular bersifat non-monoton, dan meskipun bersifat periodik dengan periode , selebihnya sangat tidak trivial. Jadi menghitung inversnya, logaritma diskret, ternyata tidak efisien untuk yang besar pada komputer klasik.
Pengamatan ini menjadi dasar dari pertukaran kunci Diffie-Hellman (DH) dan Algoritma Tanda Tangan Digital (DSA), yang dibahas di bagian berikutnya.
DLP dapat diperluas ke subgrup siklik sebagai berikut:
- Pertimbangkan yang didefinisikan di atas dan sebuah elemen berorde prima yaitu, .
- Himpunan pangkat bilangan bulat dari : adalah subgrup siklik dari dengan orde grup .
- Sebuah DLP dapat ditentukan pada dengan memilih dan meminta sehingga
Pertukaran kunci Diffie-Hellmanβ
Pada tahun 1976, Whitfield Diffie dan Martin Hellman mengusulkan protokol pertukaran kunci untuk memungkinkan pembuatan kunci rahasia bersama melalui saluran komunikasi yang tidak aman. Kunci rahasia tersebut kemudian dapat digunakan oleh pihak-pihak yang berbagi untuk enkripsi simetris. Algoritma ini bergantung pada DLP.

Gambar 1. Pertukaran kunci Diffie-Hellman
Detail matematis dari pertukaran kunci Diffie-Hellman
Dengan Alice dan Bob sebagai dua pihak yang berkomunikasi, protokolnya bekerja sebagai berikut:
- Pertama, Alice dan Bob sepakat tentang bilangan prima besar dan akar primitif atau generator .
- Kemudian, Alice memilih eksponen rahasia secara acak dengan dan menghitung . masing-masing adalah kunci privat dan publik Alice.
- Selanjutnya, Bob memilih eksponen rahasia secara acak dengan dan menghitung . masing-masing adalah kunci privat dan publik Bob.
- Kemudian, Alice mengirim ke Bob dan Bob mengirim ke Alice melalui saluran yang andal namun tidak harus aman.
- Lalu, Alice menggunakan yang diterimanya untuk menghitung kunci rahasia bersama .
- Terakhir, Bob sementara itu menggunakan yang diterimanya untuk menghitung kunci rahasia bersama .
Dengan protokol ini,
- Alice dan Bob dijamin mendapatkan kunci rahasia yang sama karena .
- Pihak ketiga yang mencegat atau tidak dapat membuat kunci rahasia karena mereka tidak memiliki akses ke atau masing-masing.
- Mengekstrak