JavaRush /جاوا بلاگ /Random-SD /جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف
Viacheslav
سطح

جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف

گروپ ۾ شايع ٿيل
ڊيٽا جي بدلي جي سيڪيورٽي جديد ايپليڪيشنن جي سڀ کان اهم ملڪيتن مان هڪ آهي. قديم زماني کان وٺي، ماڻهو چالاڪ طريقن سان گڏ آيا آهن، جيڪي انسانيت جي ترقي سان گڏ Cryptography جي پوري سائنس بڻجي ويا. قدرتي طور، جاوا هڪ طرف نه بيٺو ۽ ڊولپرز کي پيش ڪيو جاوا ڪرپٽوگرافي آرڪيٽيڪچر (JCA). اهو جائزو وٺڻ گهرجي ته اهو پهريون خيال ڪيئن ڪم ڪري ٿو.

اڳڪٿي

مان وقت ۾ واپس سفر ڪرڻ جو مشورو ڏيان ٿو. اسان جي اڳيان قديم روم آهي. ۽ اسان کان اڳ گيوس جوليس سيزر آهي، جيڪو پنهنجي ڪمانڊرن ڏانهن پيغام موڪلي ٿو. اچو ته ڏسون هن پيغام ۾ ڇا آهي:
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف - 2
هن جو مطلب ڇا ٿي سگهي ٿو "ЕСКЕУГЬГМХИФЯ Е УЛП":؟ اچو ته جاوا آن لائن ڪمپيلر کوليون، مثال طور: repl.it
class Main {
  public static void main(String[] args) {
    String code = "ЕСКЕУГЬГМХИФЯ Е УЛП";
    for (char symbol : code.toCharArray()) {
      if (symbol != ' ') {
        symbol = (char) (symbol - 3);
      }
      System.out.print(symbol);
    }
  }
}
اسان جي اڳيان سيزر سيفر جو آسان ترين عمل آهي. آڳاٽي رومن مورخ سوٽونيس جي ڪم موجب ”ٻارهن سيزرن جي زندگين“ جي عنوان سان، بلڪل ائين آهي جيئن سيزر پنهنجي جنرلن ڏانهن پيغامن کي ڳنڍي ڇڏيو. ۽ هي هڪ آهي قديم ترين حوالن مان هڪ اهڙي شيءِ جي استعمال لاءِ Cryptography . لفظ "cryptography" قديم يوناني لفظن "لڪيل" ۽ "لکيو" مان ورتل آهي، يعني. اهو رازداري ٽيڪنالاجي جي سائنس آهي. جاوا ڪرپٽوگرافي لاءِ پنهنجي مدد حاصل ڪري ٿو ۽ ان کي جاوا ڪرپٽوگرافي آرڪيٽيڪچر (JCA) سڏيو وڃي ٿو. تفصيل سرڪاري دستاويزن ۾ ڳولهي سگھجي ٿو Oracle - " Java Cryptography Architecture (JCA) ". مان توهان کي صلاح ڏيان ٿو ته اسان کي ڪهڙا موقعا ملن ٿا JCA جي مهرباني.
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف - 3

J.C.A

جيئن اسان اڳ ۾ سکيو، جاوا پيش ڪري ٿو جاوا ڪرپٽوگرافي آرڪيٽيڪچر (JCA) ڪرپٽوگرافي سان ڪم ڪرڻ لاءِ. هي فن تعمير هڪ API تي مشتمل آهي (يعني انٽرفيس جو هڪ خاص سيٽ) ۽ فراهم ڪندڙ (جيڪي انهن کي لاڳو ڪن ٿا):
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف - 4
جيئن ته دستاويز چوي ٿو، " جاوا پليٽ فارم ۾ شامل آهن ڪيترن ئي ٺاهيل مهيا ڪندڙ ". اهو آهي، جاوا پليٽ فارم مهيا ڪري ٿو ٺهيل مهيا ڪندڙن جو هڪ سيٽ جيڪو ضروري هجي ته وڌايو وڃي. توھان ھي پاڻ لاء ڏسي سگھو ٿا:
import java.security.Provider;
import java.security.Security;
class Main {
  public static void main(String[] args) {
    Provider[] providers = Security.getProviders();
    for (Provider p : providers) {
      System.out.println(p.getName());
    }
  }
}
ٽئين پارٽي فراهم ڪندڙ کي رجسٽر ڪرڻ تمام آسان آهي. مثال طور: Security.addProvider(new BouncyCastleProvider()); هي مثال هڪ تمام مشهور مهيا ڪندڙن مان هڪ سان ڳنڍي ٿو - BouncyCastle . پر هن جائزي ۾ اسان صرف بنيادي اوزار استعمال ڪنداسين، ٽئين پارٽي جي لائبريرين کان سواء. اسان جو مکيه دستاويز: " Java Cryptography Architecture (JCA) ". سمجھڻ سان ته JCA ڪيئن ڪم ڪري ٿي توھان کي وڌيڪ آسانيءَ سان سمجھڻ ۾ مدد ملندي ٽيڪنالاجيون جن ۾ ھي ساڳي JCA فعال طور استعمال ٿيل آھي. مثال طور: HTTPS (ڏسو " HTTP کان HTTPS تائين ").
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف - 5

MessageDigest

JCA دستاويزن ۾ ذڪر ڪيل پهرين شيء آهي MessageDigest. عام طور تي، روسي ۾ ڊائجسٽ ساڳيو هوندو - هڪ ڊائجسٽ معني ۾ "تت" سان ملندو آهي. پر cryptography ۾، هڪ هضم هڪ هيش رقم آهي. توهان اهو به آساني سان ياد ڪري سگهو ٿا ته انگريزيء ۾ ڊائجسٽ پڻ ترجمو ڪري سگهجي ٿو. وڌيڪ تفصيل ملي سگھن ٿا JCA دستاويزن ۾ " MessageDigest " سيڪشن ۾. جيئن دستاويز چوي ٿو، MessageDigest هڪ مقرر ٿيل ماپ جو نتيجو ٺاهي ٿو جنهن کي ڊائجسٽ يا هيش سڏيو ويندو آهي. Hashing هڪ طرفي فنڪشن آهي، يعني. جيڪڏهن اسان ڪنهن شيءِ کي هيش ڪيو ته پوءِ نتيجي مان (يعني هيش مان) اسان اصل ماخذ حاصل نٿا ڪري سگهون. پر جيڪڏهن هڪجهڙا شيون هيش ڪيون وينديون آهن (مثال طور، هڪجهڙا اکرن جا تار)، ته پوءِ انهن جو هيش ضرور ملندو. جيئن ته دستاويز ۾ بيان ڪيو ويو آهي، اهڙي هيش ڪڏهن ڪڏهن ڊيٽا جي "چيڪسم" يا "ڊجيٽل فنگر پرنٽ" پڻ سڏيو ويندو آهي. Hashing مختلف الگورتھم استعمال ڪندي پرفارم ڪري سگهجي ٿو. دستياب الگورتھم دستاويز ۾ ڏسي سگھجي ٿو " Java Cryptography Architecture Standard Algorithm Name Documentation for JDK 8 ". اچو ته هيشنگ ڪريون ۽ هيش کي ڪنسول تي پرنٽ ڪريون:
import javax.xml.bind.DatatypeConverter;
import java.security.*;
public class Main {
  public static void main(String[] args) {
    try {
      MessageDigest digester = MessageDigest.getInstance("SHA-512");
      byte[] input = "Secret string".getBytes();
      byte[] digest = digester.digest(input);
      System.out.println(DatatypeConverter.printHexBinary(digest));
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalStateException(e);
    }
  }
}
هاشنگ ڪارائتو ٿي سگهي ٿو، مثال طور، جڏهن پاسورڊ محفوظ ڪرڻ. جيئن ته داخل ٿيل پاسورڊ جي هيش اڳ ۾ محفوظ ڪيل هيش جي خلاف چيڪ ڪري سگهجي ٿي. جيڪڏهن هيش ملن ٿا، ته پاسورڊ پڻ ملن ٿا. اڃا به وڌيڪ محفوظ هيشنگ لاءِ، ”نمڪ“ نالي هڪ تصور استعمال ڪيو ويندو آهي. لوڻ استعمال ڪري سگھجي ٿو SecureRandom ڪلاس استعمال ڪندي . هضم جي طريقي تي عمل ڪرڻ کان اڳ، اچو ته بيان ڪريون "لوڻ" شامل ڪرڻ:
byte[] salt = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(salt);
digester.update(salt);
پر hash هڪ طرفي فنڪشن آهي. پر ڇا جيڪڏھن توھان چاھيو ٿا ته انڪريپٽ ۽ ڊڪرپٽ ڪرڻ جي قابل؟
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف - 6

Symmetric key cryptography

Symmetric encryption is ancryption جيڪا ساڳي ڪيئي استعمال ڪري ٿي انڪريپشن ۽ ڊيڪرپشن لاءِ. symmetric encryption استعمال ڪرڻ لاءِ اسان کي چاٻي جي ضرورت آھي. ان کي حاصل ڪرڻ لاءِ اسان استعمال ڪريون ٿا KeyGenerator . ان کان علاوه، اسان کي هڪ طبقي جي ضرورت پوندي جيڪا هڪ cipher ( Cipher ) جي نمائندگي ڪري ٿي. جيئن بيان ڪيو ويو آهي JCA دستاويزن ۾ سيڪشن ۾ “ Creating a Cipher Object ”، هڪ Cipher ٺاهڻ لاءِ توهان کي نه رڳو هڪ الگورٿم، پر لائن ۾ هڪ “تبديلي” بيان ڪرڻ جي ضرورت آهي. تبديلي جي وضاحت هن طرح نظر اچي ٿي: "الگورٿم/موڊ/پيڊنگ":
  • Algorithm : هتي اسان معياري نالن کي ڏسون ٿا “ Cipher (Encryption) Algorithms ”. اهو AES استعمال ڪرڻ جي صلاح ڏني آهي.
  • موڊ : انڪرپشن موڊ. مثال طور: ECB يا CBC (اسان ان بابت ٿوري دير بعد ڳالهائينداسين)
  • Indentation/Split : ڊيٽا جي هر بلاڪ کي الڳ الڳ انڪرپٽ ڪيو ويو آهي. هي پيٽرولر اهو طئي ڪري ٿو ته ڪيتري ڊيٽا کي 1 بلاڪ طور شمار ڪيو ويندو آهي.
مثال طور، ھيٺ ڏنل تبديلي وٺو: "AES/ECB/PKCS5Padding". اهو آهي، انڪرپشن الگورٿم AES آهي، انڪريپشن موڊ ECB آهي (اليڪٽرانڪ ڪوڊ بڪ لاءِ مختصر)، بلاڪ سائيز PKCS5Padding آهي. PKCS5Padding چوي ٿو ته ھڪڙي بلاڪ جي ماپ 2 بائيٽ (16 بٽ) آھي. اليڪٽرانڪ ڪوڊ بڪ انڪرپشن موڊ ۾ شامل آهي هر بلاڪ جي ترتيب وار انڪرپشن:
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف - 7
اهو ڪوڊ ۾ هن طرح نظر اچي سگهي ٿو:
import javax.xml.bind.DatatypeConverter;
import javax.crypto.*;
import java.security.Key;
public class Main {
  public static void main(String[] args) throws Exception {
    String text = "secret!!secret!!secret!!secret!!";
    // Generate new key
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    keygen.init(256);
    Key key = keygen.generateKey();
    // Encrypt with key
    String transformation = "AES/ECB/PKCS5Padding";
    Cipher cipher = Cipher.getInstance(transformation);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] encrypted = cipher.doFinal(text.getBytes());
    System.out.println(DatatypeConverter.printHexBinary(encrypted));
    // Decrypt with key
    cipher.init(Cipher.DECRYPT_MODE, key);
    String result = new String(cipher.doFinal(encrypted));
    System.out.println(result);
  }
}
جيڪڏهن اسان عمل ڪريون ٿا، اسان کي ٻيهر ڏسڻ جي اميد ڪنداسين، ڇاڪاڻ ته اسان 32 اکرن کي بيان ڪيو. اهي ڪردار 16 بٽ جا 2 بلاڪ ٺاهيندا آهن:
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف - 8
هن حالت ۾ ٻيهر هلائڻ کان بچڻ لاء، توهان کي ٻيو طريقو استعمال ڪرڻ گهرجي - Cipher Block Chaining (CBC). هي موڊ شروعاتي ویکٹر جي تصور کي متعارف ڪرايو آهي (IvParameterSpec ڪلاس جي نمائندگي ڪندي). ۽ پڻ هن موڊ جي مهرباني، آخري بلاڪ پيدا ڪرڻ جو نتيجو ايندڙ هڪ پيدا ڪرڻ لاء استعمال ڪيو ويندو:
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف - 9
اچو ته ھاڻي ھن کي ڪوڊ ۾ لکون:
import javax.xml.bind.DatatypeConverter;
import javax.crypto.*;
import java.security.*;
import javax.crypto.spec.IvParameterSpec;
public class Main {
  public static void main(String[] args) throws Exception {
    // Initialization Vector
    SecureRandom random = SecureRandom.getInstanceStrong();
    byte[] rnd = new byte[16];
    random.nextBytes(rnd);
    IvParameterSpec ivSpec = new IvParameterSpec(rnd);
    // Prepare key
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    keygen.init(256);
    Key key = keygen.generateKey();
    // CBC
    String text = "secret!!secret!!secret!!secret!!";
    String transformation = "AES/CBC/PKCS5Padding";
    Cipher cipher = Cipher.getInstance(transformation);
    cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
    byte[] enc = cipher.doFinal(text.getBytes());
    System.out.println(DatatypeConverter.printHexBinary(enc));
    // Decrypt
    cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
    String result = new String(cipher.doFinal(enc));
    System.out.println(result);
  }
}
جيئن اسان ڏسون ٿا، نتيجي طور اسان کي بار بار سائفر بلاڪ نظر نه ٿا اچن. انهي سبب لاء، ECB موڊ جي سفارش نه ڪئي وئي آهي، ڇاڪاڻ ته اهو ممڪن بڻائي ٿو ته ورجائي ڏسڻ ۽ هن علم کي استعمال ڪرڻ لاء استعمال ڪريو. ECB ۽ CBC بابت وڌيڪ معلومات لاءِ، مان توهان کي مواد پڙهڻ جي صلاح ڏيان ٿو: “ اليڪٽرانڪ ڪوڊ بڪ موڊ ”. پر symmetric encryption ۾ هڪ واضح مسئلو آهي - توهان کي ڪنهن نه ڪنهن طريقي سان چاٻي کي منتقل ڪرڻ جي ضرورت آهي جيڪو انڪرپٽ ڪري ٿو ان کي جيڪو انڪرپٽ ڪري ٿو. ۽ ھن رستي سان، ھن ڪنجي کي روڪي سگھجي ٿو ۽ پوءِ ڊيٽا کي مداخلت ڪرڻ ممڪن ٿيندو. ۽ asymmetric encryption هن مسئلي کي حل ڪرڻ لاء ٺهيل آهي.
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف - 10

غير متناسب انڪرپشن

Asymmetric encryption يا Public-key cryptography هڪ انڪرپشن جو طريقو آهي جيڪو استعمال ڪري ٿو هڪ جوڙو جوڙو: هڪ خانگي ڪي (هر ڪنهن کان ڳجهي رکيل) ۽ هڪ عوامي ڪيئي (عوام لاءِ دستياب). هي علحدگي ضروري آهي ته محفوظ طور تي پارٽين جي وچ ۾ عوامي ڪنجي کي معلومات جي تبادلي لاء، جڏهن ته رازداري چاٻي کي محفوظ رکڻ لاء. جڏهن هڪ اهم جوڙو ٺاهي، KeyGenerator هاڻي اسان لاء ڪافي نه آهي؛ اسان کي KeyPairGenerator جي ضرورت آهي . اچو ته هڪ مثال ڏسو:
import javax.crypto.*;
import java.security.*;
public class Main {
  public static void main(String[] args) throws Exception {
    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
    generator.initialize(1024);
    KeyPair keyPair = generator.generateKeyPair();
    // Encrypt with PRIVATE KEY
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
    byte[] data = cipher.doFinal("Hello!".getBytes());
    // Decrypt with PUBLIC KEY
    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
    byte[] result = cipher.doFinal(data);
    System.out.println(new String(result));
  }
}
ھتي اھو سمجھڻ ضروري آھي ته جڏھن بي ترتيب انڪرپشن استعمال ڪريون ٿا، اسين ھميشه ڪيپيئر استعمال ڪندا آھيون ھڪڙي ڪيئي کي انڪرپشن لاءِ ۽ ٻي ڪي ڊيڪرپشن لاءِ. پر ڇاڪاڻ ته انڪريپشن جو نقطو اهو آهي ته صرف وصول ڪندڙ ان کي رد ڪري سگهي ٿو؛ اهو هڪ عوامي ڪني سان انڪرپٽ ڪيو ويو آهي، ۽ صرف هڪ خانگي سان ڊريڪٽ ڪيو ويو آهي.
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون واقفيت - 11

ڊجيٽل دستخط

جيئن اسان مٿي ڏٺو، عوامي ڪني کي ڄاڻڻ سان، توهان ڊيٽا موڪلي سگهو ٿا ته جيئن صرف پرائيويٽ ڪني جو مالڪ ان کي رد ڪري سگهي. اهو آهي، غير متناسب انڪرپشن جو جوهر اهو آهي ته ڪو به انڪرپٽ ڪري ٿو، پر صرف اسان پڙهون ٿا. هتي هڪ ريورس پروسيس پڻ آهي - هڪ ڊجيٽل دستخط، نمائندگي ڪندڙ دستخط طبقي طرفان . هڪ ڊجيٽل دستخط هيٺ ڏنل الگورتھم استعمال ڪري سگھن ٿا: " دستخط الگورٿم ". JCA دستاويزن انھن ٻنھي تي ويجھي نظر رکڻ جي صلاح ڏني آھي: DSAwithMD5 ۽ RSAwithMD5 ڇا آھي DSA يا RSA کان بھتر آھي ۽ انھن جو فرق ڇا آھي توھان ھتي پڙھي سگھو ٿا: " Encrypted File Transfers لاءِ ڪھڙو ڪم چڱو آھي - RSA يا DSA؟ " يا هتي بحث پڙهو: " RSA بمقابله DSA SSH تصديق واري ڪيز لاءِ ". تنهن ڪري، ڊجيٽل دستخط. اسان کي ضرورت پوندي، اڳ وانگر، هڪ KeyPair ۽ هڪ نئون دستخط ڪلاس. جيڪڏهن توهان هينئر تائين آن لائن ڪمپلرز ۾ آزمايا آهيو، ته پوءِ هيٺ ڏنل مثال انهن لاءِ ڪجهه ڏکيو ٿي سگهي ٿو. منهنجو مثال صرف هتي هليو ويو: rextester.com . اسان ڪلاس درآمد ڪريون ٿا جيڪي اسان کي گهرجن:
import javax.crypto.*;
import java.security.*;
اسان پڻ مکيه طريقي سان ٻيهر لکنداسين:
public static void main(String[] args) throws Exception {
    // Generate keys
    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
    SecureRandom random = SecureRandom.getInstanceStrong();
    generator.initialize(2048, random);
    KeyPair keyPair = generator.generateKeyPair();
    // Digital Signature
    Signature dsa = Signature.getInstance("SHA256withRSA");
    dsa.initSign(keyPair.getPrivate());
    // Update and sign the data
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
    byte[] data = cipher.doFinal("Hello!".getBytes());
    dsa.update(data);
    byte[] signature = dsa.sign();
    // Verify signature
    dsa.initVerify(keyPair.getPublic());
    dsa.update(data);
    boolean verifies = dsa.verify(signature);
    System.out.println("Signature is ok: " + verifies);
    // Decrypt if signature is correct
    if (verifies) {
      cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
      byte[] result = cipher.doFinal(data);
      System.out.println(new String(result));
    }
}
اهو ڪيئن هڪ ڊجيٽل دستخط ڪم ڪندو آهي. ڊجيٽل دستخط هڪ دلچسپ موضوع آهي. مان توهان کي صلاح ڏيان ٿو ته هن موضوع تي رپورٽ ڏسو:
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهرين واقفيت - 12
مٿي اسان ڏٺو ته ڪئين پارٽيون ڊيٽا مٽائي. ڇا JCA ۾ مهيا ڪيل هن رابطي لاءِ ڪو معياري انٽرفيس ناهي؟ اهو ظاهر ٿئي ٿو ته اتي آهي. اچو ته ان تي نظر وجهون.
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون واقفيت - 13

اهم معاهدو

جاوا ڪرپٽوگرافي آرڪيٽيڪچر هڪ اهم اوزار متعارف ڪرايو آهي - اهم معاهدو هڪ پروٽوڪول آهي. اهو KeyAgreement طبقي جي نمائندگي ڪري ٿو . جيئن JCA دستاويزن ۾ بيان ڪيو ويو آهي، هي پروٽوڪول ڪيترن ئي پارٽين کي اجازت ڏئي ٿو ته پارٽين جي وچ ۾ ڪنهن به ڳجهي معلومات شيئر ڪرڻ کان سواءِ ساڳي ڪرپٽوگرافڪ ڪيچ سيٽ ڪرڻ. عجيب آواز؟ پوء اچو ته هڪ مثال ڏسو:
// 1. Одна из сторон (Алиса) генерирует пару ключей. Encoded публичный ключ отдаёт.
KeyPairGenerator generator = KeyPairGenerator.getInstance("DH");
KeyPair aliceKeyPair = generator.generateKeyPair();
byte[] alicePubKeyEncoded = aliceKeyPair.getPublic().getEncoded();

// 2. Другая сторона (например, Боб) получает открытый ключ Алисы
KeyFactory bobKeyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(alicePubKeyEncoded);
PublicKey alicePubKey = bobKeyFactory.generatePublic(x509KeySpec);
// Параметры, которые использовала Алиса при генерации ключей
DHParameterSpec dhParamFromAlicePubKey = ((DHPublicKey)alicePubKey).getParams();
// Создаёт свою пару ключей. Отдаёт свой Encoded открытый ключ
KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");
bobKpairGen.initialize(dhParamFromAlicePubKey);
KeyPair bobKeyPair = bobKpairGen.generateKeyPair();
byte[] bobPubKeyEncoded = bobKeyPair.getPublic().getEncoded();

Теперь, у Алисы есть открытый ключ Боба, а у Боба есть открытый ключ Алисы. What дальше?
Как сказано в documentации JCA, у нас есть инструмент KeyAgreement, https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#KeyAgreement который позволяет установить одинаковые ключи шифрования без необходимости обмениваться секретной информацией (т.е. без обмена private key). Соглашение выглядит следующим образом:
// 3. Соглашение по протоколу Диффи-Хеллмана (Diffie–Hellman, DH)
KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");
aliceKeyAgree.init(aliceKeyPair.getPrivate());
// Алиса на основе ключа боба и своего private key создаёт общий shared ключ
KeyFactory aliceKeyFactory = KeyFactory.getInstance("DH");
x509KeySpec = new X509EncodedKeySpec(bobPubKeyEncoded);
PublicKey bobPubKey = aliceKeyFactory.generatePublic(x509KeySpec);
aliceKeyAgree.doPhase(bobPubKey, true);
byte[] aliceSharedSecret = aliceKeyAgree.generateSecret();
SecretKeySpec aliceAesKey = new SecretKeySpec(aliceSharedSecret, 0, 16, "AES");
// Боб на основе ключа Алисы и своего private key создаёт общий shared ключ
KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");
bobKeyAgree.init(bobKeyPair.getPrivate());
bobKeyAgree.doPhase(alicePubKey, true);
byte[] bobSharedSecret = bobKeyAgree.generateSecret();
SecretKeySpec bobAesKey = new SecretKeySpec(bobSharedSecret, 0, 16, "AES");
// Общий ключ у Алисы и Боба одинаков
System.out.println("Shared keys are equals: " + Arrays.equals(aliceSharedSecret, bobSharedSecret));

Далее Боб и Алиса, используя общий ключ, про который больше никто не знает, обмениваются зашифрованными данными:
// 4. Боб шифрует сообщение для Алисы
Cipher bobCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
bobCipher.init(Cipher.ENCRYPT_MODE, bobAesKey);
byte[] ciphertext = bobCipher.doFinal("Hello, Alice!".getBytes());
// Передаёт Алисе параметры, с которыми выполнялась шифровка
byte[] encodedParamsFromBob = bobCipher.getParameters().getEncoded();

// 5. Алиса принимает сообщение и расшифровывает его
AlgorithmParameters aesParams = AlgorithmParameters.getInstance("AES");
aesParams.init(encodedParamsFromBob);
Cipher aliceCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
aliceCipher.init(Cipher.DECRYPT_MODE, aliceAesKey, aesParams);
byte[] recovered = aliceCipher.doFinal(ciphertext);
System.out.println(new String(recovered));
هي مثال JCA دستاويزي مثال مان ورتو ويو آهي: " Diffie-Hellman Key Exchange between 2 Parties ". اهو لڳ ڀڳ اهو آهي ته جيئن ڪيئي معاهدي پروٽوڪول کي استعمال ڪندي جاوا ڪرپٽوگرافي آرڪيٽيڪچر ۾ غير متناسب انڪرپشن نظر اچي ٿي. غير متناسب انڪرپشن بابت وڌيڪ معلومات لاءِ، تجويز ڪيل وڊيوز:
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهرين واقفيت - 14

سرٽيفڪيٽ

خير، شيرين لاء اسان وٽ اڃا تائين ڪجھ به گهٽ اهم ناهي - سرٽيفڪيٽ. عام طور تي، سرٽيفڪيٽ ٺاهيا ويندا آهن استعمال ڪندي ڪيٽول يوٽيليٽي شامل آهن jdk سان. توھان وڌيڪ تفصيل پڙھي سگھو ٿا، مثال طور، ھتي: " Java keytool ڪمانڊ استعمال ڪندي ھڪڙو خود دستخط ٿيل SSL سرٽيفڪيٽ ٺاھيو ". توھان پڻ پڙھي سگھو ٿا دستورالعمل Oracle مان. مثال طور، هتي: " سرور سرٽيفڪيٽ ٺاهڻ لاءِ ڪيٽول استعمال ڪرڻ لاءِ ". مثال طور، اچو ته استعمال ڪريون Tutorialspoint Java Online Compiler :
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.*;
import java.security.cert.*;
import java.security.*;
// Compiler args: -XDignore.symbol.file
public class Main {
  public static void main(String[] args) throws Exception {
    CertAndKeyGen certGen = new CertAndKeyGen("RSA", "SHA256WithRSA", null);
    // generate it with 2048 bits
    certGen.generate(2048);
    PrivateKey privateKey = certGen.getPrivateKey();
    X509Key publicKey = certGen.getPublicKey();
    // prepare the validity of the certificate
    long validSecs = (long) 365 * 24 * 60 * 60; // valid for one year
    // enter your details according to your application
    X500Name principal = new X500Name("CN=My Application,O=My Organisation,L=My City,C=DE");
    // add the certificate information, currently only valid for one year.
    X509Certificate cert = certGen.getSelfCertificate(principal, validSecs);
    // Public Key from Cert equals Public Key from generator
    PublicKey publicKeyFromCert = cert.getPublicKey();
    System.out.println(publicKeyFromCert.equals(publicKey));
  }
}
جيئن اسان ڏسي سگهون ٿا، هڪ سند مهيا ڪري ٿي عوامي ڪيچ مهيا ڪرڻ جي صلاحيت. هن طريقي ۾ هڪ خرابي آهي - اسان استعمال ڪريون ٿا sun.security، جيڪو خطرناڪ سمجهيو ويندو آهي، ڇاڪاڻ ته ... هي پيڪيج عوامي Java API جو حصو ناهي. اهو ئي سبب آهي ته تاليف جي دوران اهو ضروري آهي ته پيٽرولر جي وضاحت ڪرڻ - XDignore.symbol.file. اتي هڪ ٻيو طريقو آهي - دستي طور هڪ سرٽيفڪيٽ ٺاهڻ لاء. نقصان اهو آهي ته اهو هڪ اندروني API استعمال ڪري ٿو جيڪو دستاويز نه ڪيو ويو آهي. تنهن هوندي به، ان جي باري ۾ ڄاڻڻ لاء مفيد آهي. گهٽ ۾ گهٽ، ڇاڪاڻ ته اهو واضح طور تي نظر اچي ٿو ته RFC-2459 وضاحت ڪيئن استعمال ٿئي ٿي: " Internet X.509 پبلڪ ڪيئي انفراسٽرڪچر ". هتي هڪ مثال آهي:
// 1. Генерируем пару ключей
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 2. Определяем данные сертификата
// Определяем срок действия сертификата
Date from = new Date();
Date to = new Date(from.getTime() + 365 * 1000L * 24L * 60L * 60L);
CertificateValidity interval = new CertificateValidity(from, to);
// Определяем subject name, т.е. Name того, с чем ассоциирован публичный ключ
// CN = Common Name. Через точку с запятой могут быть указаны также другие атрибуты
// См. https://docs.oracle.com/cd/E24191_01/common/tutorials/authz_cert_attributes.html
X500Name owner = new X500Name("cn=Unknown");
// Уникальный в пределах CA, т.е. Certificate Authority (тот, кто выдаёт сертификат) номер
BigInteger number = new BigInteger(64, new SecureRandom());
CertificateSerialNumber serialNumber = new CertificateSerialNumber(number);
// Определяем алгоритм подписи сертификата
AlgorithmId algorithmId = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
CertificateAlgorithmId certificateAlgorithmId = new CertificateAlgorithmId(algorithmId);
// 3. По подготовленной информации создаём сертификат
X509CertInfo info = new X509CertInfo();
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, serialNumber);
info.set(X509CertInfo.SUBJECT, owner);
info.set(X509CertInfo.ISSUER, owner);
info.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
info.set(X509CertInfo.ALGORITHM_ID, certificateAlgorithmId);
// 4. Подписываем сертификат
X509CertImpl certificate = new X509CertImpl(info);
certificate.sign(keyPair.getPrivate(), "SHA256withRSA");
// 5. Проверка сертификата
try {
	// В случае ошибки здесь будет брошено исключение. Например: java.security.SignatureException
	certificate.verify(keyPair.getPublic());
} catch (Exception e) {
	throw new IllegalStateException(e);
}
جاوا ڪرپٽوگرافي آرڪيٽيڪچر: پهريون تعارف - 15

ڪي اسٽور (ڪي اسٽور)

آخري شيء جنهن بابت مان ڳالهائڻ چاهيندس اهو آهي ڪيئي ۽ سرٽيفڪيٽ اسٽور، جنهن کي KeyStore سڏيو ويندو آهي. اهو واضح آهي ته مسلسل سرٽيفڪيٽ ۽ چابيون پيدا ڪرڻ مهانگو ۽ بي مقصد آهي. تنهن ڪري، انهن کي ڪنهن به طريقي سان محفوظ ڪرڻ جي ضرورت آهي. ھن لاء ھڪڙو اوزار آھي - KeyStore. اهم اسٽور کي JCA دستاويزن ۾ " KeyManagement " باب ۾ بيان ڪيو ويو آهي. ان سان گڏ ڪم ڪرڻ لاء API بلڪل واضح آهي. هتي هڪ ننڍڙو مثال آهي:
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
String alias = "EntityAlias";
java.security.cert.Certificate[] chain = {certificate};
keyStore.setKeyEntry(alias, keyPair.getPrivate(), "keyPassword".toCharArray(), chain);
// Загрузка содержимого (Private Key + Certificate)
Key key = keyStore.getKey(alias, "keyPassword".toCharArray());
Certificate[] certificateChain = keyStore.getCertificateChain(alias);
// Сохранение KeyStore на диск
File file = File.createTempFile("security_", ".ks");
System.out.println(file.getAbsolutePath());
try (FileOutputStream fos = new FileOutputStream(file)) {
	keyStore.store(fos, "keyStorePassword".toCharArray());
}
جئين توهان مثال مان ڏسي سگهو ٿا، اهو پهريون ڀيرو loadKeyStore لاء عمل ڪيو ويو آهي. پر اسان جي صورت ۾، اسان پهريون وصف null طور بيان ڪيو آهي، يعني. KeyStore لاءِ ڪوبه ذريعو ناهي. هن جو مطلب آهي ته KeyStore خالي ٺهيل آهي انهي کي وڌيڪ بچائڻ لاءِ. ٻيو پيٽرولر پڻ null آهي، ڇاڪاڻ ته اسان هڪ نئون KeyStore ٺاهي رهيا آهيون. جيڪڏهن اسان هڪ فائل مان KeyStore لوڊ ڪري رهيا هئاسين، پوء اسان کي هتي پاسورڊ بيان ڪرڻ جي ضرورت پوندي (جهڙوڪ KeyStore طريقي سان سڏيو ويندو آهي اسٽور).

هيٺين لائن

تنهن ڪري اسان توهان سان گڏ جائزو ورتو آهي سڀ کان وڌيڪ بنيادي ۽ ابتدائي ڪارناما جاوا ڪرپٽوگرافي آرڪيٽيڪچر (اڪا JCA) جي فريم ورڪ اندر. اسان ڏٺو ته symmetric and asymmetric encryption ڇا آهي ۽ JCA ۾ ان کي ڪيئن لاڳو ڪيو وڃي ٿو. اسان ڏٺو ته سرٽيفڪيٽ ۽ ڊجيٽل دستخط ڪيئن ٺاهيا ويا آهن ۽ اهي ڪيئن استعمال ڪيا ويا آهن. اهي سڀ صرف بنيادي آهن، جن جي پويان ڪيتريون ئي پيچيده ۽ دلچسپ شيون آهن. مون کي اميد آهي ته هي جائزو مواد مفيد ثابت ٿيندو ۽ توهان کي هن علائقي جي وڌيڪ مطالعي ۾ دلچسپي وٺندي.
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION