JavaRush /Blog Java /Random-MS /Seni Bina Kriptografi Java: Pengenalan pertama

Seni Bina Kriptografi Java: Pengenalan pertama

Diterbitkan dalam kumpulan
Keselamatan pertukaran data adalah salah satu sifat terpenting aplikasi moden. Sejak zaman purba, orang telah menghasilkan kaedah licik, yang dengan perkembangan manusia menjadi seluruh ilmu Kriptografi. Sememangnya, Java tidak mengetepikan dan menawarkan pembangun Java Cryptography Architecture (JCA). Kajian ini harus memberikan idea pertama tentang cara ia berfungsi.

Mukadimah

Saya bercadang untuk mengembara kembali ke masa lalu. Di hadapan kita adalah Rom Purba. Dan di hadapan kita adalah Gaius Julius Caesar, yang menghantar mesej kepada komandernya. Mari lihat apa yang ada dalam mesej ini:
Seni Bina Kriptografi Java: Pengenalan pertama - 2
Apakah maksud ini: "ЕСКЕУГЬГМХИФЯ Е УЛП"? Mari buka Java Online Compiler, contohnya: 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);
    }
  }
}
Sebelum kita adalah pelaksanaan Caesar Cipher yang paling mudah. Menurut karya ahli sejarah Rom purba Suetonius bertajuk "The Lives of the Twelve Caesars," inilah cara Caesar menyulitkan mesej kepada jeneralnya. Dan ini adalah salah satu rujukan paling kuno tentang penggunaan perkara seperti Kriptografi . Perkataan "kriptografi" berasal daripada perkataan Yunani kuno "tersembunyi" dan "menulis", i.e. ia adalah sains teknik privasi. Java mempunyai sokongan tersendiri untuk kriptografi dan ia dipanggil Java Cryptography Architecture (JCA). Penerangan boleh didapati dalam dokumentasi rasmi dari Oracle - " Java Cryptography Architecture (JCA) ". Saya cadangkan anda melihat peluang yang kami dapat terima kasih kepada JCA.
Seni Bina Kriptografi Java: Pengenalan pertama - 3

J.C.A.

Seperti yang kita pelajari sebelum ini, Java menawarkan Seni Bina Kriptografi Java (JCA) untuk bekerja dengan kriptografi. Seni bina ini mengandungi API (iaitu set antara muka tertentu) dan pembekal (yang melaksanakannya):
Seni Bina Kriptografi Java: Pengenalan pertama - 4
Seperti yang dinyatakan dalam dokumentasi, " Platform Java merangkumi beberapa pembekal terbina dalam ". Iaitu, platform Java menyediakan satu set penyedia terbina dalam yang boleh dikembangkan jika perlu. Anda boleh lihat ini sendiri:
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());
    }
  }
}
Mendaftar penyedia pihak ketiga adalah sangat mudah. Contohnya: Security.addProvider(new BouncyCastleProvider()); Contoh ini menghubungkan salah satu penyedia yang paling terkenal - BouncyCastle . Tetapi dalam semakan ini kami hanya akan menggunakan alat asas, tanpa perpustakaan pihak ketiga. Dokumen utama kami: " Seni Bina Kriptografi Java (JCA) ". Memahami cara JCA berfungsi akan membantu anda memahami dengan lebih mudah teknologi yang JCA yang sama digunakan secara aktif. Contohnya: HTTPS (lihat " Dari HTTP ke HTTPS ").
Seni Bina Kriptografi Java: Pengenalan pertama - 5

MessageDigest

Perkara pertama yang disebut dalam dokumentasi JCA ialah MessageDigest. Secara umum, Digest dalam bahasa Rusia akan sama - digest sepadan dengan maksud "ringkasan". Tetapi dalam kriptografi, ringkasan adalah jumlah cincang. Anda juga boleh ingat dengan mudah bahawa dalam bahasa Inggeris Digest juga boleh diterjemahkan sebagai digest. Butiran lanjut boleh didapati dalam dokumentasi JCA dalam bahagian " MessageDigest ". Seperti yang dinyatakan dalam dokumentasi, MessageDigest menjana hasil bersaiz tetap yang dipanggil digest atau hash. Hashing ialah fungsi sehala, i.e. jika kita mencincang sesuatu, maka daripada hasil (iaitu daripada cincang) kita tidak boleh mendapatkan sumber asal. Tetapi jika objek yang sama dicincang (contohnya, rentetan aksara yang sama), maka cincangnya mesti sepadan. Seperti yang dinyatakan dalam dokumentasi, cincangan sedemikian kadangkala juga dipanggil "checksum" atau "cap jari digital" data. Hashing boleh dilakukan menggunakan algoritma yang berbeza. Algoritma yang tersedia boleh dilihat dalam dokumen " Java Cryptography Architecture Standard Algorithm Name Documentation for JDK 8 ". Mari lakukan pencincangan dan cetak pencincangan ke konsol:
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 boleh berguna, contohnya, apabila menyimpan kata laluan. Memandangkan cincangan kata laluan yang dimasukkan boleh disemak terhadap cincangan yang disimpan sebelum ini. Jika cincang sepadan, maka kata laluan juga sepadan. Untuk pencincangan yang lebih selamat, konsep yang dipanggil "garam" digunakan. Garam boleh dilaksanakan menggunakan kelas SecureRandom . Sebelum melaksanakan kaedah penghadaman, mari kita terangkan penambahan "garam":
byte[] salt = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(salt);
digester.update(salt);
Tetapi hash ialah fungsi sehala. Tetapi bagaimana jika anda mahu dapat menyulitkan dan menyahsulit?
Seni Bina Kriptografi Java: Pengenalan pertama - 6

kriptografi kunci simetri

Penyulitan simetri ialah penyulitan yang menggunakan kunci yang sama untuk penyulitan dan penyahsulitan. Untuk menggunakan penyulitan simetri kita memerlukan kunci. Untuk mendapatkannya kami menggunakan KeyGenerator . Di samping itu, kita memerlukan kelas yang mewakili sifir ( Cipher ). Seperti yang dinyatakan dalam dokumentasi JCA dalam bahagian " Mencipta Objek Cipher ", untuk mencipta Cipher anda perlu menentukan bukan sahaja algoritma, tetapi "transformasi" dalam baris. Perihalan transformasi kelihatan seperti ini: "algoritma/mod/padding":
  • Algoritma : di sini kita melihat nama standard untuk " Algoritma Cipher (Penyulitan) ". Adalah disyorkan untuk menggunakan AES.
  • Mod : mod penyulitan. Contohnya: ECB atau CBC (kita akan bercakap tentang perkara ini sedikit kemudian)
  • Inden/Pecah : Setiap blok data disulitkan secara berasingan. Parameter ini menentukan jumlah data yang dikira sebagai 1 blok.
Sebagai contoh, ambil transformasi berikut: "AES/ECB/PKCS5Padding". Iaitu, algoritma penyulitan ialah AES, mod penyulitan ialah ECB (singkatan untuk Electronic Codebook), saiz blok ialah PKCS5Padding. PKCS5Padding mengatakan bahawa saiz satu blok ialah 2 bait (16 bit). Mod penyulitan Buku Kod Elektronik melibatkan penyulitan berurutan bagi setiap blok:
Seni Bina Kriptografi Java: Pengenalan pertama - 7
Ia mungkin kelihatan seperti ini dalam kod:
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);
  }
}
Jika kita melaksanakan, kita akan mengharapkan untuk melihat ulangan, kerana kami menetapkan 32 aksara. Aksara ini membentuk 2 blok 16 bit:
Seni Bina Kriptografi Java: Pengenalan pertama - 8
Untuk mengelakkan main semula dalam kes ini, anda harus menggunakan mod lain - Cipher Block Chaining (CBC). Mod ini memperkenalkan konsep Vektor Permulaan (diwakili oleh kelas IvParameterSpec). Dan juga terima kasih kepada mod ini, hasil penjanaan blok terakhir akan digunakan untuk menjana yang seterusnya:
Seni Bina Kriptografi Java: Pengenalan pertama - 9
Mari kita tulis ini dalam kod:
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);
  }
}
Seperti yang kita lihat, akibatnya kita tidak melihat blok sifir berulang. Atas sebab ini, mod ECB tidak disyorkan, kerana memungkinkan untuk melihat ulangan dan menggunakan pengetahuan ini untuk penyahsulitan. Untuk maklumat lanjut tentang ECB dan CBC, saya menasihati anda untuk membaca bahan: " Mod buku kod elektronik ". Tetapi penyulitan simetri mempunyai masalah yang jelas - entah bagaimana anda perlu memindahkan kunci daripada orang yang menyulitkan kepada orang yang menyulitkan. Dan di sepanjang laluan ini, kunci ini boleh dipintas dan kemudiannya mungkin untuk memintas data. Dan penyulitan asimetri direka untuk menyelesaikan masalah ini.
Seni Bina Kriptografi Java: Pengenalan pertama - 10

Penyulitan asimetri

Penyulitan asimetri atau kriptografi kunci awam ialah kaedah penyulitan yang menggunakan sepasang kunci: kunci peribadi (dirahsiakan daripada semua orang) dan kunci awam (tersedia kepada orang ramai). Pemisahan ini adalah perlu untuk menukar kunci awam dengan selamat antara pihak-pihak kepada pertukaran maklumat, sambil memastikan kunci rahsia selamat. Apabila mencipta pasangan kunci, KeyGenerator tidak lagi mencukupi untuk kami; kami memerlukan KeyPairGenerator . Mari lihat contoh:
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));
  }
}
Adalah penting untuk memahami di sini bahawa apabila menggunakan penyulitan asimetri, kami sentiasa menggunakan KeyPair untuk menggunakan satu kunci untuk penyulitan dan satu lagi untuk penyahsulitan. Tapi sebab Inti penyulitan ialah hanya penerima boleh menyahsulitnya; ia disulitkan dengan kunci awam, dan dinyahsulit hanya dengan kunci peribadi.
Seni Bina Kriptografi Java: Kenalan pertama - 11

Tandatangan digital

Seperti yang kita lihat di atas, mengetahui kunci awam, anda boleh menghantar data supaya hanya pemilik kunci peribadi boleh menyahsulitnya. Iaitu, intipati penyulitan asimetri ialah sesiapa sahaja yang menyulitkan, tetapi hanya kita yang membaca. Terdapat juga prosedur terbalik - tandatangan digital, diwakili oleh kelas Tandatangan . Tandatangan digital boleh menggunakan algoritma berikut: " Algoritma Tandatangan ". Dokumentasi JCA mencadangkan untuk melihat dengan lebih dekat kedua-dua ini: DSAwithMD5 dan RSAwithMD5 Apakah yang lebih baik daripada DSA atau RSA dan apakah perbezaannya yang boleh anda baca di sini: " Mana Yang Paling Sesuai untuk Pemindahan Fail Disulitkan - RSA atau DSA? ". Atau baca perbincangan di sini: " RSA lwn. DSA untuk kunci pengesahan SSH ". Jadi, tandatangan digital. Kami memerlukan, seperti sebelum ini, KeyPair dan kelas Tandatangan baharu. Jika anda telah menguji setakat ini dalam penyusun dalam talian, maka contoh berikut mungkin agak sukar untuk mereka. Contoh saya hanya dijalankan di sini: rextester.com . Kami mengimport kelas yang kami perlukan:
import javax.crypto.*;
import java.security.*;
Kami juga akan menulis semula kaedah utama:
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));
    }
}
Beginilah cara tandatangan digital berfungsi. Tandatangan digital adalah topik yang menarik. Saya menasihati anda untuk melihat laporan mengenai topik ini:
Seni Bina Kriptografi Java: Kenalan pertama - 12
Di atas kita melihat bagaimana pihak bertukar data. Tidakkah terdapat antara muka standard untuk interaksi ini disediakan dalam JCA? Ternyata ada. Jom tengok.
Seni Bina Kriptografi Java: Kenalan pertama - 13

KeyAgreement

Seni Bina Kriptografi Java memperkenalkan alat penting - Perjanjian utama ialah protokol. Ia diwakili oleh kelas KeyAgreement . Seperti yang dinyatakan dalam dokumentasi JCA, protokol ini membenarkan berbilang pihak untuk menetapkan kunci kriptografi yang sama tanpa berkongsi sebarang maklumat rahsia antara pihak. Bunyi pelik? Kemudian mari kita lihat contoh:
// 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));
Contoh ini diambil daripada contoh dokumentasi JCA: " Pertukaran Kunci Diffie-Hellman antara 2 Pihak ". Ini kira-kira rupa penyulitan asimetri dalam Seni Bina Kriptografi Java menggunakan protokol perjanjian Kunci. Untuk mendapatkan maklumat lanjut tentang penyulitan asimetri, video yang disyorkan:
Seni Bina Kriptografi Java: Kenalan pertama - 14

Sijil

Nah, untuk pencuci mulut kami masih mempunyai sesuatu yang tidak kurang penting - sijil. Biasanya, sijil dijana menggunakan utiliti alat kunci yang disertakan dengan jdk. Anda boleh membaca butiran lanjut, contohnya, di sini: " Menjana sijil SSL yang ditandatangani sendiri menggunakan arahan alat kunci Java ". Anda juga boleh membaca manual daripada Oracle. Contohnya, di sini: " Untuk Menggunakan alat kekunci untuk Mencipta Sijil Pelayan ". Sebagai contoh, mari kita gunakan 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));
  }
}
Seperti yang dapat kita lihat, sijil menyediakan keupayaan untuk menyediakan kunci awam. Kaedah ini mempunyai kelemahan - kami menggunakan sun.security, yang dianggap berisiko, kerana... pakej ini bukan sebahagian daripada API Java awam. Itulah sebabnya semasa penyusunan adalah perlu untuk menentukan parameter - XDignore.symbol.file. Terdapat cara lain - untuk membuat sijil secara manual. Kelemahannya ialah ia menggunakan API dalaman yang tidak didokumenkan. Walau bagaimanapun, adalah berguna untuk mengetahui mengenainya. Sekurang-kurangnya, kerana ia dapat dilihat dengan jelas bagaimana spesifikasi RFC-2459 digunakan: " Infrastruktur Kunci Awam Internet X.509 ". Berikut ialah contoh:
// 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);
}
Seni Bina Kriptografi Java: Pengenalan pertama - 15

Kedai Kunci (KeyStore)

Perkara terakhir yang saya ingin bincangkan ialah kedai kunci dan sijil, yang dipanggil KeyStore. Adalah jelas bahawa sentiasa menjana sijil dan kunci adalah mahal dan sia-sia. Oleh itu, mereka perlu disimpan dengan selamat. Terdapat alat untuk ini - KeyStore. Stor kunci diterangkan dalam dokumentasi JCA dalam bab " Pengurusan Kunci ". API untuk bekerja dengannya sangat jelas. Berikut adalah contoh kecil:
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());
}
Seperti yang anda lihat daripada contoh, ia dilaksanakan terlebih dahulu loaduntuk KeyStore. Tetapi dalam kes kami, kami menentukan atribut pertama sebagai null, i.e. tiada sumber untuk KeyStore. Ini bermakna KeyStore dicipta kosong untuk menyimpannya lagi. Parameter kedua juga adalah batal, kerana kami sedang mencipta KeyStore baharu. Jika kami memuatkan KeyStore daripada fail, maka kami perlu menentukan kata laluan di sini (serupa dengan kaedah KeyStore yang dipanggil kedai).

Pokoknya

Oleh itu, kami telah menyemak bersama anda tindakan paling asas dan asas dalam rangka kerja Seni Bina Kriptografi Java (aka JCA). Kami melihat apa itu penyulitan simetri dan asimetri dan cara ia dilaksanakan dalam JCA. Kami melihat cara sijil dan tandatangan digital dibuat dan cara ia digunakan. Ini semua hanyalah asas, di belakangnya terdapat banyak perkara yang lebih kompleks dan menarik. Saya berharap bahan ulasan ini berguna dan akan menarik minat anda untuk mengkaji lebih lanjut mengenai bidang ini.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION