JavaRush /Блоги Java /Random-TG /Архитектураи криптографияи Java: Муқаддимаи аввал
Viacheslav
Сатҳи

Архитектураи криптографияи Java: Муқаддимаи аввал

Дар гурӯҳ нашр шудааст
Амнияти мубодилаи маълумот яке аз хосиятҳои муҳимтарини замимаҳои муосир мебошад. Аз замонҳои қадим одамон усулҳои маккоронаеро ба вуҷуд меоранд, ки бо рушди инсоният ба тамоми илми криптография табдил ёфтанд. Табиист, ки Java дар канор наистод ва ба таҳиягарон меъмории Java Cryptography (JCA) пешниҳод кард. Ин барраси бояд фикри аввал дар бораи он ки чӣ тавр кор мекунад, диҳад.

Сарсухан

Ман пешниҳод мекунам, ки дар вақтҳо сафар кунам. Дар пеши мо Рими Қадим аст. Ва дар пеши мо Гай Юлий Цезар аст, ки ба фармондеҳони худ паём мефиристад. Биёед бубинем, ки дар ин паём чӣ гуфта шудааст:
Архитектураи криптографияи Java: Муқаддимаи аввал - 2
Ин чӣ маъно дошта метавонад "ЕСКЕУГЬГМХИФЯ Е УЛП":? Биёед Java Online Compiler -ро кушоем, масалан: 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);
    }
  }
}
Дар пеши мо соддатарин татбиқи Cipher аст. Тибқи асари муаррихи Рими қадим Светоний таҳти унвони «Зиндагии дувоздаҳ қайсар», маҳз ҳамин тавр Сезар паёмҳоро ба сарбозони худ шифр кардааст. Ва ин яке аз истинодҳои қадимтарин дар бораи истифодаи чунин чизе ба монанди криптография мебошад . Калимаи «криптография» аз калимаҳои юнонии қадим «пинҳон» ва «навиштан», яъне. он илми техникаи махфият аст. Java барои криптография дастгирии худро дорад ва онро Java Cryptography Architecture (JCA) меноманд. Тавсифи онро дар ҳуҷҷатҳои расмии Oracle пайдо кардан мумкин аст - " Java Cryptography Architecture (JCA) ". Ман тавсия медиҳам, ки бубинед, ки мо ба шарофати JCA чӣ гуна имкониятҳоро ба даст меорем.
Архитектураи криптографияи Java: Муқаддимаи аввал - 3

J.C.A.

Тавре ки мо қаблан фаҳмидем, Java меъмории Java Cryptography Architecture (JCA) -ро барои кор бо криптография пешниҳод мекунад. Ин меъморӣ дорои API (яъне маҷмӯи муайяни интерфейсҳо) ва провайдерҳо (ки онҳоро амалӣ мекунанд):
Архитектураи криптографияи Java: Муқаддимаи аввал - 4
Тавре ки ҳуҷҷатҳо мегӯянд, " Платформаи Java як қатор провайдерҳои дарунсохтро дар бар мегирад ". Яъне, платформаи Java маҷмӯи провайдерҳои дарунсохтро пешниҳод мекунад, ки дар ҳолати зарурӣ васеъ карда мешаванд. Шумо метавонед инро худатон бубинед:
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 ").
Архитектураи криптографияи Java: Муқаддимаи аввал - 5

MessageDigest

Аввалин чизе, ки дар ҳуҷҷатҳои JCA зикр шудааст, MessageDigest мебошад. Дар маҷмӯъ, Дайҷест дар забони русӣ якхела хоҳад буд - дайджест ба маънои "резонанс" мувофиқат мекунад. Аммо дар криптография, дайджест маблағи ҳаш аст. Шумо инчунин метавонед ба осонӣ дар хотир доред, ки Digest-ро ба забони англисӣ ҳамчун дайҷест низ тарҷума кардан мумкин аст. Тафсилоти бештарро дар ҳуҷҷатҳои JCA дар бахши " MessageDigest " пайдо кардан мумкин аст. Тавре ки дар ҳуҷҷатҳо гуфта мешавад, MessageDigest натиҷаи андозаи муайянеро тавлид мекунад, ки ҳаш ё ҳаш ном дорад. Hashing вазифаи яктарафа аст, яъне. агар мо чизеро ҳаш карда бошем, пас аз натиҷа (яъне аз ҳаш) мо манбаи аслиро гирифта наметавонем. Аммо агар an objectҳои якхела (масалан, сатрҳои аломатҳои якхела) ҳаш карда шуда бошанд, пас хэши онҳо бояд мувофиқат кунад. Тавре ки дар ҳуҷҷатҳо гуфта шудааст, чунин хэшро баъзан "маблағи чек" ё "изи ангуштони рақамӣ"-и маълумот низ меноманд. Хешро бо истифода аз алгоритмҳои гуногун иҷро кардан мумкин аст. Алгоритмҳои дастрасро дар ҳуҷҷати " Java Cryptography Architecture 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);
    }
  }
}
Hashing метавонад муфид бошад, масалан, ҳангоми нигоҳ доштани паролҳо. Азбаски хэши пароли воридшударо метавон нисбат ба хэши қаблан захирашуда тафтиш кард. Агар хэшҳо мувофиқат кунанд, пас парол низ мувофиқат мекунад. Барои боз ҳам бехатартар ҳашинг, мафҳуми "намак" истифода мешавад. Намакро бо истифода аз синфи SecureRandom амалӣ кардан мумкин аст . Пеш аз иҷрои усули ҳазм, биёед илова кардани "намак"-ро тавсиф кунем:
byte[] salt = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(salt);
digester.update(salt);
Аммо хэш функсияи яктарафа аст. Аммо агар шумо хоҳед, ки рамзгузорӣ ва рамзкушоӣ кунед?
Архитектураи криптографияи Java: Муқаддимаи аввал - 6

Криптографияи калидҳои симметрӣ

Рамзгузории симметрӣ рамзгузорӣ мебошад, ки барои рамзгузорӣ ва рамзкушоӣ як калидро истифода мебарад. Барои истифодаи рамзгузории симметрӣ ба мо калид лозим аст. Барои ба даст овардани он мо KeyGenerator -ро истифода мебарем . Илова бар ин, ба мо синфе лозим мешавад, ки рамзро ифода мекунад ( Cipher ). Тавре ки дар ҳуҷҷатҳои JCA дар қисмати " Сохтани an objectи рамзгузорӣ " гуфта шудааст, барои сохтани рамз шумо бояд на танҳо алгоритм, балки "трансформатсия" -ро дар сатр муайян кунед. Тавсифи трансформатсия чунин менамояд: "algorithm/mode/padding":
  • Алгоритм : дар ин ҷо мо ба номҳои стандартии " Алгоритмҳои шифр (шифркунӣ) " назар мекунем. Истифодаи AES тавсия дода мешавад.
  • Режим : ҳолати рамзгузорӣ. Масалан: ECB ё CBC (мо дар ин бора каме дертар сӯҳбат хоҳем кард)
  • Индентатсия/Тақсим : Ҳар як блоки маълумот алоҳида рамзгузорӣ карда мешавад. Ин параметр муайян мекунад, ки чӣ қадар маълумот ҳамчун 1 блок ҳисоб карда мешавад.
Масалан, табдor зеринро гирем: "AES/ECB/PKCS5Padding". Яъне, алгоритми рамзгузорӣ AES, ҳолати рамзгузорӣ ECB (кӯтоҳ барои электронии Codebook), андозаи блок PKCS5Padding мебошад. PKCS5Padding мегӯяд, ки андозаи як блок 2 byte (16 бит) аст. Реҷаи рамзгузории электронии Codebook рамзгузории пайдарпайи ҳар як блокро дар бар мегирад:
Архитектураи криптографияи Java: Муқаддимаи аввал - 7
Он метавонад дар code чунин бошад:
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 аломат муайян кардем. Ин аломатҳо 2 блоки 16 битро ташкил медиҳанд:
Архитектураи криптографияи Java: Муқаддимаи аввал - 8
Барои роҳ надодан ба такрор дар ин ҳолат, шумо бояд режими дигарро истифода баред - Cipher Block Chaining (CBC). Ин режим мафҳуми Initialization Vector (бо синфи IvParameterSpec муаррифӣ мешавад) муаррифӣ мекунад. Ва инчунин ба шарофати ин режим, натиҷаи тавлиди блоки охирин барои тавлиди блоки навбатӣ истифода мешавад:
Архитектураи криптографияи Java: Муқаддимаи аввал - 9
Биёед ҳоло инро дар code нависед:
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, ман ба шумо маслиҳат медиҳам, ки маводро хонед: " Реҷаи китоби электронӣ ». Аммо рамзгузории симметрӣ як мушкor рӯшан дорад - шумо бояд калидро аз касе, ки рамзгузорӣ мекунад, ба шахси рамзгузоранда интиқол диҳед. Ва дар ин роҳ, ин калидро метавон боздошт кард ва пас аз он маълумотро боздоштан мумкин аст. Ва рамзгузории асимметрӣ барои ҳалли ин мушкилот тарҳрезӣ шудааст.
Архитектураи криптографияи Java: Муқаддимаи аввал - 10

Рамзгузории асимметрӣ

Рамзгузории асимметрӣ ё криптографияи калиди оммавӣ як усули рамзгузорӣ мебошад, ки як ҷуфт калидҳоро истифода мебарад: калиди хусусӣ (аз ҳама махфӣ нигоҳ дошта мешавад) ва калиди ҷамъиятӣ (барои ҳамагон дастрас). Ин ҷудокунӣ барои он зарур аст, ки калиди ошкоро байни тарафҳои табодули иттилоот дар ҳоле, ки калиди махфӣ бехатар нигоҳ дошта шавад. Ҳангоми сохтани ҷуфти калидӣ, 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));
  }
}
Дар ин ҷо фаҳмидан муҳим аст, ки ҳангоми истифодаи рамзгузории асимметрӣ, мо ҳамеша KeyPair-ро барои истифода аз як калид барои рамзгузорӣ ва калиди дигар барои рамзкушоӣ истифода мебарем. Аммо азбаски Нуқтаи рамзгузорӣ дар он аст, ки танҳо гиранда рамзро кушода метавонад; он бо калиди ҷамъиятӣ рамзгузорӣ карда мешавад ва танҳо бо калиди хусусӣ рамзкушо карда мешавад.
Архитектураи криптографияи Java: Шиносоии аввал - 11

Имзои рақамӣ

Тавре ки мо дар боло дидем, бо донистани калиди ҷамъиятӣ, шумо метавонед маълумотро фиристед, то танҳо соҳиби калиди махфӣ рамзкушоӣ кунад. Яъне, моҳияти рамзгузории асимметрӣ дар он аст, ки ҳар касе рамзгузорӣ мекунад, аммо танҳо мо мехонем. Инчунин тартиби баръакс вуҷуд дорад - имзои рақамӣ, ки бо синфи Signature муаррифӣ мешавад . Имзои рақамӣ метавонад алгоритмҳои зеринро истифода барад: " Алгоритмҳои имзо ". Ҳуҷҷатҳои JCA пешниҳод мекунад, ки ин дуро бодиққат дида бароем: DSAwithMD5 ва RSAwithMD5 Аз DSA ё RSA чӣ беҳтар аст ва фарқияти онҳо дар ин ҷо чӣ гуна аст, шумо метавонед дар инҷо хонед: " Кадомаш барои интиқоли файлҳои шифршуда беҳтарин кор мекунад - RSA ё DSA? ". Ё муҳокимаҳоро дар ин ҷо хонед: " RSA против. DSA барои калидҳои аутентификатсияи SSH ". Ҳамин тавр, имзои рақамӣ. Мо мисли пештара ба KeyPair ва синфи нави Signature ниёз дорем. Агар шумо то кунун дар компиляторҳои онлайн озмоиш карда бошед, пас мисоли зерин метавонад барои онҳо то андозае душвор бошад. Намунаи ман танҳо дар ин ҷо кор мекард: 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));
    }
}
Имзои рақамӣ ҳамин тавр кор мекунад. Имзои рақамӣ як мавзӯи ҷолиб аст. Ман ба шумо маслиҳат медиҳам, ки ба гузориши ин мавзӯъ нигаред:
Архитектураи криптографияи Java: Шиносоии аввал - 12
Дар боло мо дидем, ки тарафҳо чӣ гуна маълумот мубодила мекунанд. Оё дар JCA интерфейси стандартӣ барои ин ҳамкорӣ вуҷуд надорад? Маълум мешавад, ки вуҷуд дорад. Биёед ба он назар андозем.
Java Cryptography Architecture: Первое знакомство - 13

Созишномаи калидӣ

Архитектураи криптографияи Java як воситаи муҳимро муаррифӣ мекунад - Созишномаи калидӣ протокол аст. Он бо синфи 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 гирифта шудааст: " Мубодилаи калидҳои Диффи-Хелман байни 2 Тараф ". Ин тақрибан он чизест, ки рамзгузории асимметрӣ дар меъмории криптографияи Java бо истифода аз протоколи созишномаи калид ба назар мерасад. Барои маълумоти бештар дар бораи рамзгузории асимметрӣ, видеоҳои тавсияшаванда:
Java Cryptography Architecture: Первое знакомство - 14

Шаҳодатномаҳо

Хуб, барои шириниҳо мо то ҳол чизи муҳиме надорем - сертификатҳо. Одатан, сертификатҳо бо истифода аз утorтаи keytool, ки ба jdk дохил мешаванд, тавлид мешаванд. Шумо метавонед тафсилоти бештарро хонед, масалан, дар ин ҷо: " Ташкил кардани сертификати худимзошудаи SSL бо истифода аз фармони Java keytool ". Шумо инчунин метавонед дастурҳоро аз Oracle хонед. Масалан, дар ин ҷо: " Барои сохтани сертификати server истифода бурдани асбоби клавиатура ". Масалан, биёед 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));
  }
}
Тавре ки мо мебинем, сертификат қобorяти пешниҳоди калиди оммавиро фароҳам меорад. Ин усул як нуқсон дорад - мо истифода мебарем sun.security, ки хатарнок ҳисобида мешавад, зеро... ин баста қисми APIи ҷамъиятии Java нест. Аз ин рӯ, ҳангоми тартиб додан параметри - ро муайян кардан лозим аст XDignore.symbol.file. Роҳи дигар вуҷуд дорад - дастӣ сохтани шаҳодатнома. Камбуди он аст, ки он API-и дохorро истифода мебарад, ки ҳуҷҷатгузорӣ нашудааст. Бо вуҷуди ин, дар бораи он донистан муфид аст. Ҳадди ақал, зеро он ба таври равшан намоён аст, ки мушаххасоти RFC-2459 чӣ гуна истифода мешавад: “ Infrastructure Key Public Key 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);
}
Java Cryptography Architecture: Первое знакомство - 15

Мағозаи калидҳо (KeyStore)

Охирин чизе, ки ман мехоҳам дар бораи он сӯҳбат кунам, ин мағозаи калид ва сертификатҳо мебошад, ки 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());
}
Тавре ки шумо аз мисол мебинед, он аввал loadбарои KeyStore иҷро карда мешавад. Аммо дар ҳолати мо, мо атрибути аввалро ҳамчун null муайян кардем, яъне. манбаи KeyStore вуҷуд надорад. Ин маънои онро дорад, ки KeyStore барои нигоҳ доштани минбаъдаи он холӣ сохта шудааст. Параметри дуюм низ нул аст, зеро мо як KeyStore нав эҷод мекунем. Агар мо KeyStore-ро аз файл бор мекардем, пас мо бояд паролро дар ин ҷо муайян кунем (ба усули KeyStore, ки мағоза ном дорад).

Хатти поён

Ҳамин тавр, мо бо шумо амалҳои асосӣ ва ибтидоиро дар доираи меъмории Java Cryptography (aka JCA) баррасӣ кардем. Мо дидем, ки рамзгузории симметрӣ ва асимметрӣ чист ва он дар JCA чӣ гуна амалӣ карда мешавад. Мо дидем, ки чӣ гуна сертификатҳо ва имзоҳои рақамӣ сохта мешаванд ва чӣ гуна истифода мешаванд. Ин ҳама танҳо асосҳо мебошанд, ки дар паси онҳо чизҳои бештар мураккаб ва ҷолиб мавҷуданд. Умедворам, ки ин маводи барраси муфид хоҳад буд ва шуморо ба омӯзиши минбаъдаи ин соҳа таваҷҷӯҳ хоҳад кард.
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION