JavaRush /Java Blog /Random-ID /Arsitektur Kriptografi Java: Pengenalan pertama
Viacheslav
Level 3

Arsitektur Kriptografi Java: Pengenalan pertama

Dipublikasikan di grup Random-ID
Keamanan pertukaran data adalah salah satu properti terpenting dari aplikasi modern. Sejak zaman kuno, orang telah menemukan metode licik, yang seiring dengan perkembangan umat manusia menjadi ilmu Kriptografi secara keseluruhan. Tentu saja, Java tidak tinggal diam dan menawarkan kepada pengembang Java Cryptography Architecture (JCA). Ulasan ini akan memberikan gambaran awal tentang cara kerjanya.

Kata pengantar

Saya mengusulkan untuk melakukan perjalanan kembali ke masa lalu. Di depan kita adalah Roma Kuno. Dan di depan kita adalah Gaius Julius Caesar, yang mengirimkan pesan kepada komandannya. Mari kita lihat isi pesan ini:
Arsitektur Kriptografi Java: Pengenalan pertama - 2
Apa artinya ini: "ЕСКЕУГЬГМХИФЯ Е УЛП"? Mari kita buka Java Online Compiler, contoh: 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);
    }
  }
}
Di hadapan kita adalah implementasi Caesar Cipher yang paling sederhana. Menurut karya sejarawan Romawi kuno Suetonius yang berjudul “Kehidupan Dua Belas Kaisar,” inilah cara Caesar mengenkripsi pesan kepada para jenderalnya. Dan ini adalah salah satu referensi paling kuno tentang penggunaan Kriptografi . Kata "kriptografi" berasal dari kata Yunani kuno "tersembunyi" dan "menulis", yaitu. itu adalah ilmu teknik privasi. Java memiliki dukungannya sendiri untuk kriptografi dan disebut Java Cryptography Architecture (JCA). Deskripsinya dapat ditemukan di dokumentasi resmi dari Oracle - " Java Cryptography Architecture (JCA) ". Saya sarankan Anda melihat peluang apa yang kita dapatkan berkat JCA.
Arsitektur Kriptografi Java: Pengenalan pertama - 3

J.C.A.

Seperti yang kita pelajari sebelumnya, Java menawarkan Java Cryptography Architecture (JCA) untuk bekerja dengan kriptografi. Arsitektur ini berisi API (yaitu sekumpulan antarmuka tertentu) dan penyedia (yang mengimplementasikannya):
Arsitektur Kriptografi Java: Pengenalan pertama - 4
Seperti yang tertulis dalam dokumentasi, " Platform Java mencakup sejumlah penyedia bawaan ". Artinya, platform Java menyediakan seperangkat penyedia bawaan yang dapat diperluas jika diperlukan. Anda dapat melihatnya 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());
    }
  }
}
Mendaftarkan penyedia pihak ketiga sangatlah mudah. Misalnya: Security.addProvider(new BouncyCastleProvider()); Contoh ini menghubungkan salah satu penyedia paling terkenal - BouncyCastle . Namun dalam ulasan ini kami hanya akan menggunakan alat dasar, tanpa perpustakaan pihak ketiga. Dokumen utama kami: " Arsitektur Kriptografi Java (JCA) ". Memahami cara kerja JCA akan membantu Anda lebih mudah memahami teknologi yang digunakan secara aktif oleh JCA ini. Misalnya: HTTPS (lihat " Dari HTTP ke HTTPS ").
Arsitektur Kriptografi Java: Pengenalan pertama - 5

Intisari Pesan

Hal pertama yang disebutkan dalam dokumentasi JCA adalah MessageDigest. Secara umum, Intisari dalam bahasa Rusia akan sama - intisari memiliki arti yang sama dengan "ringkasan". Namun dalam kriptografi, intisari adalah jumlah hash. Anda juga dapat dengan mudah mengingat bahwa dalam bahasa Inggris Digest juga dapat diterjemahkan sebagai intisari. Detail selengkapnya dapat ditemukan di dokumentasi JCA di bagian " MessageDigest ". Seperti yang disebutkan dalam dokumentasi, MessageDigest menghasilkan hasil berukuran tetap yang disebut intisari atau hash. Hashing adalah fungsi satu arah, mis. jika kita meng-hash sesuatu, maka dari hasilnya (yaitu dari hash) kita tidak bisa mendapatkan sumber aslinya. Namun jika objek yang identik di-hash (misalnya, string karakter yang identik), maka hashnya harus cocok. Sebagaimana dinyatakan dalam dokumentasi, hash semacam itu terkadang juga disebut “checksum” atau “sidik jari digital” data. Hashing dapat dilakukan menggunakan algoritma yang berbeda. Algoritma yang tersedia dapat dilihat pada dokumen " Dokumentasi Nama Algoritma Standar Arsitektur Kriptografi Java untuk JDK 8 ". Mari lakukan hashing dan cetak hash 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 dapat berguna, misalnya saat menyimpan kata sandi. Karena hash dari kata sandi yang dimasukkan dapat dibandingkan dengan hash yang disimpan sebelumnya. Jika hashnya cocok, maka kata sandinya juga cocok. Untuk hashing yang lebih aman, konsep yang disebut “garam” digunakan. Salt dapat diimplementasikan menggunakan kelas SecureRandom . Sebelum menjalankan metode intisari, mari kita jelaskan penambahan "garam":
byte[] salt = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(salt);
digester.update(salt);
Tapi hash adalah fungsi satu arah. Tapi bagaimana jika Anda ingin bisa mengenkripsi dan mendekripsi?
Arsitektur Kriptografi Java: Pengenalan pertama - 6

Kriptografi kunci simetris

Enkripsi simetris adalah enkripsi yang menggunakan kunci yang sama untuk enkripsi dan dekripsi. Untuk menggunakan enkripsi simetris kita memerlukan kunci. Untuk mendapatkannya kami menggunakan KeyGenerator . Selain itu, kita memerlukan kelas yang mewakili sebuah sandi ( Cipher ). Sebagaimana dinyatakan dalam dokumentasi JCA di bagian “ Membuat Objek Cipher ”, untuk membuat Cipher Anda perlu menentukan tidak hanya algoritma, tetapi “transformasi” di baris. Deskripsi transformasinya terlihat seperti ini: "algorithm/mode/padding":
  • Algoritma : di sini kita melihat nama standar untuk “ Algoritma Cipher (Enkripsi) ”. Disarankan untuk menggunakan AES.
  • Mode : mode enkripsi. Misalnya: ECB atau CBC (kita akan membicarakannya nanti)
  • Indentasi/Pemisahan : Setiap blok data dienkripsi secara terpisah. Parameter ini menentukan berapa banyak data yang dihitung sebagai 1 blok.
Misalnya, ambil transformasi berikut: "AES/ECB/PKCS5Padding". Artinya, algoritma enkripsinya adalah AES, mode enkripsinya adalah ECB (kependekan dari Electronic Codebook), ukuran bloknya adalah PKCS5Padding. PKCS5Padding mengatakan bahwa ukuran satu blok adalah 2 byte (16 bit). Mode enkripsi Buku Kode Elektronik melibatkan enkripsi berurutan dari setiap blok:
Arsitektur Kriptografi Java: Pengenalan pertama - 7
Mungkin terlihat seperti ini dalam kode:
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 mengeksekusi, kita akan mengharapkan pengulangan, karena kami menentukan 32 karakter. Karakter-karakter ini membentuk 2 blok 16 bit:
Arsitektur Kriptografi Java: Pengenalan pertama - 8
Untuk menghindari pengulangan dalam kasus ini, Anda harus menggunakan mode lain - Cipher Block Chaining (CBC). Mode ini memperkenalkan konsep Inisialisasi Vektor (diwakili oleh kelas IvParameterSpec). Dan juga berkat mode ini, hasil pembuatan blok terakhir akan digunakan untuk menghasilkan blok berikutnya:
Arsitektur Kriptografi Java: Pengenalan pertama - 9
Sekarang mari kita tulis ini dalam kode:
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 bisa kita lihat, sebagai hasilnya kita tidak melihat blok sandi yang berulang. Oleh karena itu, mode ECB tidak disarankan karena memungkinkan untuk melihat pengulangan dan menggunakan pengetahuan ini untuk dekripsi. Untuk informasi lebih lanjut tentang ECB dan CBC, saya menyarankan Anda untuk membaca materi: “ Mode buku kode elektronik ”. Tetapi enkripsi simetris memiliki masalah yang jelas - Anda harus mentransfer kunci dari orang yang mengenkripsi ke orang yang mengenkripsi. Dan di sepanjang jalur ini, kunci ini dapat dicegat dan kemudian data dapat dicegat. Dan enkripsi asimetris dirancang untuk mengatasi masalah ini.
Arsitektur Kriptografi Java: Pengenalan pertama - 10

Enkripsi asimetris

Enkripsi asimetris atau Kriptografi kunci publik adalah metode enkripsi yang menggunakan sepasang kunci: kunci pribadi (dirahasiakan dari semua orang) dan kunci publik (tersedia untuk publik). Pemisahan ini diperlukan untuk pertukaran kunci publik yang aman antara pihak-pihak yang bertukar informasi, sekaligus menjaga kunci rahasia tetap aman. Saat membuat pasangan kunci, KeyGenerator tidak lagi cukup bagi kita; kita memerlukan KeyPairGenerator . Mari kita lihat sebuah 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));
  }
}
Penting untuk dipahami di sini bahwa saat menggunakan enkripsi asimetris, kami selalu menggunakan KeyPair untuk menggunakan satu kunci untuk enkripsi dan kunci lainnya untuk dekripsi. Tapi karena Inti dari enkripsi adalah hanya penerima yang dapat mendekripsinya; enkripsi tersebut dienkripsi dengan kunci publik, dan hanya didekripsi dengan kunci pribadi.
Arsitektur Kriptografi Java: Kenalan pertama - 11

Tanda tangan digital

Seperti yang kita lihat di atas, dengan mengetahui kunci publik, Anda dapat mengirim data sehingga hanya pemilik kunci pribadi yang dapat mendekripsinya. Artinya, inti dari enkripsi asimetris adalah siapa pun mengenkripsi, tetapi hanya kita yang membaca. Ada juga prosedur sebaliknya - tanda tangan digital, yang diwakili oleh kelas Signature . Sebuah tanda tangan digital dapat menggunakan algoritma berikut: “ Algoritma Tanda Tangan ”. Dokumentasi JCA menyarankan untuk melihat lebih dekat keduanya: DSAwithMD5 dan RSAwithMD5 Apa yang lebih baik dari DSA atau RSA dan apa perbedaannya, Anda dapat membaca di sini: " Mana yang Paling Cocok untuk Transfer File Terenkripsi - RSA atau DSA? ". Atau baca diskusinya di sini: " RSA vs. DSA untuk kunci otentikasi SSH ". Jadi, tanda tangan digital. Kita memerlukan, seperti sebelumnya, KeyPair dan kelas Signature baru. Jika Anda sejauh ini telah menguji kompiler online, maka contoh berikut mungkin agak sulit bagi mereka. Contoh saya hanya berjalan di sini: rextester.com . Kami mengimpor kelas yang kami butuhkan:
import javax.crypto.*;
import java.security.*;
Kami juga akan menulis ulang metode 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 kerja tanda tangan digital. Tanda tangan digital adalah topik yang menarik. Saya menyarankan Anda untuk melihat laporan tentang topik ini:
Arsitektur Kriptografi Java: Kenalan pertama - 12
Di atas kita melihat bagaimana para pihak bertukar data. Bukankah ada antarmuka standar untuk interaksi ini yang disediakan di JCA? Ternyata ada. Mari kita lihat itu.
Arsitektur Kriptografi Java: Kenalan pertama - 13

Perjanjian Kunci

Arsitektur Kriptografi Java memperkenalkan alat penting - Perjanjian kunci adalah sebuah protokol. Itu diwakili oleh kelas KeyAgreement . Sebagaimana dinyatakan dalam dokumentasi JCA, protokol ini memungkinkan banyak pihak untuk mengatur kunci kriptografi yang sama tanpa membagikan informasi rahasia apa pun antar pihak. Kedengarannya aneh? Mari kita lihat contohnya:
// 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 dari contoh dokumentasi JCA: " Pertukaran Kunci Diffie-Hellman antara 2 Pihak ". Ini kira-kira seperti apa enkripsi asimetris dalam Arsitektur Kriptografi Java menggunakan protokol perjanjian Kunci. Untuk informasi lebih lanjut tentang enkripsi asimetris, video yang direkomendasikan:
Arsitektur Kriptografi Java: Kenalan pertama - 14

Sertifikat

Nah, untuk hidangan penutup kami masih memiliki sesuatu yang tidak kalah pentingnya - sertifikat. Biasanya, sertifikat dibuat menggunakan utilitas keytool yang disertakan dengan jdk. Anda dapat membaca lebih detailnya, misalnya di sini: " Menghasilkan sertifikat SSL yang ditandatangani sendiri menggunakan perintah Java keytool ". Anda juga dapat membaca manual dari Oracle. Misalnya, di sini: " Menggunakan keytool untuk Membuat Sertifikat Server ". 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 bisa kita lihat, sertifikat memberikan kemampuan untuk menyediakan kunci publik. Cara ini mempunyai kekurangan - kami menggunakan sun.security, yang dianggap berisiko, karena... paket ini bukan bagian dari Java API publik. Itu sebabnya selama kompilasi perlu menentukan parameter - XDignore.symbol.file. Ada cara lain - membuat sertifikat secara manual. Kelemahannya adalah ia menggunakan API internal yang tidak didokumentasikan. Namun, ada baiknya untuk mengetahuinya. Minimal, karena terlihat jelas bagaimana spesifikasi RFC-2459 digunakan: “ Infrastruktur Kunci Publik Internet X.509 ”. Berikut ini contohnya:
// 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);
}
Arsitektur Kriptografi Java: Pengenalan pertama - 15

Penyimpanan Kunci (Penyimpanan Kunci)

Hal terakhir yang ingin saya bicarakan adalah penyimpanan kunci dan sertifikat, yang disebut KeyStore. Jelas bahwa pembuatan sertifikat dan kunci secara terus-menerus itu mahal dan tidak ada gunanya. Oleh karena itu, mereka perlu disimpan dengan aman. Ada alat untuk ini - KeyStore. Penyimpanan kunci dijelaskan dalam dokumentasi JCA di bab " Manajemen Kunci ". API untuk bekerja dengannya sangat jelas. Berikut ini contoh kecilnya:
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 dari contoh, ini dijalankan pertama kali loaduntuk KeyStore. Namun dalam kasus kami, kami menetapkan atribut pertama sebagai null, yaitu. tidak ada sumber untuk KeyStore. Artinya KeyStore dibuat kosong untuk disimpan lebih lanjut. Parameter kedua juga null, karena kami sedang membuat KeyStore baru. Jika kita memuat KeyStore dari sebuah file, maka kita perlu menentukan kata sandi di sini (mirip dengan metode KeyStore yang disebut store).

Intinya

Jadi kami telah meninjau bersama Anda tindakan paling mendasar dan mendasar dalam kerangka Arsitektur Kriptografi Java (alias JCA). Kami melihat apa itu enkripsi simetris dan asimetris dan bagaimana penerapannya di JCA. Kami melihat bagaimana sertifikat dan tanda tangan digital dibuat dan bagaimana penggunaannya. Ini semua hanyalah dasar-dasarnya, dibalik itu masih banyak hal yang lebih kompleks dan menarik. Saya harap materi ulasan ini bermanfaat dan menarik minat Anda untuk mempelajari lebih lanjut bidang ini.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION