خوارزمية تشفير RSA
دعنا نراجع خوارزمية تشفير RSA. نحن نستخدم لغة موحدة نسبيًا لوصف هذه الخوارزمية بناءً على تعريف خوارزمية تشفير المفاتيح العامة وخوارزمية التوقيع.
يتضمن نظام تشفير المفاتيح العامة RSA الخوارزميات الثلاثة التالية: Keygen (خوارزمية توليد المفاتيح) ، Encrypt (Encrypt) و Decrypt (خوارزمية فك التشفير).
تستخدم خوارزمية توليد المفاتيح ثابتًا للأمان كمدخلات لإخراج مفتاح PK العام ومفتاح خاص SK. يتم استخدام ثابت الأمان لتحديد مدى تأمين خوارزمية التشفير ، والتي ترتبط عمومًا بحجم الرقم الرئيسي P الذي تستخدمه خوارزمية التشفير. كلما كان الرقم الرئيسي P أكبر ، كلما زاد النظام ، ضمان ارتفاع الأمن. في RSA ، فإن خوارزمية توليد المفاتيح هي كما يلي: الخوارزمية أولاً تنشئ عشوائيين اثنين من الأرقام الأولية الكبيرة P و Q ، وتحسب N = PQ. ثم ، تحسب الخوارزمية وظيفة Euler. بعد ذلك ، تختار الخوارزمية بشكل عشوائي عدد صحيح أقل من E ويحسب العنصر العكسي Modulo D من E. أخيرًا ، المفتاح العام هو pk = (n ، e) والمفتاح الخاص هو sk = (n ، d).
تستخدم خوارزمية التشفير المفتاح العام PK والرسالة M ليتم تشفيرها على أنها إدخال وإخراج Ciphertext CT. في RSA ، فإن خوارزمية التشفير هي كما يلي: الخوارزمية تخرج مباشرة النص المشفر حيث تستخدم خوارزمية فك التشفير SK SK و Ciphertext المقطوعة المقطعية مثل إخراج algorithm الناتج عن النزعة المعيار المفرطة مباشرةً. نظرًا لأن E و D معاكس عكسيا لبعضهما البعض ، لدينا:
لذلك ، من وصف الخوارزمية ، يمكننا أيضًا أن نرى أن المفتاح العام يستخدم لتشفير البيانات ، ويتم استخدام المفتاح الخاص لفك تشفير البيانات. بالطبع ، يمكن أيضًا فهم هذا بشكل حدسي: المفتاح العام هو مفتاح عام ، وفقط عند الكشف عنه ، يمكن للجميع استخدامها لتشفير البيانات. المفتاح الخاص هو مفتاح خاص ، وأي شخص لديه هذا المفتاح يمكنه فك تشفير النص المشفر. خلاف ذلك ، إذا تمكن الجميع من رؤية المفتاح الخاص وفك تشفيره ، فسيكون ذلك فوضى.
دعنا نلقي نظرة على التنفيذ البسيط في جافا:
حزمة com.stone.security ؛ استيراد java.security.keypair ؛ استيراد java.security.keypairgenerator ؛ استيراد java.security.privatekey ؛ استيراد java.security.publickey ؛ استيراد java.util.arrays ؛ استيراد javax.crypto.cipher ؛ / *** RSA خوارزمية تشفير المفتاح العمومي التشفير غير المتماثل*/ الفئة العامة RSA {public Static Final String key_algorithm = "RSA" ؛ Static Static Final Final Cipher_algorithm_ecb1 = "RSA/ECB/PKCS1Padding" ؛ Static Static Final Final Cipher_algorithm_ecb2 = "RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING" ؛ // لا يمكنك استخدام السلسلة النهائية الثابتة العامة Cipher_algorithm_ecb3 = "OAEPWITHSHA-256ANDMGF1PADDING" ؛ // لا يمكنك استخدام Publickey Static Publickey ؛ Static Privatekey Privatekey ؛ تشفير تشفير ثابت. keypair keypair ثابت. يبرز الفراغ الثابت العام (سلسلة [] args) الاستثناء {method1 ("skoda u*(sfsad7f ()*^٪٪ $") ؛ method2 ("skoda u*(sfsad7f ()*^٪٪ $") Default Cipher_algorithm_ecb1 * param str * athrows استثناء */ static void method1 (String Str) keypair.getPrivate () ؛ Arrays.ToString (Encrypt)) ؛ cipher_algorithm_ecb1 * param str * throws استثناء */ static void method2 (String str) يرمي استثناء {keypairgenerator keygenerator = keypairgenerator.getInstance (key_algorithm) ؛ keypair keypair = keygenerator.generatekeypair () ؛ publickey = keypair.getPublic () ؛ privateKey = keypair.getPrivin () ؛ cipher = cipher.getInstance (key_algorithm) ؛ cipher.init (cipher.encrypt_mode ، privatekey) ؛ // بايت تشفير المفتاح الخاص [] encrypt = cipher.dofinal (str.getBytes ()) ؛ System.out.println ("تشفير المفتاح الخاص 2:" + صفائف. toString (Encrypt)) ؛ cipher.init (cipher.decrypt_mode ، publickey) ؛ // المفتاح العام decrypt byte [] decrypt = cipher.dofinal (encrypt) ؛ System.out.println ("المفتاح العمومي decrypt 2:" + سلسلة جديدة (decrypt)) ؛ }/** * تشفير المفتاح الخاص ، يستخدم فك تشفير المفاتيح العامة cipher_algorithm_ecb1 = rsa/ecb/pkcs1padding * @param str * athrows stisply */static void method3 (string str) استثناء {keypairgenerator keygenerator = keypairgeneratoratorator. keypair keypair = keygenerator.generatekeypair () ؛ publickey = keypair.getPublic () ؛ privateKey = keypair.getPrivin () ؛ cipher = cipher.getInstance (cipher_algorithm_ecb1) ؛ cipher.init (cipher.encrypt_mode ، privatekey) ؛ // بايت تشفير المفتاح الخاص [] encrypt = cipher.dofinal (str.getBytes ()) ؛ system.out.println ("تشفير المفتاح الخاص 3:" + صفائف. toString (Encrypt)) ؛ cipher.init (cipher.decrypt_mode ، publickey) ؛ // public key decryption byte [] decrypt = cipher.dofinal (encrypt) ؛ System.out.println ("3 بعد فك تشفير المفتاح العام:" + سلسلة جديدة (decrypt)) ؛ }} خوارزمية DSA والتوقيع الرقمي
يستخدم DSA بشكل عام للتوقيعات الرقمية وإصدار الشهادات.
DSA هو متغير من خوارزميات توقيع Schnorr و Elgamal ، ويستخدمه NIST في الولايات المتحدة كـ DSS (قياسي التوقيع الرقمي).
تعتمد DSA على مشكلة لوغاريتمية منفصلة المجال الصحيح ، وأمنها يشبه RSA.
في DSA Digital Signature والمصادقة ، يستخدم المرسل مفتاحه الخاص للتوقيع على ملف أو رسالة ، ويستخدم المستلم مفتاح المرسل العام للتحقق من صحة التوقيع بعد تلقي الرسالة. DSA هي مجرد خوارزمية ، والفرق بين RSA هو أنه لا يمكن استخدامه للتشفير وفك التشفير ، ولا للتبادل الرئيسي.
لتوقيعات فقط ، هو أسرع بكثير من RSA.
حزمة com.stone.security ؛ استيراد java.security.key ؛ استيراد java.security.keyfactory ؛ استيراد java.security.keypair ؛ استيراد java.security.keypairgenerator ؛ استيراد java.security.privatekey ؛ استيراد java.security.publickey ؛ استيراد java.security.securerandom ؛ استيراد java.security.Signature ؛ استيراد java.security.spec.pkcs8encodedkeyspec ؛ استيراد java.security.spec.x509encodedKeySpec ؛ استيراد java.util.hashmap ؛ استيراد java.util.map ؛ استيراد sun.misc.base64decoder ؛ استيراد sun.misc.base64encoder ؛ /*** خوارزمية توقيع DSA الرقمية هي متغير من خوارزميات توقيع Schnorr و Elgamal ، ويستخدم كـ DSS من قبل NIST في الولايات المتحدة. * باختصار ، هذه طريقة تحقيق أكثر تقدماً تستخدم كتوقيع رقمي. ليس فقط المفاتيح العامة والخاصة ، ولكن أيضا التوقيعات الرقمية. يولد تشفير المفتاح الخاص توقيعات رقمية وبيانات التحقق من المفاتيح العامة والتوقيعات. * إذا لم تتطابق البيانات والتوقيع ، فسيتم اعتبار التحقق من الفشل! وهذا هو ، لم يعد من الممكن تشفير البيانات قيد النقل. بعد حصول المتلقي على البيانات ، يحصل على المفتاح العام والتوقيع للتحقق مما إذا كانت البيانات صالحة. */ الفئة العامة DSA {/ ***ليس فقط يمكنك استخدام خوارزمية DSA ، ولكن يمكنك أيضًا استخدام خوارزمية RSA للتوقيعات الرقمية*/ سلسلة نهائية ثابتة key_algorithm = "RSA" ؛ Static Final String signature_algorithm = "md5withrsa" ؛*/ public static final string key_algorithm = "dsa" ؛ Signature_algorithm = "DSA" ؛ السلسلة النهائية الثابتة العامة default_seed = "$ ٪^*٪^() (hjg8awfjas7" ؛ // الافتراضي البذرة العامة static final string public_key = "dsapublickey" ؛ public static final string private_key = "dsaprivatekey" ؛ أنت*() _ + "؛ byte [] data = str.getBytes () ؛ خريطة <سلسلة ، كائن> keymap = initKey () ؛ // إنشاء key publickey publickey = (publickey) keymap.get (public_key) ؛ privatekey = (privatekey) keymap.get (private_key) ؛ system.out.println ( System.out.println ("تنسيق المفتاح العام:" + publickey.getFormat () ؛ تحقق 1) ؛ } / *** إنشاء مفتاح** Param Seed Seed* Key Key Object* @Throws استثناء* / خريطة ثابتة عامة <String ، Object> initKey (String Seed) Riseves {system.out.println ("إنشاء مفتاح") ؛ keypairgenerator keygen = keypairgenerator.getInstance (key_algorithm) ؛ SecurerAndom SecurerAndom = new SecurerAndom () ؛ SecurerAndom.setseed (seed.getBytes ()) ؛ يجب أن يتراوح حجم المعامل من 512 إلى 1024 ويكون مضاعفًا من 64 Keygen.Initialize (640 ، Securerandom) ؛ KEYPAIR KEYS = KEYGEN.GENKEYPAIR () ؛ PrivateKey PrivateKey = keys.getPrivate () ؛ publickey publickey = keys.getpublic () ؛ خريطة <string ، object> map = new hashmap <string ، Object> (2) ؛ map.put (public_key ، publickey) ؛ map.put (private_key ، privatekey) ؛ خريطة العودة } / *** قم بإنشاء مفتاح المفتاح الافتراضي** Key Key Conject* Throws استثناء* / خريطة ثابتة عامة <String ، Object> initKey () رمي الاستثناء {return initKey (default_seed) ؛ } / ** * احصل على المفتاح الخاص * * param keymap * return * @throws استثناء * / سلسلة ثابتة عامة getPrivateKey (خريطة <سلسلة ، كائن> keymap) رمي الاستثناء {key key = key) keymap.get (private_key) ؛ إرجاع encryptbase64 (key.getenCoded ()) ؛ // BASE64 Encryption key}/** * احصل على المفتاح العمومي * * param keymap * regurn * @Throws استثناء */سلسلة ثابتة عامة getPublicKey (خريطة <سلسلة ، كائن> keymap) يلقي استثناء {مفتاح المفتاح = (مفتاح) keymap.get (public_key) ؛ إرجاع encryptbase64 (key.getenCoded ()) ؛ . byte [] keybytes = decryptbase64 (privateKey) ؛ PKCS8ENCODEDKEYSPEC KEYSPEC = جديد PKCS8ENCODEDEDEKESPEC (keybytes) ؛ KeyFactory Factory = keyfactory.getInstance (key_algorithm) ؛ privatekey prikey = factory.generateprivate (keyspec) ؛ // إنشاء مفتاح خاص // digitsign مع توقيع توقيع المفتاح الخاص = signature.getInstance (signature_algorithm) ؛ signature.initsign (prikey) ؛ signature.update (البيانات) ؛ إرجاع encryptbase64 (signature.sign ()) ؛ } / *** BASE64ENCODER ENCRYPTION* PARAM بيانات البيانات ليتم تشفيرها* سلسلة مشفرة* / السلسلة الثابتة الخاصة encryptbase64 (BYTE [] DATA) {base64encoder encoder = new BASE64ENCODER () ؛ سلسلة encode = encoder.encode (data) ؛ ترميز الإرجاع ؛ } / *** BASE64DECODER DECRYPT* param سلسلة بيانات ليتم فك تشفيرها* byte decrypted byte []* @throws استثناء* / خاص بايت ثابت [] decryptbase64 (بيانات السلسلة) يلقي استثناء {base64decoder decoder = new base64decoder () ؛ byte [] buffer = decoder.decodeBuffer (data) ؛ إرجاع المخزن المؤقت } / *** تحقق من التوقيع الرقمي* param البيانات المشفرة البيانات* param publickey* param تسجيل التوقيع الرقمي* regurn* @Throws استثناء* / عام ثابت منطقي التحقق (Byte [] Data ، String PublicKey ، سلسلة السلسلة) استثناء {byte [] keybytes = decryptbase64 (publickey) ؛ X509EncodEdKeySpec Keyspec = جديد X509EncodEdKeySpec (keybytes) ؛ keyfactory keyfactory = keyfactory.getInstance (key_algorithm) ؛ publickey pubkey = keyfactory.generatepublic (keyspec) ؛ توقيع التوقيع = signature.getInstance (signature_algorithm) ؛ Signature.InitVerify (pubKey) ؛ signature.update (البيانات) ؛ إرجاع signature.verify (decryptbase64 (علامة)) ؛ // تحقق من التوقيع}}