Vodič za klasu šifre

1. Pregled

Jednostavno rečeno, šifriranje je postupak kodiranja poruke takav da je samo ovlašteni korisnici mogu razumjeti ili joj pristupiti.

Poruka, nazvana otvoreni tekst, šifriran je algoritmom šifriranja - a šifra - generiranje šifrirani tekst koje mogu pročitati samo ovlašteni korisnici putem dešifriranja.

U ovom smo članku detaljno opisali Jezgra Šifra klase, koja pruža funkciju kriptografskog šifriranja i dešifriranja na Javi.

2. Klasa šifre

Proširenje za kriptografiju Java (JCE) je dio Java Cryptography Architecture (JCA) koja pruža aplikaciju s kriptografskim šiframa za šifriranje i dešifriranje podataka, kao i za raspršivanje privatnih podataka.

The Šifra razred - smješten u javax.crypto paket - čini jezgru JCE okvira, pružajući funkcionalnost za šifriranje i dešifriranje.

2.1. Instalacija šifre

Za instanciranje a Šifra objekt, mi nazovite statičkim getInstance metoda, prosljeđujući naziv tražene transformacije. Po želji se može navesti ime davatelja usluge.

Napišimo primjer klase koja ilustrira instanciju a Šifra:

public class Encryptor {javni byte [] encryptMessage (byte [] poruka byte [] keyBytes) baca InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException {šifra šifra = Cipher.getInstance ( "AES / ECB / PKCS5Padding"); // ...}}

Transformacija AES / ECB / PKCS5Dopadanje govori getInstance metoda za instanciranje Šifra objekt kao AES šifra s ECB načinom rada i PKCS5 shemom popunjavanja.

Također možemo instancirati Šifra objekt specificirajući samo algoritam u transformaciji:

Šifra šifra = Cipher.getInstance ("AES");

U ovom će slučaju Java koristiti zadane vrijednosti davatelja usluga za način rada i shemu dodavanja.

Imajte na umu da getInstance bacit će a NoSuchAlgorithmException ako je transformacija null, prazan ili u nevaljanom formatu ili ako ga davatelj usluga ne podržava.

Bacit će a NoSuchPaddingException ako transformacija sadrži nepodržanu shemu dodavanja.

2.2. Sigurnost navoja

The Šifra klasa je državna bez ikakvog oblika interne sinkronizacije. Zapravo, metode poput u tome() ili ažuriranje() promijenit će unutarnje stanje određenog Šifra primjer.

Stoga je Šifra klasa nije zaštićena nitima. Pa bismo ga trebali stvoriti Šifra primjerak po potrebi šifriranja / dešifriranja.

2.3. Ključevi

The Ključ sučelje predstavlja ključeve za kriptografske operacije. Ključevi su neprozirni spremnici koji sadrže kodirani ključ, format kodiranja ključa i njegov kriptografski algoritam.

Ključevi se obično dobivaju putem generatora ključeva, certifikata ili specifikacija ključeva pomoću tvornice ključeva.

Stvorimo simetrično Ključ iz isporučenih bajtova ključa:

SecretKey secretKey = novi SecretKeySpec (keyBytes, "AES");

2.4. Inicijalizacija šifre

Mi zovemo u tome() metoda za inicijalizaciju Cifer objekt s Ključ ili Potvrda i an opmode naznačujući način rada šifre.

Po želji, možemo proći u izvoru slučajnosti. Prema zadanim postavkama a SecureRandom koristi se implementacija instaliranog davatelja najvišeg prioriteta. U suprotnom, koristit će izvor koji osigurava sustav.

Po želji možemo odrediti skup parametara specifičnih za algoritam. Na primjer, možemo proći IvParameterSpec do odredite inicijalizacijski vektor.

Evo dostupnih načina rada šifre:

  • ENCRYPT_MODE: inicijalizirati šifra objekt modu šifriranja
  • DECRYPT_MODE: inicijalizirati šifra prigovoriti načinu dešifriranja
  • WRAP_MODE: inicijalizirati šifra prigovoriti načinu umotavanja ključeva
  • UNWRAP_MODE: inicijalizirati šifra prigovor načinu otpakiranja ključa

Inicirajmo Šifra objekt:

Šifra šifra = Cipher.getInstance ("AES / ECB / PKCS5Padding"); SecretKey secretKey = novi SecretKeySpec (keyBytes, "AES"); cipher.init (Cipher.ENCRYPT_MODE, secretKey); // ...

Sada, u tome metoda baca an InvalidKeyException ako je isporučeni ključ neprikladan za inicijalizaciju šifre, na primjer kada je duljina / kodiranje ključa nevaljano.

Također se baca kada šifra zahtijeva određene parametre algoritma koji se ne mogu odrediti iz ključa ili ako ključ ima veličinu ključa koja premašuje najveću dopuštenu veličinu ključa (određena iz konfiguriranih datoteka politike JCE jurisdikcije).

Pogledajmo primjer pomoću a Potvrda:

javni bajt [] encryptMessage (poruka bajta [, certifikat certifikata) baca InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException {Cipher cipher = Cipher.getInstance ("RSA / ECB / PKCS1Padding"); cipher.init (Cipher.ENCRYPT_MODE, certifikat); // ...}

The Šifra objekt dobiva javni ključ za šifriranje podataka iz certifikata pozivanjem datoteke getPublicKey metoda.

2.5. Šifriranje i dešifriranje

Nakon inicijalizacije Šifra objekt, nazivamo doFinal () metoda za izvođenje operacije šifriranja ili dešifriranja. Ova metoda vraća niz bajtova koji sadrži šifriranu ili dešifriranu poruku.

The doFinal () metoda također resetira Šifra prigovoriti stanju u kojem je bio kada je prethodno inicijaliziran pozivom na u tome() metoda, izrada Šifra objekt dostupan za šifriranje ili dešifriranje dodatnih poruka.

Nazovimo doFinal u našem encryptMessage metoda:

javni bajt [] encryptMessage (bajt [] poruka, bajt [] keyBytes) izbacuje InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {Cipher cipher = CipherPgetPCP / CipherPG. SecretKey secretKey = novi SecretKeySpec (keyBytes, "AES"); cipher.init (Cipher.ENCRYPT_MODE, secretKey); povratna šifra.doFinal (poruka); }

Da bismo izvršili operaciju dešifriranja, mijenjamo opmode do DECRYPT_MODE:

javni bajt [] decryptMessage (bajt [] encryptedMessage, bajt [] keyBytes) baca NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {Cipher cipherS / Cipher Cipher Cipher Cipher Cipher Cipher Cipher Cipher Cipher Cipher Cipher Cipher cipherds / Cipher cipherds SecretKey secretKey = novi SecretKeySpec (keyBytes, "AES"); cipher.init (Cipher.DECRYPT_MODE, secretKey); povratna šifra.doFinal (encryptedMessage); }

2.6. Pružatelji usluga

Dizajniran za upotrebu arhitekture zasnovane na davatelju usluga, JCE omogućuje da se kvalificirane biblioteke kriptografije, poput BouncyCastlea, priključe kao pružatelji sigurnosti i da se novi algoritmi dodaju bez problema.

Sad dodajmo BouncyCastle kao pružatelja sigurnosti. Davatelja zaštite možemo dodati statički ili dinamički.

Da bismo statično dodali BouncyCastle, mijenjamo java.sigurnost datoteka smješteno u / jre / lib / sigurnost mapu.

Dodamo redak na kraju popisa:

... security.provider.4 = com.sun.net.ssl.internal.ssl.Provider security.provider.5 = com.sun.crypto.provider.SunJCE security.provider.6 = sun.security.jgss.SunProvider security.provider.7 = org.bouncycastle.jce.provider.BouncyCastleProvider

Kada dodajete svojstvo davatelja, ključ svojstva je u formatu sigurnost.dobavljač.N gdje je broj N je jedan više od zadnjeg na popisu.

Također možemo dinamički dodati pružatelja zaštite BouncyCastle bez potrebe za izmjenom sigurnosne datoteke:

Security.addProvider (novi BouncyCastleProvider ());

Sada možemo odrediti davatelja usluge tijekom inicijalizacije šifre:

Šifra šifre = Cipher.getInstance ("AES / ECB / PKCS5Padding", "BC");

PRIJE KRISTA određuje BouncyCastle kao pružatelja usluga. Popis registriranih davatelja usluga možemo dobiti putem Security.getProviders () metoda.

3. Testiranje šifriranja i dešifriranja

Napišimo primjer testa za ilustraciju šifriranja i dešifriranja poruka.

U ovom testu koristimo algoritam AES šifriranja sa 128-bitnim ključem i tvrdimo da je dešifrirani rezultat jednak izvornom tekstu poruke:

@Test public void whenIsEncryptedAndDecrypted_thenDecryptedEqualsOriginal () baca iznimku {String encryptionKeyString = "thisisa128bitkey"; String originalMessage = "Ovo je tajna poruka"; bajt [] encryptionKeyBytes = encryptionKeyString.getBytes (); Šifra šifre = Cipher.getInstance ("AES / ECB / PKCS5Padding"); SecretKey secretKey = novi SecretKeySpec (encryptionKeyBytes, "AES"); cipher.init (Cipher.ENCRYPT_MODE, secretKey); bajt [] encryptedMessageBytes = cipher.doFinal (message.getBytes ()); cipher.init (Cipher.DECRYPT_MODE, secretKey); byte [] decryptedMessageBytes = cipher.doFinal (encryptedMessageBytes); assertThat (originalMessage) .isEqualTo (novi String (decryptedMessageBytes)); }

4. Zaključak

U ovom smo članku razgovarali o Šifra razreda i predstavljeni primjeri uporabe. Više detalja o Šifra razreda i JCE Framework mogu se naći u dokumentaciji klase i Referentnom vodiču Java Cryptography Architecture (JCA).

Implementacija svih ovih primjera i isječaka koda može se naći na GitHubu. Ovo je projekt zasnovan na Mavenu, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.