JavaRush /Blog Jawa /Random-JV /Arsitektur Kriptografi Jawa: Pambuka pisanan
Viacheslav
tingkat

Arsitektur Kriptografi Jawa: Pambuka pisanan

Diterbitake ing grup
Keamanan ijol-ijolan data minangka salah sawijining sifat paling penting ing aplikasi modern. Wiwit jaman kuna, wong-wong wis nggawe cara licik, sing kanthi perkembangan manungsa dadi ilmu kriptografi. Mesthine, Jawa ora mandheg lan nawakake pangembang Java Cryptography Architecture (JCA). Tinjauan iki kudu menehi ide pisanan babagan cara kerjane.

PURWAKA

Aku propose kanggo lelungan bali ing wektu. Sadurunge kita ana Roma Kuno. Lan sadurunge kita ana Gayus Julius Caesar, sing ngirim pesen marang komandhane. Ayo ndeleng apa sing ana ing pesen iki:
Arsitektur Kriptografi Jawa: Pambuka pisanan - 2
Apa tegese iki: "ЕСКЕУГЬГМХИФЯ Е УЛП"? Ayo mbukak Java Online Compiler, contone: 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);
    }
  }
}
Sadurunge kita minangka implementasine paling gampang saka Caesar Cipher. Miturut karya sejarawan Romawi kuno Suetonius kanthi irah-irahan "The Lives of the Twelve Caesars," iki persis carane Caesar ndhelik pesen marang para jenderal. Lan iki minangka salah sawijining referensi paling kuno babagan panggunaan barang kaya Kriptografi . Tembung "kriptografi" asalé saka tembung Yunani kuna "didhelikake" lan "nulis", i.e. iku ilmu saka Techniques privasi. Java duwe dhukungan dhewe kanggo kriptografi lan diarani Java Cryptography Architecture (JCA). Katrangan kasebut bisa ditemokake ing dokumentasi resmi saka Oracle - " Java Cryptography Architecture (JCA) ". Aku saranake sampeyan dipikir ing kesempatan apa kita njaluk thanks JCA.
Arsitektur Kriptografi Jawa: Pambuka pisanan - 3

J.C.A.

Kaya sing sadurunge wis sinau, Jawa nawakake Arsitektur Kriptografi Jawa (JCA) kanggo nggarap kriptografi. Arsitektur iki ngemot API (yaiku sakumpulan antarmuka tartamtu) lan panyedhiya (sing ngetrapake):
Arsitektur Kriptografi Jawa: Pambuka pisanan - 4
Minangka dokumentasi ngandika, " Platform Jawa kalebu sawetara panyedhiya dibangun ing ". Tegese, platform Java nyedhiyakake set panyedhiya sing dibangun sing bisa ditambahi yen perlu. Sampeyan bisa ndeleng iki dhewe:
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());
    }
  }
}
Ndhaptar panyedhiya pihak katelu gampang banget. Contone: Security.addProvider(new BouncyCastleProvider()); Conto iki nyambungake salah siji saka panyedhiya paling misuwur - BouncyCastle . Nanging ing review iki, kita mung bakal nggunakake alat dhasar, tanpa perpustakaan pihak katelu. Dokumen utama kami: " Java Cryptography Architecture (JCA) ". Ngerteni cara kerjane JCA bakal mbantu sampeyan luwih gampang ngerti teknologi sing digunakake JCA sing padha. Contone: HTTPS (ndeleng " Saka HTTP menyang HTTPS ").
Arsitektur Kriptografi Jawa: Pambuka pisanan - 5

MessageDigest

Babagan pisanan sing kasebut ing dokumentasi JCA yaiku MessageDigest. Umumé, Digest ing basa Rusia bakal padha - digest cocog karo tegesé "ringkesan". Nanging ing kriptografi, digest minangka jumlah hash. Sampeyan uga bisa gampang ngelingi yen ing Inggris Digest uga bisa diterjemahake minangka digest. Rincian liyane bisa ditemokake ing dokumentasi JCA ing bagean " MessageDigest ". Minangka dokumentasi kasebut, MessageDigest ngasilake asil ukuran tetep sing diarani digest utawa hash. Hashing minangka fungsi siji arah, yaiku. yen kita hashed soko, banjur saka asil (i.e. saka hash) kita ora bisa njaluk sumber asli. Nanging yen obyek sing padha digesek (contone, senar saka karakter sing padha), banjur hash kasebut kudu cocog. Kaya sing kasebut ing dokumentasi, hash kasebut kadhangkala uga disebut "checksum" utawa "sidik jari digital" data. Hashing bisa ditindakake kanthi nggunakake algoritma sing beda. Algoritma sing kasedhiya bisa dideleng ing dokumen " Java Cryptography Architecture Standard Algorithm Name Documentation for JDK 8 ". Ayo nggawe hashing lan print hash menyang console:
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 bisa migunani, contone, nalika nyimpen sandhi. Wiwit hash saka tembung sandhi sing dilebokake bisa dicenthang nglawan hash sing wis disimpen sadurunge. Yen hash cocog, banjur sandhi uga cocog. Kanggo hashing sing luwih aman, konsep sing diarani "uyah" digunakake. Salt bisa dileksanakake nggunakake kelas SecureRandom . Sadurunge nglakokake metode pencernaan, ayo nerangake nambahake "uyah":
byte[] salt = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(salt);
digester.update(salt);
Nanging hash minangka fungsi siji arah. Nanging apa yen sampeyan pengin bisa enkripsi lan dekripsi?
Arsitektur Kriptografi Jawa: Pambuka pisanan - 6

Kriptografi kunci simetris

Enkripsi simetris yaiku enkripsi sing nggunakake kunci sing padha kanggo enkripsi lan dekripsi. Kanggo nggunakake enkripsi simetris, kita butuh kunci. Kanggo entuk, kita nggunakake KeyGenerator . Kajaba iku, kita butuh kelas sing makili cipher ( Cipher ). Kaya sing kasebut ing dokumentasi JCA ing bagean " Nggawe Obyek Cipher ", kanggo nggawe Cipher sampeyan kudu nemtokake ora mung algoritma, nanging "transformasi" ing baris. Katrangan transformasi katon kaya iki: "algoritma/mode/padding":
  • Algoritma : ing kene kita ndeleng jeneng standar kanggo " Algoritma Cipher (Enkripsi) . Disaranake nggunakake AES.
  • Mode : mode enkripsi. Contone: ECB utawa CBC (kita bakal ngomong babagan iki mengko)
  • Indentation / Split : Saben blok data dienkripsi kanthi kapisah. Parameter iki nemtokake jumlah data sing diitung minangka 1 blok.
Contone, njupuk transformasi ing ngisor iki "AES/ECB/PKCS5Padding":. Yaiku, algoritma enkripsi yaiku AES, mode enkripsi yaiku ECB (singkatan saka Electronic Codebook), ukuran blok yaiku PKCS5Padding. PKCS5Padding ngandika sing ukuran siji blok punika 2 bait (16 bit). Mode enkripsi Buku Kode Elektronik kalebu enkripsi urutan saben blok:
Arsitektur Kriptografi Jawa: Pambuka pisanan - 7
Bisa uga katon kaya iki ing 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);
  }
}
Yen kita nglakokaké, kita bakal nyana kanggo ndeleng baleni, amarga kita nemtokake 32 karakter. Karakter kasebut nggawe 2 blok kanthi 16 bit:
Arsitektur Kriptografi Jawa: Pambuka pisanan - 8
Supaya ora muter maneh ing kasus iki, sampeyan kudu nggunakake mode liyane - Cipher Block Chaining (CBC). Mode iki ngenalake konsep Vektor Initialization (diwakili dening kelas IvParameterSpec). Lan uga thanks kanggo mode iki, asil ngasilake blok pungkasan bakal digunakake kanggo ngasilake sing sabanjure:
Arsitektur Kriptografi Jawa: Pambuka pisanan - 9
Ayo saiki nulis iki ing 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);
  }
}
Kaya sing kita deleng, minangka asil, kita ora bisa ndeleng blok cipher sing bola-bali. Mulane, mode ECB ora dianjurake, amarga ndadekake iku bisa kanggo ndeleng repetitions lan nggunakake kawruh iki kanggo decryption. Kanggo informasi luwih lengkap babagan ECB lan CBC, aku menehi saran supaya maca materi: " Mode buku kode elektronik ". Nanging enkripsi simetris duwe masalah sing jelas - sampeyan kudu nransfer kunci saka sing ndhelik menyang sing ndhelik. Lan ing sadawane dalan iki, kunci iki bisa dicegat lan banjur bisa nyegat data. Lan enkripsi asimetris dirancang kanggo ngatasi masalah iki.
Arsitektur Kriptografi Jawa: Pambuka pisanan - 10

Enkripsi asimetris

Enkripsi asimetris utawa kriptografi kunci publik minangka cara enkripsi sing nggunakake sepasang kunci: kunci pribadi (dirahasiakake saka saben wong) lan kunci umum (kasedhiya kanggo umum). Pemisahan iki perlu kanggo ijol-ijolan kunci umum kanthi aman ing antarane para pihak kanggo ijol-ijolan informasi, nalika njaga kunci rahasia kanthi aman. Nalika nggawe pasangan kunci, KeyGenerator ora cukup maneh; kita butuh KeyPairGenerator . Ayo katon ing conto:
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 kanggo mangerteni ing kene yen nalika nggunakake enkripsi asimetris, kita tansah nggunakake KeyPair kanggo nggunakake siji tombol kanggo enkripsi lan liyane kanggo dekripsi. Nanging amarga Titik enkripsi yaiku mung panampa sing bisa dekripsi; dienkripsi nganggo kunci umum, lan dekripsi mung nganggo kunci pribadi.
Arsitektur Kriptografi Jawa: Kawitan kenalan - 11

Tandha digital

Kaya sing wis dingerteni ing ndhuwur, ngerti kunci umum, sampeyan bisa ngirim data supaya mung pemilik kunci pribadi sing bisa dekripsi. Yaiku, inti saka enkripsi asimetris yaiku sapa wae sing ngenkripsi, nanging mung kita maca. Ana uga prosedur mbalikke - tandha digital, diwakili dening kelas Signature . Tandha digital bisa nggunakake algoritma ing ngisor iki: " Algoritma Tandha ". Dokumentasi JCA nyaranake nliti loro iki: DSAwithMD5 lan RSAwithMD5 Apa sing luwih apik tinimbang DSA utawa RSA lan apa bedane sampeyan bisa maca ing kene: " Kang Paling Apik kanggo Transfer File Enkripsi - RSA utawa DSA? ". Utawa maca diskusi ing kene: " RSA vs. DSA kanggo kunci otentikasi SSH ". Dadi, tandha digital. Kita butuh, kaya sadurunge, KeyPair lan kelas Signature anyar. Yen sampeyan wis nguji kompiler online nganti saiki, conto ing ngisor iki bisa uga angel kanggo dheweke. Contoku mung mlayu ing kene: rextester.com . Kita ngimpor kelas sing dibutuhake:
import javax.crypto.*;
import java.security.*;
Kita uga bakal nulis ulang cara 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));
    }
}
Iki minangka tandha digital. Tandha digital minangka topik sing menarik. Aku menehi saran supaya sampeyan ndeleng laporan babagan topik iki:
Arsitektur Kriptografi Jawa: Kawitan kenalan - 12
Ndhuwur kita weruh carane pihak ijol-ijolan data. Apa ora ana sawetara antarmuka standar kanggo interaksi iki kasedhiya ing JCA? Pranyata ana. Ayo dideleng.
Arsitektur Kriptografi Jawa: Kawitan kenalan - 13

KeyAgreement

Arsitektur Kriptografi Jawa ngenalake alat penting - Persetujuan kunci yaiku protokol. Iki diwakili dening kelas KeyAgreement . Kaya sing kasebut ing dokumentasi JCA, protokol iki ngidini sawetara pihak nyetel kunci kriptografi sing padha tanpa nuduhake informasi rahasia ing antarane pihak. Muni aneh? Banjur ayo ndeleng conto:
// 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));
Conto iki dijupuk saka conto dokumentasi JCA: " Diffie-Hellman Key Exchange antarane 2 Pihak ". Iki kira-kira kaya enkripsi asimetris ing Arsitektur Kriptografi Jawa nggunakake protokol persetujuan Kunci. Kanggo informasi luwih lengkap babagan enkripsi asimetris, dianjurake video:
Arsitektur Kriptografi Jawa: Kawitan kenalan - 14

Sertifikat

Inggih, kanggo panganan cuci mulut, kita isih duwe sing ora kalah penting - sertifikat. Biasane, sertifikat digawe nggunakake utilitas keytool sing kalebu karo jdk. Sampeyan bisa maca rincian liyane, contone, kene: " Ngasilake sertifikat SSL sing ditandatangani dhewe nggunakake printah keytool Java ". Sampeyan uga bisa maca manual saka Oracle. Contone, ing kene: " Gunakake keytool kanggo Nggawe Sertifikat Server ". Contone, ayo nggunakake 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));
  }
}
Kaya sing kita deleng, sertifikat menehi kemampuan kanggo nyedhiyakake kunci umum. Cara iki nduweni kekurangan - kita nggunakake sun.security, sing dianggep beboyo, amarga... paket iki ora bagean saka API Jawa umum. Mulane sak kompilasi perlu kanggo nemtokake parameter - XDignore.symbol.file. Ana cara liya - nggawe sertifikat kanthi manual. Kelemahane yaiku nggunakake API internal sing ora didokumentasikan. Nanging, migunani kanggo ngerti babagan iki. Paling ora, amarga katon kanthi jelas carane spesifikasi RFC-2459 digunakake: " Internet X.509 Public Key Infrastructure ". Iki contone:
// 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 Jawa: Pambuka pisanan - 15

Toko Kunci (Toko Kunci)

Wangsulan: Bab ingkang pungkasan aku arep ngomong bab iku nyimpen kunci lan sertifikat, kang disebut KeyStore. Cetha yen terus-terusan ngasilake sertifikat lan kunci larang lan ora ana gunane. Mulane, kudu disimpen kanthi aman. Ana alat kanggo iki - KeyStore. Toko tombol diterangake ing dokumentasi JCA ing " KeyManagement " bab. API kanggo nggarap iku cetha banget. Punika conto cilik:
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());
}
Kaya sing sampeyan ngerteni saka conto, dieksekusi dhisik loadkanggo KeyStore. Nanging ing kasus kita, kita nemtokake atribut pisanan minangka null, i.e. ora ana sumber kanggo KeyStore. Iki tegese KeyStore digawe kosong kanggo nyimpen luwih lanjut. Parameter kapindho uga null, amarga kita nggawe KeyStore anyar. Yen kita mbukak KeyStore saka file, mula kita kudu nemtokake tembung sandhi ing kene (padha karo metode KeyStore sing diarani nyimpen).

Garis ing ngisor

Dadi, kita wis mriksa karo sampeyan tumindak paling dhasar lan dhasar ing kerangka Arsitektur Kriptografi Jawa (alias JCA). Kita weruh apa enkripsi simetris lan asimetris lan cara dileksanakake ing JCA. Kita weruh carane sertifikat lan teken digital digawe lan carane digunakake. Iki kabeh mung dhasar, ing mburi ana akeh perkara sing luwih rumit lan menarik. Muga-muga materi review iki migunani lan bakal narik minat sampeyan kanggo sinau luwih lanjut babagan wilayah iki.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION