Kriptografi kunci asimetrik
Dalam pelajaran ini kita akan melihat kriptografi kunci asimetrik yang menjadi asas kepada banyak interaksi rangkaian selamat pada hari ini.
Menjelang akhir pelajaran ini, kita akan telah membincangkan:
- Apa itu kriptografi kunci asimetrik
- Penggunaan kriptografi kunci asimetrik, termasuk pertukaran kunci dan tandatangan digital
- Keselamatan kriptografi kunci asimetrik secara umum
- Butiran lanjut tentang algoritma RSA, DSA dan Lengkung Eliptik serta keselamatannya
- Beberapa contoh kod Python yang menunjukkan cara algoritma ini berfungsi dalam praktik
- Ancaman kepada algoritma ini daripada komputer klasik mahupun komputer kuantum
Pengenalan kepada kriptografi kunci asimetrikβ
Seperti yang kita pelajari dalam pelajaran lepas, kriptografi kunci simetrik sangat pantas dan cekap untuk melindungi maklumat, tetapi ia mempunyai beberapa had:
- Apabila bilangan pihak yang ingin bertukar maklumat selamat bertambah, bilangan kunci yang diperlukan meningkat secara kombinatorial. Ia tidak menyediakan mekanisme untuk mengedarkan kunci ini secara selamat antara penghantar dan penerima.
- Tiada peruntukan untuk tanpa penolakan. Mana-mana pihak boleh menyahsulit atau menyulitkan mesej tanpa cara untuk menjamin bahawa mesej telah diterima atau daripada mana ia berasal
Penyelesaian kepada kedua-dua masalah ini disediakan oleh kriptografi kunci asimetrik (AKC), yang juga dikenali sebagai kriptografi kunci awam (PKC), yang oleh itu membentuk tonggak keselamatan digital moden.
Kriptografi kunci asimetrik (AKC) melibatkan penggunaan sepasang kunci β satu awam, satu peribadi. Kunci awam dan kunci peribadi dipautkan secara kriptografi dan biasanya dijana pada masa yang sama sebagai pasangan kunci menggunakan algoritma matematik khusus. Kunci awam, seperti yang dicadangkan oleh namanya, kemudiannya dimaksudkan untuk diedarkan secara bebas, manakala kunci peribadi disimpan secara rahsia oleh pihak yang menjana pasangan kunci. Keselamatan komunikasi yang menggunakan pasangan kunci asimetrik terjamin selagi kunci peribadi kekal sulit.

Rajah 1. Penyulitan Kunci Asimetrik
AKC menawarkan beberapa fungsi berguna, seperti:
- Penyulitan dan penyahsulitan untuk membolehkan kerahsiaan komunikasi.
- Tandatangan digital untuk memastikan kesahihan, integriti, dan tanpa penolakan.
- Pertukaran kunci selamat untuk memudahkan penggunaan sistem kripto simetrik seterusnya.
Dalam aplikasi moden, AKC digunakan terutamanya untuk tandatangan digital dan pertukaran kunci selamat. Dalam pelajaran ini, kita memperkenalkan dua fungsi utama ini, kemudian kita membincangkan beberapa variasi protokol kriptografi untuk fungsi-fungsi ini.
Pertukaran kunci dengan kriptografi kunci asimetrikβ
Salah satu masalah asas dalam kriptografi ialah pertukaran kunci secara selamat. Sebagai contoh, jika dua pihak ingin menggunakan penyulitan simetrik, kedua-dua pihak memerlukan kunci yang sama untuk menyulitkan dan menyahsulit mesej. Tetapi bagaimana mereka boleh menukar kunci itu secara selamat? Kriptografi kunci asimetrik menangani perkara ini melalui mekanisme pertukaran kunci interaktif dan bukan interaktif.
Pertukaran kunci interaktifβ
Protokol pertukaran kunci interaktif merujuk kepada kaedah di mana dua pihak bekerjasama untuk mencipta kunci rahsia dikongsi melalui saluran komunikasi yang tidak selamat. Kunci rahsia dikongsi ini kemudiannya boleh digunakan untuk tugas penyulitan dan penyahsulitan simetrik.
Yang paling terkenal dalam kalangan protokol sedemikian ialah algoritma Diffie-Hellman (DH), yang direka khusus untuk memudahkan pertukaran kunci. Dalam protokol ini, setiap pihak menjana sepasang kunci (awam dan peribadi) dan menyiarkan kunci awam mereka. Kemudian setiap pihak menggunakan kunci peribadi mereka sendiri dan kunci awam pihak lain untuk menjana kunci rahsia dikongsi. DH menggunakan prinsip aritmetik modular untuk memastikan kedua-dua pihak akhirnya mendapat rahsia dikongsi yang sama walaupun setiap pihak hanya mempunyai akses kepada kunci awam pihak lain.
Sistem kripto moden berdasarkan kriptografi lengkung eliptik (ECC) memperluaskan konsep ini dengan pertukaran kunci Diffie-Hellman lengkung eliptik (ECDH). ECDH berfungsi serupa dengan DH tetapi menggunakan sifat-sifat lengkung eliptik, menghasilkan sistem yang lebih selamat dan cekap.

Rajah 2. Protokol Pertukaran Kunci
Pertukaran kunci bukan interaktifβ
Tidak seperti protokol pertukaran kunci seperti DH dan ECDH yang bersifat interaktif, memerlukan komunikasi berulang-alik untuk menentukan kunci simetrik, AKC juga menyediakan cara bukan interaktif untuk mewujudkan kunci rahsia dikongsi. Dalam skim sedemikian, satu pihak menjana sepasang kunci (awam dan peribadi) dan berkongsi kunci awam dengan pihak lain. Pihak kedua ini kemudiannya menjana kunci simetrik rawak, menyulitkannya dengan kunci awam yang diterima, dan menghantar semula kepada pihak pertama. Pihak pertama menggunakan kunci peribadi mereka untuk menyahsulit mesej yang diterima, dengan itu mendapatkan kunci simetrik dikongsi. Skim ini bersifat bukan interaktif dalam erti kata kunci simetrik ditentukan oleh satu pihak dan hanya dikomunikasikan secara selamat kepada pihak lain dalam bentuk tersulitkan.
Pertimbangan penting dalam pertukaran kunci bukan interaktif berkaitan dengan perbezaan panjang dalam bit antara kunci simetrik yang ingin ditukar oleh pihak-pihak dan saiz mesej yang disyorkan dalam AKC. Biasanya, kunci simetrik moden berada dalam julat 128-256 bit, manakala sistem kripto kunci asimetrik seperti RSA berfungsi dengan saiz mesej sekitar 1024-4096 bit. Oleh itu, apabila menggunakan AKC untuk menghantar kunci simetrik, demi keselamatan ia tetap perlu dikodkan ke dalam mesej 1024-4096 bit yang lebih panjang. Ini boleh dicapai melalui dua pendekatan:
-
Pertukaran kunci berasaskan padding: Dalam pendekatan ini, kunci simetrik yang lebih pendek (128-256 bit) dijana dahulu kemudian skim padding boleh-balik yang dipersetujui seperti OAEP digunakan untuk membenamkannya ke dalam mesej yang lebih panjang (1024-4096 bit). Mesej yang lebih panjang ini disulitkan menggunakan AKC dan disiarkan sebagai ciphertext. Penerima mula-mula menyahsulit ciphertext kemudian mengalihkan padding untuk mengekstrak kunci simetrik yang lebih pendek.
-
Mekanisme enkapsulasi kunci (KEM): Dengan pertukaran kunci berasaskan KEM, mesej teks biasa rawak yang panjang (1024-4096 bit) dijana terlebih dahulu, dari mana kunci simetrik yang lebih pendek (128-256 bit) boleh diekstrak menggunakan fungsi terbitan kunci (KDF) yang dipersetujui. Teks biasa yang lebih panjang disulitkan menggunakan AKC dan disiarkan kepada penerima sebagai ciphertext. Penerima menyahkod ciphertext menggunakan kunci peribadi mereka kemudian menggunakan KDF untuk mengekstrak kunci simetrik yang lebih pendek (128-256 bit). Sistem kripto popular seperti RSA, dengan keupayaannya untuk menyulitkan data secara langsung, boleh digunakan untuk melaksanakan KEM.

Rajah 3. Mekanisme Enkapsulasi Kunci
Tandatangan digital dengan kriptografi kunci asimetrikβ
Tandatangan digital ialah satu lagi aplikasi kriptografi kunci asimetrik yang berkuasa. Ia menyediakan pengesahan, integriti, dan tanpa penolakan yang didayakan oleh hakikat bahawa dalam AKC, entiti memiliki kunci peribadi yang unik. Idea asas yang mendasari protokol tandatangan ialah penghantar mesej selamat akan menandatangani secara digital mesej tersebut menggunakan kunci peribadi unik mereka. Penerima kemudiannya akan mengesahkan tandatangan digital menggunakan kunci awam penghantar. Dalam AKC, tandatangan digital boleh dilaksanakan dengan menggunakan algoritma yang direka khusus untuk tujuan itu atau dengan menggunakan sistem kripto generik.

Rajah 4. Tandatangan digital dengan kriptografi kunci asimetrik
Algoritma tandatangan digital khususβ
Pada masa ini, Piawaian Pemprosesan Maklumat Persekutuan AS (FIPS) untuk tandatangan digital ialah skim khusus yang dinamakan mudah Algoritma Tandatangan Digital (DSA). Agak serupa dengan protokol Diffie-Hellman, DSA menggunakan sifat-sifat algebra daripada eksponen modular dan songsangan pendaraban untuk penjanaan dan pengesahan tandatangan.
Algoritma tandatangan digital lengkung eliptik (ECDSA) ialah varian ECC bagi DSA, menyediakan fungsi yang sama tetapi dengan kunci yang jauh lebih pendek. Ini menghasilkan kecekapan yang lebih baik, menjadikannya pilihan popular untuk sistem dengan kekangan sumber.
Kedua-dua DSA dan ECDSA akan diilustrasikan dengan lebih terperinci kemudian.
Skim tandatangan digital menggunakan sistem kripto generikβ
Selain daripada algoritma khusus, tandatangan digital juga boleh dijana menggunakan sistem kripto asimetrik generik, seperti RSA.
RSA, yang akan dibincangkan secara terperinci dalam bahagian kemudian, turut mengeksploitasi songsangan pendaraban modular dan pemangkatan modular sebagai operasi asas tetapi menggabungkannya dalam urutan yang berbeza daripada DSA. Dalam RSA, penandatangan biasanya mencipta hash mesej kemudian menyulitkan hash tersebut dengan kunci peribadi mereka, mencipta tandatangan digital. Mana-mana pihak kemudiannya boleh mengesahkan tandatangan ini dengan menyahsulitnya menggunakan kunci awam penandatangan dan membandingkannya dengan mesej yang di-hash.
Aplikasi kriptografi kunci asimetrikβ
Kriptografi kunci asimetrik adalah merata-rata dalam aplikasi teknologi digital moden. Fungsi asas AKC yang diterangkan di atas membentuk blok binaan banyak protokol aplikasi peringkat lebih tinggi, termasuk:
-
Komunikasi internet: Komunikasi selamat melalui internet, seperti HTTPS, sangat bergantung pada kriptografi kunci asimetrik. Transport Layer Security (TLS) dan pendahulunya, Secure Sockets Layer (SSL), menggunakan kriptografi kunci asimetrik semasa proses jabat tangan awal untuk mewujudkan kunci simetrik, yang kemudiannya digunakan untuk selebihnya sesi komunikasi.
-
Pengesahan: Kriptografi kunci asimetrik digunakan untuk mencipta tandatangan digital, membolehkan entiti mengesahkan dokumen atau mesej digital sebagai datang daripada penghantar tertentu. Ini digunakan dalam banyak senario, daripada mengesahkan kemas kini perisian kepada kontrak digital yang mengikat secara undang-undang.
-
Penyulitan e-mel: Protokol penyulitan e-mel seperti PGP (Pretty Good Privacy) dan alternatif sumber terbukanya GPG (GNU Privacy Guard) menggunakan kriptografi kunci asimetrik untuk memastikan hanya penerima yang dimaksudkan boleh membaca kandungan e-mel.
-
Secure shell (SSH): SSH ialah protokol untuk log masuk jauh yang selamat dan perkhidmatan rangkaian selamat lain melalui rangkaian yang tidak selamat. Ia menggunakan kriptografi kunci asimetrik untuk mengesahkan pelayan kepada klien dan, secara pilihan, klien kepada pelayan.
-
VPN (rangkaian peribadi maya): Penyulitan kunci asimetrik digunakan untuk mewujudkan sambungan selamat dalam VPN, memastikan komunikasi selamat melalui rangkaian awam.
-
Blokchain dan mata wang kripto: Teknologi blokchain, termasuk Bitcoin dan Ethereum, menggunakan kriptografi kunci asimetrik. Sebagai contoh, pemilikan Bitcoin diwujudkan melalui tandatangan digital menggunakan kriptografi kunci asimetrik.
-
Pihak berkuasa sijil: Kriptografi kunci asimetrik digunakan oleh pihak berkuasa sijil (CA) untuk mengeluarkan dan menandatangani sijil digital, yang digunakan dalam komunikasi TLS, penandatanganan kod, penyulitan e-mel, dan lain-lain. Sijil digital mengikat kunci awam kepada entiti tertentu (contohnya, seseorang atau pelayan).

Rajah 5. Mengeluarkan dan menandatangani sijil digital menggunakan kriptografi kunci asimetrik
Keselamatan kriptografi kunci asimetrikβ
Beberapa gagasan kriptografi bergabung untuk membolehkan kriptografi kunci asimetrik yang selamat, termasuk:
Kerahsiaan kunci peribadi: Keperluan keselamatan paling asas AKC ialah kunci peribadi kekal rahsia. Walau bagaimanapun, memandangkan kunci peribadi mesti dipautkan secara matematik kepada kunci awam, kerahsiaan kunci peribadi juga memerlukan bahawa adalah tidak mungkin secara pengiraan untuk mendapatkan kunci peribadi daripada pengetahuan tentang kunci awam. Skim penjanaan kunci dalam AKC bergantung kepada masalah matematik yang sukar secara pengiraan untuk memudahkan keperluan ini.
Fungsi perangkap Dalam AKC, operasi penyulitan dan penyahsulitan melibatkan kunci pelengkap berbeza daripada pasangan kunci tunggal. Ciphertext yang dijana oleh penyulitan menggunakan salah satu kunci (contohnya kunci awam) mesti tidak dapat difahami oleh pihak ketiga manakala mudah disahsulit oleh pemegang kunci pelengkap (dalam kes ini kunci peribadi). Dengan kata lain, penyulitan sepatutnya menyerupai fungsi sehala perangkap supaya pihak ketiga tidak boleh membalikkan operasi dan memulihkan teks biasa tetapi kunci peribadi menyediakan perangkap rahsia yang membolehkan penyongsangan mudah. Algoritma AKC popular menggunakan pemangkatan modular untuk mewujudkan tingkah laku fungsi sehala perangkap.
Kerawakan: Proses penjanaan kunci juga perlu mengeksploitasi kerawakan untuk memastikan kunci tidak dapat diramalkan, kerana sebarang corak atau kebolehramalan dalam penjanaan kunci boleh dieksploitasi oleh penyerang. Kerawakan juga digunakan untuk padding semasa penyulitan untuk menjana ciphertext yang selamat secara semantik dan dalam skim tandatangan digital untuk menghasilkan tandatangan unik walaupun mesej yang sama ditandatangani beberapa kali. Atas sebab ini, penggunaan penjana nombor rawak yang kuat adalah bahagian penting AKC.
Saiz kunci besar: Seperti dalam kes SKC, saiz kunci besar memastikan perlindungan terhadap serangan brute force. Walau bagaimanapun, memandangkan saiz kunci besar juga meningkatkan kos pengiraan proses penyulitan dan penyahsulitan, penyelesaian optimum perlu mengimbangi pertimbangan keselamatan dan kecekapan. Jadual berikut menunjukkan saiz kunci tipikal untuk pelbagai protokol dan aplikasi kriptografi kunci asimetrik:
| Protokol | Saiz Kunci Tipikal (dalam bit) | Aplikasi |
|---|---|---|
| RSA | 1024 (ditamatkan), 2048, 3072, 4096 | Penyulitan, tandatangan digital |
| DSA | 1024 (ditamatkan), 2048, 3072 | Tandatangan digital |
| DH | 2048, 3072, 4096 | Pertukaran kunci |
| ECDH | 224, 256, 384, 521 | Pertukaran kunci |
| ECDSA | 224, 256, 384, 521 | Tandatangan digital |
Infrastruktur kunci awam: Dalam AKC, kunci peribadi mesti disimpan secara rahsia oleh pemilik manakala kunci awam dikongsi. Perlu ada mekanisme selamat untuk mengurus dan mengedarkan kunci awam ini antara pengguna. Infrastruktur kunci awam (PKI) menyediakan cara untuk melakukan ini menggunakan sijil digital. Sijil digital menyediakan bukti identiti pemilik kunci awam dan dikeluarkan oleh pihak berkuasa yang dipercayai seperti pihak berkuasa sijil (yang merupakan sebahagian daripada PKI). Oleh itu, PKI memainkan peranan penting dalam keselamatan aplikasi moden menggunakan AKC dengan membolehkan pengurusan kunci berskala besar (dengan mencipta, mengurus, mengedarkan dan membatalkan sijil digital).
Risiko keselamatan kepada kriptografi kunci asimetrikβ
Seperti yang digariskan dalam jadual di atas, algoritma kunci asimetrik moden seperti RSA biasanya menggunakan saiz kunci yang jauh lebih besar daripada rakan sejawatan kunci simetrik yang biasa digunakan seperti AES-128. Malah protokol berasaskan ECC (ECDH dan ECDSA) yang mempunyai saiz kunci lebih kecil menggunakan sekurang-kurangnya 224 bit untuk kunci. Ini seterusnya bermakna bahawa serangan brute force yang melibatkan carian menyeluruh ruang kunci peribadi untuk mengenal pasti kunci yang betul adalah tidak dapat dilaksanakan secara pengiraan dalam masa terdekat. Ini tetap benar walaupun komputer kuantum digunakan untuk tugas ini. Oleh itu, serangan terhadap AKC biasanya menumpukan kepada mengeksploitasi kelemahan potensi lain sistem kripto tertentu. Beberapa mod serangan yang didokumentasikan dengan baik menyasarkan:
-
Kelemahan algoritma dengan menggunakan cara matematik dan pengiraan yang canggih untuk menjejaskan andaian kekerasan yang digunakan untuk merumuskan algoritma kunci asimetrik. Sebagai contoh, keselamatan RSA adalah bergantung kepada kesukaran memfaktorkan nombor perdana besar, dan kemajuan pengiraan terkini telah membolehkan pemfaktoran berjaya kunci RSA 829-bit. Oleh itu, RSA 1024-bit pada masa ini telah ditamatkan. Seperti yang akan dibincangkan kemudian, risiko utama yang ditimbulkan oleh komputer kuantum kepada AKC juga termasuk dalam kategori ini.
-
Kerawakan tidak sempurna, yang boleh membawa kepada kelemahan dalam proses penjanaan kunci. Sebagai contoh, jika penjana nombor rawak yang digunakan untuk mencipta kunci adalah cacat dan menjana kunci yang tidak benar-benar rawak, penyerang mungkin dapat meramalkan kunci tersebut.
-
Kelemahan pelaksanaan seperti ralat dalam pelaksanaan algoritma kriptografi yang secara tidak sengaja mendedahkan maklumat tentang kunci. Sebagai contoh, padding yang salah berpotensi mendedahkan butiran tentang kunci.
-
Saluran sisi yang merujuk kepada kebocoran maklumat daripada sistem fizikal yang menjalankan kriptografi. Kebocoran sedemikian boleh dalam bentuk maklumat masa, penggunaan kuasa, atau bahkan bunyi, yang boleh dieksploitasi dalam apa yang dipanggil serangan saluran sisi. Sebagai contoh, menganalisis berapa lama operasi kriptografi mengambil masa untuk dilaksanakan boleh mendedahkan bilangan '1' dalam kunci binari. Kebocoran yang kelihatan tidak berbahaya ini secara ketara mempersempitkan ruang carian, mendedahkan penyelesaian yang berpotensi kepada masalah yang pada mulanya kelihatan tidak dapat diatasi.
-
Pertukaran kunci dengan memintas kunci semasa pertukaran, seperti dalam serangan man-in-the-middle (MITM). Protokol DH terdedah kepada serangan MITM jika langkah pengesahan tambahan tidak dimasukkan.
-
Penyimpanan kunci dengan bertujuan mencuri kunci daripada storan yang tidak selamat. Ini termasuk serangan fizikal seperti manipulasi atau kecurian peranti storan.
Mengamankan sistem kripto kunci asimetrik terhadap pelbagai serangan yang mungkin adalah oleh itu satu tugas yang signifikan melibatkan pertimbangan matematik, perkakasan, perisian, logistik, dan perundangan.
RSAβ
Algoritma RSA (Rivest-Shamir-Adleman) ialah salah satu sistem kripto kunci awam yang pertama dan digunakan secara meluas untuk penghantaran data selamat. Ia adalah sistem kripto yang serba guna kerana ia menyediakan operasi yang diperlukan untuk membolehkan penyulitan, penyahsulitan, tandatangan digital, dan pertukaran kunci dalam kerangka yang sama.
Dalam bahagian ini, kita akan mengilustrasikan kriptografi kunci asimetrik (AKC) menggunakan RSA melalui contoh mudah.
Kita akan menggunakan senario standard dua pihak, Alice dan Bob, yang ingin berkomunikasi secara selamat menggunakan AKC.
Algoritma RSAβ
Algoritma RSA asas melibatkan empat operasi: penjanaan kunci, pengedaran kunci, penyulitan, dan penyahsulitan:
-
Penjanaan kunci:
Kunci awam dan peribadi dijana berdasarkan prinsip matematik sekitar nombor perdana, di mana mengira ia adalah mudah, tetapi sebaliknya adalah sukar.
Kita akan merujuk kepada ini:
- Kunci awam:
- Kunci peribadi:
Perhatikan bahawa adalah biasa kepada kedua-dua kunci awam dan kunci peribadi, dan dikenali sebagai modulus. Kita akan perlu menggunakannya kemudian.
Butiran matematik
- Pilih dua nombor perdana berbeza, dan .
- dipilih secara rawak (untuk keselamatan).
- Ia sepatutnya serupa dalam magnitud, tetapi berbeza dalam panjang beberapa digit, untuk menjadikan pemfaktoran lebih sukar.
- Nombor perdana boleh dipilih secara cekap menggunakan ujian keprimeaan.
- Kira .
- ialah modulus untuk kedua-dua kunci awam dan peribadi.
- Kira fungsi totient .
- Totient dimaksudkan untuk disimpan secara rahsia dan biasanya dibuang selepas penjanaan kunci.
- Pilih integer supaya dan .
- iaitu, dan sepatutnya koprima.
- Nombor ini membentuk eksponen kunci awam dan biasanya dipilih sebagai nombor kecil untuk kecekapan pengiraan.
- Nombor perdana sering digunakan.
- Kira untuk memenuhi hubungan kekongruenan .
- Iaitu, ialah songsangan pendaraban modulo .
- Ini dikira dengan lebih cekap menggunakan algoritma Euclidean lanjutan.
- Nombor ini ialah eksponen kunci peribadi.
- Kunci awam terdiri daripada , dan kunci peribadi ialah .
-
Pengedaran kunci:
- Kunci awam dijadikan awam kepada mereka yang mungkin ingin menghantar mesej
- Kunci peribadi disimpan secara rahsia.
-
Penyulitan:
- Alice ingin menghantar mesej kepada Bob. Dalam kes ini satu integer mudah
- Alice menggunakan kunci awam Bob untuk menyulitkan mesej menjadi ciphertext
Butiran matematik
- ialah integer .
- , di mana ialah ciphertext.
-
Penyahsulitan:
- Bob menerima ciphertext
- Bob menggunakan kunci peribadinya untuk menyahsulit mesej semula menjadi mesej
Butiran matematik
- .
Ini adalah garis besar asas RSA. Dalam praktik, skim padding yang lebih canggih digunakan kepada teks biasa sebelum penyulitan untuk memastikan teks biasa yang sama menghasilkan ciphertext yang berbeza. Ini mencegah pelbagai serangan yang mungkin terhadap pelaksanaan naif RSA dan membolehkan keselamatan semantik.
Ilustrasi RSA dalam Pythonβ
Dalam sel kod berikut, kita mengilustrasikan contoh mudah algoritma RSA menggunakan integer kecil kemudian menunjukkan pengedaran kunci praktikal dan aplikasi tandatangan digital menggunakan pustaka Python yang melaksanakan RSA.
Nota: Dalam bahagian ini kita akan menunjukkan pengiraan matematik secara terperinci sebagai sebahagian daripada kod Python
Penjanaan kunci RSAβ
Mari kita lalui contoh mudah algoritma RSA menggunakan nombor perdana kecil.
Kita perlu dapat mengira pembahagi sepunya terbesar dua integer, kerana ia diperlukan untuk menguji sama ada dua integer adalah koprima.
Kita akan menerangkan satu cara mudah untuk mengira ini, tetapi adalah lebih cekap dengan integer 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)
Fasa pertama aliran kerja RSA ialah penjanaan kunci. Ini dimulakan dengan memilih dua nombor perdana, yang dimaksudkan untuk disimpan secara rahsia oleh entiti yang menjana kunci.
# Choosing two prime numbers and keep them secret
p = 13
q = 19
print("The secret prime numbers p and q are:", p, q)
Seterusnya, modulus , yang merupakan hasil darab dua perdana yang dipilih, dikira. Modulus ini akan diterbitkan sebagai sebahagian daripada kunci awam.
# 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 dikira seterusnya, kerana ia diperlukan untuk operasi songsangan pendaraban modular yang digunakan untuk menentukan kunci dalam RSA. juga disimpan secara rahsia dan biasanya dibuang selepas penjanaan 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 kini bersedia untuk mengira kunci awam dan peribadi. Dalam RSA, setiap satunya ditentukan oleh tupel dua integer. Entri pertama dalam setiap tupel ialah integer yang berbeza, dan entri kedua ialah modulus yang biasa kepada kedua-dua kunci.
Entri pertama dalam kunci awam boleh menjadi mana-mana integer yang lebih besar daripada 1 yang koprima kepada . Dua integer adalah koprima jika pembahagi sepunya terbesar mereka ialah 1. Jadi kita menggunakan fungsi math.gcd untuk mencari integer yang koprima kepada .
# 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 peribadi memerlukan integer , yang merupakan songsangan pendaraban modulo ; iaitu, ia memenuhi hubungan kekongruenan . Untuk ilustrasi mudah ini di mana kita berurusan dengan integer kecil, kita boleh hanya mengulang ke atas integer positif untuk mencari yang sesuai. Dalam tetapan sebenar, algoritma Euclidean lanjutan yang cekap secara pengiraan 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 kini membentuk tupel , yang membentuk kunci awam dan peribadi masing-masing. Kunci awam kemudiannya diterbitkan, manakala kunci peribadi disimpan secara rahsia.
# Public and Private Key pair
public = (e, n)
private = (d, n)
print(f"The Public key is {public} and Private Key is {private}")
Penyulitan dan penyahsulitan dalam RSA menggunakan operasi pemangkatan modular. Selanjutnya, kunci awam dan peribadi adalah saling melengkapi dalam erti kata sama ada boleh digunakan untuk menyulitkan mesej yang satu lagi boleh menyahsulitnya.
Di sini kita mengilustrasikan kes di mana kunci awam digunakan untuk penyulitan dan kunci peribadi digunakan untuk penyahsulitan dengan mentakrifkan fungsi Python untuk setiap operasi.
Kita kemudiannya menyulitkan dan menyahsulit mesej integer .
# 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)
Walaupun integer kecil yang digunakan di atas berguna untuk dengan mudah menggariskan idea teras dalam algoritma RSA, dalam aplikasi sebenar RSA memerlukan penggunaan integer yang sangat besar. Sebagai contoh, RSA 2048-bit melibatkan penggunaan modulus yang panjang 2048 bit, setara integer perpuluhan yang mana adalah sekitar 10. Nombor-nombor yang benar-benar luar biasa besar ini diperlukan untuk keselamatan praktikal RSA.
Pertukaran kunci simetrik dengan RSAβ
Seperti yang dibincangkan sebelumnya, AKC membolehkan dua pihak yang ingin berkomunikasi untuk mewujudkan secara selamat rahsia dikongsi, yang boleh digunakan, sebagai contoh, sebagai kunci rahsia untuk penyulitan simetrik teks biasa pukal yang seterusnya.
Mari kita pertimbangkan senario berikut. Alice dan Bob ingin menggunakan SKC untuk menyulitkan dan menyahsulit mesej. Walau bagaimanapun, sebelum proses ini boleh dimulakan, mereka perlu bersetuju dengan kunci rahsia yang sama. Satu pilihan ialah satu pihak β katakan Alice β menjana kunci rahsia kemudian menghantarnya secara selamat kepada Bob. Untuk mencapai pemindahan selamat ini, Alice memutuskan untuk menggunakan RSA sebagai mekanisme enkapsulasi kunci (KEM).
Ini melibatkan langkah-langkah berikut:
- Pertama, Alice menjana kunci simetrik rawak, yang dia ingin kongsi dengan Bob.
- Kemudian, Bob menjana pasangan kunci asimetrik dan menjadikan kunci awamnya tersedia pada saluran yang sesuai.
- Seterusnya, Alice menggunakan kunci awam Bob untuk menyulitkan kunci simetrik, dengan itu mengenkapsulasikannya dalam ciphertext.
- Kemudian, Alice menyiarkan ciphertext melalui saluran yang boleh dipercayai tetapi tidak semestinya selamat.
- Akhirnya, Bob menerima ciphertext dan menyahsulitnya menggunakan kunci peribadinya. Dia kini mempunyai akses kepada kunci simetrik yang dijana oleh Alice.

Rajah 1. Pertukaran kunci simetrik dengan RSA
Contoh pertukaran kunci berasaskan padding dalam Pythonβ
Aliran kerja praktikal menggunakan RSA untuk pertukaran kunci bukan interaktif berasaskan padding kini diilustrasikan menggunakan pustaka Python cryptography.
Import modul yang diperlukan daripada pustaka Python cryptography. Jika diperlukan, pustaka ini boleh dipasang menggunakan perintah pip install cryptography.
Alice kemudiannya menjana kunci rahsia rawak, yang dia ingin hantar kepada 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 daripada pustaka cryptography, Bob menjana pasangan kunci dan kemudiannya menyiarkan kunci awamnya. Sesiapa sahaja boleh memintas kunci awam dan membaca nombor awam yang membentuk kunci.
# 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 ketika ini, kita andaikan Alice telah menerima kunci awam yang disiarkan oleh Bob. symmetric_key Alice di atas kini boleh disulitkan menggunakan kunci awam Bob untuk menghasilkan ciphertext. Dalam tetapan sebenar, Alice juga akan menggunakan kaedah padding tambahan seperti OAEP untuk memastikan keselamatan semantik 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 kemudiannya menyiarkan ciphertext melalui saluran terbuka, yakin bahawa hanya Bob dengan kunci peribadi yang sepadan akan dapat menyahsulitnya. Kita andaikan Bob telah menerima ciphertext dan kini boleh menyahsulitnya menggunakan kunci peribadi sulit miliknya.
# 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 ketika ini, Alice dan Bob kedua-duanya mempunyai akses kepada kunci simetrik rahsia, yang boleh mereka gunakan untuk aplikasi SKC.
Simulasi Mekanisme Enkapsulasi Kunci dengan RSA dalam Pythonβ
Dalam aliran kerja berikut, kita menggambarkan penggunaan RSA untuk mensimulasikan Mekanisme Enkapsulasi Kunci (KEM) di mana rahsia rawak yang cukup panjang ditukar secara selamat dan kemudiannya ditukarkan kepada rahsia bersama yang sesuai panjangnya menggunakan KDF.
Sekali lagi Alice dan Bob ingin mewujudkan rahsia bersama secara tidak interaktif dan Alice adalah pihak yang memutuskan rahsia mana yang hendak digunakan.
Kita mulakan dengan mengimport beberapa perpustakaan Python yang diperlukan.
Bob kemudian menjana pasangan kunci RSA-nya dan menyiarkan kunci awamnya.
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 mula-mula menjana rahsia rawak yang panjang dari mana rahsia bersama akhirnya akan diterbitkan. Dalam KEM yang tulen, rahsia panjang itu akan menjadi elemen rawak daripada struktur algebra yang mendasari sistem kriptografi. Dalam kes RSA 2048-bit, ini akan menjadi integer rawak modulo modulus RSA 2048-bit. Oleh itu, KEM yang tulen tidak memerlukan pengisi tambahan, tetapi dalam contoh ini kita hanya mensimulasikan KEM menggunakan RSA dan perpustakaan cryptography memerlukan penggunaan pengisi semasa penyulitan dengan RSA. Jadi kita akan menggunakan rahsia panjang yang agak lebih pendek namun jauh lebih panjang daripada kunci AES 256-bit standard.
Alice_long_secret = urandom(160) # A 160 byte or 1280 bit random message
print("Alice's secret created")
Seterusnya Alice menyulitkan rahsia panjang itu menggunakan kunci awam Bob dan rahsia yang disulitkan itu disampaikan kepada 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 menyahsulit rahsia yang disulitkan yang diterima daripada Alice menggunakan kunci peribadinya.
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")
Akhir sekali, Alice dan Bob masing-masing secara berasingan menggunakan Fungsi Penurunan Kunci (KDF) yang telah dipersetujui ke atas rahsia panjang untuk mendapatkan kunci simetri.
Perhatikan bahawa proses ini melibatkan protokol pencincangan dan penggunaan garam rawak yang memastikan keunikan dan ketidakbolehramalan kunci simetri bersama sekiranya rahsia panjang itu digunakan semula (tidak disyorkan). Walau bagaimanapun, garam itu sendiri tidak perlu dirahasiakan dan setelah dijana secara rawak, katakanlah oleh Alice dalam contoh ini, ia boleh disiarkan kepada Bob bersama rahsia panjang yang disulitkan.
Oleh itu kita akan anggap bahawa Alice dan Bob mempunyai akses kepada garam rawak 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!"
)
Tandatangan digital dengan RSAβ
Kita kini akan meluaskan senario komunikasi sulit antara Alice dan Bob di atas kepada senario yang juga termasuk pengesahan dengan bantuan tandatangan digital.
Seperti sebelumnya, Alice akan menghantar mesej yang merangkumi kunci simetri kepada Bob secara sulit, tetapi dia juga akan menandatanganinya secara digital supaya Bob, setelah menerima mesej itu, boleh mengesahkan bahawa Alice yang menghantar mesej itu dan kandungan mesej tidak diganggu semasa penghantaran.
Secara lebih umum, adalah wajar untuk membolehkan pengesahan tanpa menjejaskan kerahsiaan di mana mana-mana pihak yang berminat dapat mengesahkan integriti, keaslian, dan mewujudkan penafian tidak boleh dilakukan terhadap sesuatu komunikasi, walaupun pihak itu tidak mempunyai akses kepada mesej teks biasa yang sebenar.
Kita akan mempertimbangkan tetapan umum ini yang kemudiannya melibatkan langkah-langkah berikut:
- Pertama, Bob dan Alice sama-sama membuat kunci awam mereka tersedia melalui saluran terbuka.
- Kemudian, Alice menyulitkan teks biasa menggunakan kunci awam Bob, mencipta teks sifir.
- Seterusnya, Alice mencipta cincang teks sifir dengan fungsi cincang dan kemudian menyulitkan teks sifir yang telah dicincang itu menggunakan kunci peribadinya. Cincang yang disulitkan ini adalah tandatangan.
- Kemudian, Alice menghantar kedua-dua teks sifir dan tandatangan melalui saluran terbuka.
- Kemudian, Bob menggunakan kunci awam Alice untuk menyahsulit tandatangan, mendedahkan teks sifir yang telah dicincang.
- Seterusnya, kerana Bob juga mempunyai akses kepada teks sifir itu sendiri, dia menggunakan fungsi cincang yang sama yang digunakan oleh Alice untuk mencipta semula contoh kedua teks sifir yang dicincang. Jika yang terakhir sepadan dengan yang diperoleh dengan menyahsulit tandatangan Alice, maka mesej itu disahkan, walaupun teks sifir itu sendiri belum lagi dinyahsulit.
- Akhir sekali, Bob, setelah mengesahkan mesej itu, menyahsulit teks sifir menggunakan kunci peribadinya sendiri.

Rajah 2. Tandatangan digital dengan RSA
Aliran kerja untuk tandatangan digital ini diilustrasikan seterusnya.
Kita sekali lagi mengimport beberapa modul berguna daripada perpustakaan cryptography.
Seperti sebelumnya, Alice berhasrat menghantar kunci simetri kepada Bob secara selamat, tetapi dia juga ingin menandatanganinya secara digital. Dalam kes ini, kita memerlukan kunci awam untuk Alice dan Bob. Oleh itu, langkah pertama adalah bagi Alice dan Bob masing-masing mencipta pasangan kunci mereka sendiri menggunakan RSA dan menyiarkan kunci awam mereka sendiri kepada 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.")
Dalam langkah seterusnya, seperti sebelumnya, Alice menggunakan kunci awam Bob untuk menyulitkan kunci simetri dan menyediakan teks sifir.
# 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 peringkat ini, daripada hanya menyiarkan teks sifir, Alice berhasrat untuk melampirkan tandatangan digital padanya supaya dia boleh membuktikan kepada Bob bahawa dia adalah pengirim mesej itu. Ini dilakukan dalam dua langkah:
- Cipta cincang teks sifir menggunakan algoritma pencincangan.
- Sulitkan cincang menggunakan kunci peribadi Alice, yang merupakan tandatangan.
# 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 teks sifir dan tandatangan melalui rangkaian supaya Bob dapat menerima kedua-duanya.
# Bob receives the ciphertext and signature
received_ciphertext = ciphertext
received_signature = signature
# Send signature and ciphertext here
print("Sending ciphertext and signature.....")
Dari sisi Bob, tugas pertama adalah untuk mengesahkan integriti dan keaslian teks sifir. Untuk melakukan ini, Bob mencipta cincang teks sifir yang diterima menggunakan algoritma pencincangan yang sama yang digunakan oleh 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 menyahsulit tandatangan yang diterima menggunakan kunci awam Alice. Kerana Alice menggunakan kunci peribadinya untuk mencipta tandatangan, Bob dapat menyahsulitnya menggunakan kunci awam Alice. Tandatangan yang dinyahsulit tidak lain hanyalah cincang teks sifir yang dicipta di pihak Alice. Jika cincang yang dicipta oleh Bob sepadan dengan tandatangan yang dinyahsulit, maka Bob telah mengesahkan bahawa teks sifir yang diterimanya tidak diganggu dan bahawa Alice yang menandatangani teks sifir itu.
Dalam kod Python di bawah, operasi-operasi ini digabungkan ke dalam fungsi utiliti berguna yang dipanggil verify yang disediakan oleh objek yang dikaitkan dengan kunci awam 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 mengesahkan integriti dan keaslian teks sifir yang diterima, Bob kemudian boleh menyahsulitnya menggunakan kunci peribadinya kerana Alice mencipta teks sifir menggunakan kunci awam 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 senario tandatangan digital di atas, mana-mana pihak β bukan hanya Bob β boleh mengesahkan bahawa Alice adalah pengirim teks sifir kerana semua orang boleh mengakses kunci awam Alice, teks sifir, dan tandatangan digital. Tambahan pula, setelah menghantar teks sifir dan tandatangan, Alice tidak boleh kemudiannya menafikan telah berbuat demikian kerana tandatangan itu boleh dinyahsulit kepada cincang yang bermakna hanya menggunakan kunci awamnya. Ini mewujudkan penafian tidak boleh dilakukan.
Dengan membolehkan pengedaran kunci yang selamat dan menyokong penafian tidak boleh dilakukan, kriptografi kunci awam mewujudkan asas yang kukuh untuk komunikasi digital yang selamat.
Memecahkan RSAβ
Kegunaan dan keselamatan algoritma RSA yang digariskan di atas bersandarkan dua andaian matematik:
-
Mencari songsang pendaraban modular sedangkan hanya mempunyai akses kepada adalah tidak boleh dilaksanakan secara pengiraan.
-
Dalam tetapan RSA, operasi pendarapan modular berkelakuan seperti fungsi trapdoor sehala. Apabila digunakan untuk penyulitan, ia menghasilkan teks sifir yang sukar difahami, dan tanpa akses kepada kunci peribadi, membalikkan operasi untuk memulihkan teks biasa daripada teks sifir adalah tidak boleh dilaksanakan. Walau bagaimanapun, dengan akses kepada kunci peribadi, yang bertindak sebagai trapdoor, teks sifir boleh dengan mudah dinyahsulit.
Serangan paling menonjol terhadap algoritma RSA bertujuan untuk melemahkan andaian 1 dengan memulihkan nombor kunci peribadi secara cekap melalui pemfaktoran modulus . Seperti yang akan diilustrasikan di bawah, adalah mudah untuk memulihkan jika seseorang mempunyai akses kepada sama ada faktor perdana dan bagi atau totient . Ingat bahawa , , dan dirahsiakan semasa penjanaan kunci dan dibuang selepas itu. Pihak ketiga yang memulihkan maklumat ini menggunakan komputer klasik atau kuantum pada dasarnya mendedahkan kunci peribadi, memecahkan RSA. Oleh itu, pemfaktoran perdana adalah primitif pengiraan utama yang diperlukan untuk memecahkan RSA.
Pengkomputeran klasik dan RSAβ
Pemfaktoran perdana bagi integer besar diketahui menunjukkan penskalaan super-polinomial atau subeksponential pada komputer klasik. Algoritma klasik terbaik yang diketahui untuk memfaktorkan integer yang lebih besar daripada ialah penapis medan nombor umum (GNFS)
Perincian matematik
sebagai fungsi integer yang hendak difaktorkan.
Penskalaan ini adalah super-polinomial dalam bilangan bit yang diperlukan untuk mewakili .
Oleh itu, pemfaktoran perdana dianggap tidak cekap pada komputer klasik.
Pada masa ini, integer terbesar yang difaktorkan pada perkakasan klasik adalah dalam julat 829 bit atau 250 digit perpuluhan. Memandangkan pertumbuhan eksponen dalam kuasa pengkomputeran klasik yang telah disaksikan dalam beberapa dekad yang lalu, RSA 1024-bit tidak lagi dianggap selamat dalam jangka pendek dan kini sudah tidak diguna pakai. Walau bagaimanapun, dalam masa terdekat, memfaktorkan integer 2048-bit yang magnitudnya berada dalam julat pada masa ini dianggap tidak boleh dilaksanakan pada sistem klasik, mencadangkan kebolehterusan berterusan. Kemunculan komputer kuantum, bagaimanapun, membatalkan penilaian ini.
Algoritma kuantum Shor dan RSAβ
Mungkin algoritma kuantum yang paling terkenal hari ini ialah algoritma Shor untuk mencari faktor perdana integer. Apabila diperkenalkan oleh Peter Shor pada tahun 1994, ia diiktiraf sebagai algoritma kuantum pertama yang menawarkan percepatan super-polinomial berbanding algoritma klasik dalam masalah yang sangat penting dari segi praktikal, iaitu pemfaktoran perdana.
Algoritma Shor boleh memfaktorkan perdana dengan di mana ialah bilangan bit.
Penjelasan matematik algoritma Shor
Dalam konteks RSA, algoritma Shor berfungsi dengan mengeksploitasi keperiodikan fungsi eksponen modular dan menyediakan primitif pencarian tempoh kuantum yang membolehkan pemfaktoran perdana yang cekap bagi modulus .
Garis besar ringkas peringkat tinggi skema keseluruhan Shor untuk memecahkan RSA adalah seperti berikut:
-
Diberi modulus , yang diterbitkan sebagai sebahagian daripada kunci awam, pilih nombor yang koprim kepada iaitu, . Oleh kerana kita tahu bahawa mempunyai tepat dua faktor perdana , hampir mana-mana nombor yang kurang daripada yang kita pilih secara rawak berkemungkinan besar koprim kepada .
-
Setelah memilih , cari eksponen supaya . Ini bermaksud . Kewujudan eksponen supaya kongruens di atas berlaku dijamin oleh sifat keperiodikan pendarapan modular.
-
Jika adalah genap, untuk sesetengah integer . Sebelah kiri persamaan terakhir ini mesti mengandungi dan sebagai dua daripada faktor perdananya kerana sebelah kanan juga berbuat demikian. Jika adalah ganjil, kembali ke langkah 1 dan cuba pilihan berbeza untuk .
-
Gunakan algoritma Euclid yang diperluas untuk mencari atau . GCD yang dikira sangat berkemungkinan mengenal pasti salah satu faktor perdana atau . Bahagikan dengan faktor perdana ini untuk memulihkan yang satu lagi.
-
Setelah diketahui, gunakan langkah-langkah dari algoritma RSA asal untuk membina semula totient dan menjana nombor kunci peribadi sebagai songsang modular bagi nombor kunci awam yang diketahui.
Pada Ogos 2023 Oded Regev menerbitkan penambahbaikan pada asli Shor menggunakan pendekatan berbilang dimensi yang menghasilkan . Penyelidikan lanjut terus berlangsung termasuk oleh Ragavan dan Vaikuntanathan dalam bidang ini yang mungkin meningkatkan masa, kos, atau bilangan qubit yang diperlukan. Walaupun kita tidak boleh mengatakan bila menjalankan algoritma sedemikian terhadap penyulitan RSA dunia nyata benar-benar menjadi boleh dilaksanakan, ia semakin hampir dari masa ke masa.
Contoh Python yang menunjukkan pemecahan penyulitan RSAβ
Dalam sel kod berikut, kita menggambarkan contoh mencari kunci peribadi berdasarkan kunci awam sahaja. Ini akan menggunakan pengiraan klasik kasar, tetapi menunjukkan bagaimana algoritma Shor boleh digunakan β termasuk kunci yang besar.
Dalam bahagian ini kita akan menunjukkan pengiraan matematik secara terperinci sebagai sebahagian daripada kod Python
Dalam contoh ini, kita mempunyai kunci awam , dan kita akan memulihkan kunci peribadi.
Langkah 1: Langkah pertama adalah untuk memilih nombor yang koprim kepada 247. Hampir mana-mana nombor yang kita teka akan melaksanakan tugas tersebut. Mari kita 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: Seterusnya kita perlu mencari tempoh supaya . Dalam contoh ini, kita mengira secara klasik menggunakan kasar paksa, tetapi kita juga boleh 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: Oleh kerana tempoh adalah genap, kita boleh mengira .
# 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: Cari GCD bagi salah satu faktor tersebut dengan . Bahagikan sahaja dengan faktor perdana yang telah ditemui untuk mendapatkan faktor perdana 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 perdana sebagai dan , kita mengira totient .
Kunci peribadi adalah songsang modular bagi nombor kunci awam .
# 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 tempoh yang penting di mana algoritma Shor menggunakan dua primitif kuantum asas, iaitu jelmaan Fourier kuantum dan anggaran fasa kuantum. Untuk penjelasan terperinci tentang aspek kuantum algoritma Shor, lihat pelajaran Anggaran fasa dan pemfaktoran dalam Asas Algoritma Kuantum. Langkah 1 dan 3 hingga 5 melibatkan operasi yang agak murah yang boleh dilaksanakan dengan mudah pada komputer klasik.
Secara pilihan, inilah panduan visual terperinci tentang pelaksanaan algoritma Shor.
Pada komputer kuantum, algoritma Shor boleh menunjukkan penskalaan polilogaritmik sebaik dari segi modulus , atau penskalaan polinomial dari segi bilangan bit yang diperlukan untuk mewakili . Ini adalah percepatan super-polinomial berbanding algoritma GNFS klasik.
Anggaran sumber terkini menunjukkan bahawa berdasarkan andaian tertentu yang dibuat mengenai konfigurasi perkakasan, beberapa puluh ribu hingga beberapa juta qubit akan diperlukan untuk memecahkan RSA 2048-bit menggunakan algoritma Shor. Tidak mustahil bahawa komputer kuantum dengan beberapa puluh ribu qubit akan tersedia dalam beberapa tahun akan datang, menjadikan hujung bawah anggaran sumber boleh dicapai.
Pertukaran kunci Diffie-Hellman dan Algoritma Tandatangan Digitalβ
Dalam bahagian sebelumnya, kita membincangkan kriptosistem RSA yang keselamatannya bergantung pada kesukaran pengiraan pemfaktoran perdana. Di sini, kita akan membincangkan dua protokol kriptografi kunci asimetri yang popular, iaitu pertukaran kunci Diffie-Hellman (DH) dan Algoritma Tandatangan Digital (DSA), kedua-duanya berasaskan masalah matematik yang berbeza, iaitu masalah logaritma diskret (DLP).
Masalah logaritma diskretβ
Dalam persamaan berikut, kita perlu mencari dengan hanya diberi , ,
Ini dipercayai sukar dilakukan dengan komputer klasik kerana penggunaan aritmetik modulo, dan oleh itu menjadi asas matematik yang baik untuk algoritma penyulitan.
Ini dikenali sebagai masalah logaritma diskret (DLP).
Butiran matematik masalah logaritma diskretβ
DLP biasanya dibingkai dalam konteks kumpulan kitaran dan dinyatakan seperti berikut.
Pertimbangkan kumpulan kitaran yang dijana oleh elemen kumpulan dan diberi elemen sembarangan , cari integer supaya .
Di sini integer adalah logaritma diskret. Sifat kitaran menjamin bahawa untuk setiap , terdapat integer yang sah.
Untuk kriptografi, DLP pada kumpulan pendaraban integer modulo nombor perdana yang ditandakan ternyata berguna. Elemen-elemen ialah kelas kongruens yang dilabelkan dengan integer modulo yang coprime dengan .
Sebagai contoh:
Operasi pendaraban pada kumpulan ini hanyalah pendaraban integer biasa diikuti dengan pengurangan modulo , dan pemangkatan dengan integer hanyalah pendaraban berulang sebanyak kali dan pengurangan modulo .
Mari kita ilustrasikan contoh DLP pada .
Kumpulan pendaraban ini mempunyai dua penjana yang juga dikenali sebagai punca primitif. Kita akan menggunakan sebagai penjana; iaitu, jana setiap elemen menggunakan kuasa integer berturutan bagi 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 lihat bahawa dalam aritmetik modulo 7, menaikkan 5 kepada kuasa integer berturutan menghasilkan setiap elemen tepat sekali sebelum kitaran berulang tanpa had dengan tempoh .
Jadi DLP pada dengan penjana [5] ialah:
.
Daripada output sel Python di atas kita lihat bahawa:
Dalam aritmetik nombor nyata biasa, pemangkatan adalah fungsi monoton dan mencari logaritma sebarang nombor kepada sebarang asas adalah mudah secara pengiraan. Sebaliknya, seperti yang jelas daripada contoh mudah di atas, pemangkatan modular adalah bukan monoton, dan walaupun ia berkala dengan tempoh , ia sebaliknya sangat tidak trivial. Jadi mengira songsangannya, iaitu logaritma diskret, ternyata tidak cekap untuk yang besar pada komputer klasik.
Pemerhatian ini menyokong kedua-dua pertukaran kunci Diffie-Hellman (DH) dan Algoritma Tandatangan Digital (DSA), yang dibincangkan dalam bahagian seterusnya.
DLP boleh diperluaskan kepada subkumpulan kitaran seperti berikut:
- Pertimbangkan yang ditakrifkan di atas dan elemen bertertib perdana , iaitu .
- Set kuasa integer bagi : adalah subkumpulan kitaran dengan tertib kumpulan .
- Satu DLP boleh ditentukan pada dengan memilih dan meminta supaya
Pertukaran kunci Diffie-Hellmanβ
Pada tahun 1976, Whitfield Diffie dan Martin Hellman mencadangkan protokol pertukaran kunci untuk membolehkan penciptaan kunci rahsia dikongsi melalui saluran komunikasi yang tidak selamat. Kunci rahsia tersebut kemudian boleh digunakan oleh pihak-pihak yang berkongsinya untuk penyulitan simetri. Algoritma ini bergantung pada DLP.

Rajah 1. Pertukaran kunci Diffie-Hellman
Butiran matematik pertukaran kunci Diffie-Hellman
Dengan Alice dan Bob sebagai dua pihak yang berkomunikasi, protokol berfungsi seperti berikut:
- Pertama, Alice dan Bob bersetuju pada nombor perdana besar dan punca primitif atau penjana .
- Kemudian, Alice memilih eksponen rahsia secara rawak dengan dan mengira . masing-masing adalah kunci peribadi dan kunci awam Alice.
- Seterusnya, Bob memilih eksponen rahsia secara rawak dengan dan mengira . masing-masing adalah kunci peribadi dan kunci awam Bob.
- Kemudian, Alice menghantar kepada Bob dan Bob menghantar kepada Alice melalui saluran yang boleh dipercayai tetapi tidak semestinya selamat.
- Selepas itu, Alice menggunakan yang diterimanya untuk mengira kunci rahsia dikongsi .
- Akhirnya, Bob pula menggunakan yang diterimanya untuk mengira kunci rahsia dikongsi .
Dengan protokol ini,
- Alice dan Bob dijamin berakhir dengan kunci rahsia yang sama kerana .
- Pihak ketiga yang memintas atau tidak boleh membina kunci rahsia kerana mereka tidak mempunyai akses kepada atau masing-masing.
- Mengekstrak atau menggunakan maklumat awam , , dan adalah sukar secara pengiraan kerana ia bersamaan dengan menyelesaikan DLP pada .
Ilustrasi protokol Diffie-Hellman dalam Pythonβ
Mari kita lihat contoh mudah protokol DH dalam Python menggunakan nombor perdana kecil:
Dalam bahagian ini kita akan menunjukkan pengiraan matematik secara terperinci sebagai sebahagian daripada kod Python
Langkah 1: Alice dan Bob bersetuju pada perdana dan punca primitif . Mari pilih .
# Step 1: Choose a prime `p` and a primitive root `a`
p = 11
a = 7
print(f"prime: {p}")
print(f"primitive root: {a}")
Langkah 2, 3: Alice memilih eksponen rahsia dan mengira . Begitu juga, Bob memilih eksponen rahsia dan mengira .
k_A = 4 # Alice's private key
h_A = (a ** (k_A)) % p # Alice's public key
print(f"Alice's private key is {k_A} and public key is {h_A}")
k_B = 8 # Bob's private key
h_B = (a ** (k_B)) % p # Bob's public key
print(f"Bob's private key is {k_B} and public key is {h_B}")
Langkah 4: Kedua-dua pihak menyiarkan kunci awam mereka dan .
Langkah 5, 6: Setiap pihak menggabungkan kunci peribadi mereka dengan kunci awam pihak lain untuk mencipta kunci rahsia dikongsi.
secret_key_alice = h_B**k_A % p
secret_key_bob = h_A**k_B % p
assert secret_key_alice == secret_key_bob
print(f"The shared secret key is: {secret_key_bob}")
Alice dan Bob kini boleh menggunakan kunci rahsia dikongsi untuk penyulitan simetri.
Keselamatan pertukaran kunci Diffie-Hellmanβ
Seperti yang dinyatakan di atas, keselamatan DH bergantung pada kesukaran pengiraan menyelesaikan DLP dengan perdana besar . Dalam aplikasi biasa, NIST mengesyorkan integer perdana 2048 atau 3072 bit untuk pertukaran kunci DH, yang dianggap cukup selamat terhadap percubaan menyelesaikan DLP menggunakan komputer klasik.
Serangan Man-in-the-middle (MITM): Hakikat bahawa DH adalah skim interaktif di mana rahsia dikongsi bergantung pada penggabungan kunci peribadi satu pihak dengan kunci awam pihak lain menjadikannya terdedah kepada serangan yang dipanggil Man-in-the-middle (MITM).
Butiran matematik keselamatan DH dan serangan MITM
Dalam senario ini, pihak ketiga β katakanlah, Eve β memintas kunci awam semasa penghantaran dan menggantikan kunci awamnya sendiri untuk setiap dan sebelum meneruskannya kepada Bob dan Alice masing-masing.
Kemudian, bukannya menggunakan untuk mencipta rahsia berkongsiannya, Alice akan menggunakan sambil menyangka bahawa dia menggunakan kunci awam Bob. Begitu juga, bukannya menggunakan untuk mencipta rahsia berkongsiannya, Bob akan menggunakan sambil menyangka bahawa dia menggunakan kunci awam Alice.
Kerana digunakan untuk mencipta rahsia dikongsi Alice (Bob), teks biasa yang disulitkan oleh Alice (Bob) boleh dinyahsulit oleh Eve.
Oleh itu, pertukaran kunci DH biasanya digunakan bersama algoritma tandatangan digital untuk memastikan setiap pihak menggunakan kunci awam yang telah disahkan untuk mencipta rahsia dikongsi mereka.
Algoritma Tandatangan Digital (DSA)β
Walaupun kriptosistem generik seperti RSA menyediakan fungsi tandatangan digital, pada tahun 1994 NIST mengadopsi skim tandatangan khusus berdasarkan pemangkatan modular dan masalah logaritma diskret sebagai piawaian persekutuan untuk tandatangan digital. Skim ini, yang kemudian dikenali hanya sebagai Algoritma Tandatangan Digital (DSA), melibatkan empat fasa berbeza:
-
Penjanaan kunci:
Kunci DSA dijana daripada:
- 2 nombor perdana yang memenuhi peraturan tertentu
- - biasanya 256 bit (kita panggil panjang ini )
- - biasanya 3072 bit (kita panggil panjang ini )
- Fungsi cincang kriptografi yang akan menukar daripada rentetan panjang kepada
- Parameter tambahan (lihat butiran di bawah)
Daripada ini kita memilih nombor rawak sebagai kunci peribadi, dan mampu mengira kunci awam
Butiran matematik penjanaan kunci
-
Penjanaan parameter: Secara matematik, DSA melibatkan subkumpulan kitaran yang dijana oleh elemen bertertib perdana q < p. Langkah pertama dalam DSA adalah memilih dua nombor perdana p, q untuk menyediakan struktur matematik yang diperlukan.
- Pilih nombor perdana sebanyak bit.
- Pilih nombor perdana sebanyak bit supaya adalah gandaan . Pilihan menentukan kumpulan
- Ambil integer secara rawak dan kira . Jika yang jarang berlaku, cuba yang lain.
- Sahkan bahawa . g dengan itu adalah penjana subkumpulan kitaran bagi bertertib perdana q.
Parameter menentukan contoh algoritma dan merupakan maklumat awam. Biasanya, dan dalam aplikasi sebenar.
Protokol ini juga memerlukan fungsi cincang kriptografi yang memetakan rentetan binari bit kepada rentetan bit, contohnya, SHA-256.
-
Penjanaan pasangan kunci: Penandatangan perlu menjana pasangan kunci di pihak mereka.
- Pilih integer rahsia rawak . adalah kunci peribadi.
- Jana . adalah kunci awam penandatangan.
- 2 nombor perdana yang memenuhi peraturan tertentu
-
Pengedaran kunci:
Maklumat berikut dikongsi dengan sesiapa yang ingin mengesahkan tandatangan
- Parameter yang digunakan yang menerangkan algoritma
- Fungsi cincang
- Kunci awam
-
Penandatanganan:
- Penandatangan kini boleh menandatangani mesej . Tandatangan yang dihasilkan adalah
- Mesej dan tandatangan kedua-duanya kini dihantar kepada penerima
Butiran matematik menandatangani mesej
Penandatangan menandatangani mesej seperti berikut:
- Pilih integer rahsia k secara rawak daripada
- Kira . Dalam kes yang jarang berlaku apabila , cuba k rawak yang lain.
- Kira . Dalam kes yang jarang berlaku jika , cuba k rawak yang lain.
- Tandatangan adalah tuple .
- Penandatangan menghantar mesej serta tandatangan kepada pengesah.
Kerana kedua-dua adalah integer, modulo saiz tandatangan adalah dalam tertib bit dan bukan bit yang lebih panjang.
-
Pengesahan:
Penerima kini ingin mengesahkan kesahihan penghantar. Mereka mempunyai akses kepada maklumat awam Mereka boleh melaksanakan pengiraan yang membuktikan bahawa penghantar mempunyai akses kepada kunci peribadi
dan berusaha memastikan bahawa penandatangan adalah seseorang yang mempunyai akses kepada kunci peribadi .
Butiran matematik skim pengesahan DSA
- Sahkan bahawa dan , iaitu, adalah integer modulo~q yang sah.
- Kira .
- Kira .
- Kira .
- Kira .
- Tandatangan disahkan jika .
Untuk tandatangan yang sah, ketepatan algoritma DSA mudah ditunjukkan seperti berikut:
- Di pihak penandatangan:
- Memandangkan bahagian kanan kesamaan yang terakhir, pengesah boleh mengira kerana adalah maklumat awam.
- Oleh itu, pengesah mengira dan .
- Pengesah juga mengira kerana juga awam.
- Perhatikan bahawa .
- Walau bagaimanapun, pengesah tidak mempunyai akses kepada kerana ia adalah kunci peribadi penandatangan, jadi itu sendiri tidak boleh dikira secara langsung. - Skim ini sebaliknya bergantung pada hakikat bahawa walaupun pengesah tidak dapat mengira , dengan penandatangan yang sah, pengesah sepatutnya mampu mengira semula