Sprievodca šifrovacou triedou

1. Prehľad

Jednoducho povedané, šifrovanie je proces kódovania správy tak, aby mu porozumeli alebo k nemu dostali prístup iba oprávnení používatelia.

Správa označovaná ako obyčajný text, je šifrované pomocou šifrovacieho algoritmu - a šifra - generovanie šifrový text ktoré môžu čítať iba autorizovaní používatelia pomocou dešifrovania.

V tomto článku popisujeme podrobne jadro Šifra triedy, ktorá poskytuje funkcie kryptografického šifrovania a dešifrovania v Jave.

2. Šifrovacia trieda

Java Cryptography Extension (JCE) je súčasť architektúry Java Cryptography Architecture (JCA) ktorá poskytuje aplikáciu s kryptografickými šiframi na šifrovanie a dešifrovanie údajov, ako aj na hašovanie súkromných údajov.

The Šifra trieda - nachádza sa v javax.crypto balík - tvorí jadro rámca JCE a poskytuje funkcie šifrovania a dešifrovania.

2.1. Šifrovanie

Na vytvorenie inštancie a Šifra objekt, my volať statický getInstance metóda, odovzdanie názvu požadovanej transformácie. Voliteľne je možné uviesť meno poskytovateľa.

Poďme napísať príkladnú triedu ilustrujúcu inštanciu a Šifra:

public class Encryptor {public byte [] encryptMessage (byte [] message, byte [] keyBytes) hodí InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException {Cipher cipher = Cipher.getInstance ("AES / ECB / PKCS5Padding"); // ...}}

Transformácia Výplň AES / ECB / PKCS5 hovorí getInstance metóda na vytvorenie inštancie Šifra objekt ako šifra AES s prevádzkovým režimom ECB a výplňovou schémou PKCS5.

Môžeme tiež vytvoriť inštanciu Šifra objekt zadaním iba algoritmu pri transformácii:

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

V takom prípade Java použije predvolené hodnoty špecifické pre poskytovateľa pre režim a výplňovú schému.

Poznač si to getInstance bude hádzať a NoSuchAlgorithmException ak je transformácia nulový, prázdny alebo v neplatnom formáte, alebo ak to poskytovateľ nepodporuje.

Bude vrhať a NoSuchPaddingException ak transformácia obsahuje nepodporovanú výplňovú schému.

2.2. Bezpečnosť závitov

The Šifra trieda je stavová bez akejkoľvek formy vnútornej synchronizácie. Ako v skutočnosti, metódy ako init () alebo aktualizácia () zmení vnútorný stav konkrétneho Šifra inštancia.

Preto Šifra trieda nie je bezpečná pre vlákna. Mali by sme si ich teda vytvoriť Šifra inštancia na potrebu šifrovania / dešifrovania.

2.3. Kľúče

The Kľúč rozhranie predstavuje kľúče pre kryptografické operácie. Kľúče sú nepriehľadné kontajnery, ktoré obsahujú kódovaný kľúč, formát kódovania kľúča a jeho kryptografický algoritmus.

Kľúče sa zvyčajne získavajú prostredníctvom generátorov kľúčov, certifikátov alebo špecifikácií kľúčov pomocou továrne na kľúče.

Vytvorme symetrický Kľúč z dodaných kľúčových bajtov:

SecretKey secretKey = nový SecretKeySpec (keyBytes, "AES");

2.4. Inicializácia šifry

Voláme init () metóda na inicializáciu C.ipher objekt s Kľúč alebo Osvedčenie a an opmode indikujúci prevádzkový režim šifry.

Voliteľne môžeme odovzdať zdroj náhodnosti. Štandardne a SecureRandom používa sa implementácia poskytovateľa s najvyššou prioritou. V opačnom prípade použije zdroj poskytnutý systémom.

Môžeme voliteľne špecifikovať množinu parametrov špecifických pre algoritmus. Napríklad môžeme zložiť znak IvParameterSpec do zadajte inicializačný vektor.

Tu sú dostupné režimy prevádzky šifry:

  • ENCRYPT_MODE: inicializovať šifra namietajte proti režimu šifrovania
  • DECRYPT_MODE: inicializovať šifra namietať proti režimu dešifrovania
  • WRAP_MODE: inicializovať šifra namietajte proti režimu zabalenia kľúčov
  • UNWRAP_MODE: inicializovať šifra namietajte proti režimu rozbaľovania kľúčov

Poďme inicializovať Šifra objekt:

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

Teraz init metóda hodí InvalidKeyException ak je dodaný kľúč nevhodný na inicializáciu šifry, napríklad keď je neplatná dĺžka / kódovanie kľúča.

Vyvolá sa tiež vtedy, keď šifra vyžaduje určité parametre algoritmu, ktoré sa nedajú určiť z kľúča, alebo ak má kľúč veľkosť kľúča, ktorá presahuje maximálnu povolenú veľkosť kľúča (určené z nakonfigurovaných súborov politiky jurisdikcie JCE).

Pozrime sa na príklad pomocou a Osvedčenie:

public byte [] encryptMessage (byte [] správa, certifikát certifikát) hodí InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException {Cipher cipher = Cipher.getInstance ("RSA / ECB / PKCS1Padding"); cipher.init (Cipher.ENCRYPT_MODE, certifikát); // ...}

The Šifra objekt získa verejný kľúč na šifrovanie údajov z certifikátu volaním súboru getPublicKey metóda.

2.5. Šifrovanie a dešifrovanie

Po inicializácii Šifra objekt, hovoríme doFinal () metóda vykonania operácie šifrovania alebo dešifrovania. Táto metóda vráti bajtové pole obsahujúce šifrovanú alebo dešifrovanú správu.

The doFinal () metóda tiež vynuluje Šifra vzniesť námietku proti stavu, v ktorom sa nachádzala, keď bola predtým inicializovaná volaním init () metóda výroby Šifra objekt dostupný na šifrovanie alebo dešifrovanie ďalších správ.

Zavoláme doFinal v našom encryptMessage metóda:

public byte [] encryptMessage (byte [] správa, byte [] keyBytes) hodí InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {Cipher cipher = Cipher.getInstance ("AES / ECB / PKCS5Padding"); SecretKey secretKey = nový SecretKeySpec (keyBytes, "AES"); cipher.init (Cipher.ENCRYPT_MODE, secretKey); return cipher.doFinal (správa); }

Ak chcete vykonať operáciu dešifrovania, zmeníme opmode do DECRYPT_MODE:

public byte [] decryptMessage (byte [] encryptedMessage, byte [] keyBytes) vyhodí NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {Cipher cipher = Cipher.getInstance ("AES / ECB /" PKCS5) SecretKey secretKey = nový SecretKeySpec (keyBytes, "AES"); cipher.init (Cipher.DECRYPT_MODE, secretKey); návratová šifra.doFinal (encryptedMessage); }

2.6. Poskytovatelia

Navrhnutý tak, aby používal architektúru založenú na poskytovateľoch, JCE umožňuje zapojenie kvalifikovaných kryptografických knižníc ako BouncyCastle ako poskytovateľov zabezpečenia a bezproblémové pridávanie nových algoritmov.

Teraz pridajme BouncyCastle ako poskytovateľa zabezpečenia. Poskytovateľa zabezpečenia môžeme pridať buď staticky, alebo dynamicky.

Ak chcete staticky pridať BouncyCastle, upravíme java.bezpečnosť spis nachádza sa v / jre / lib / bezpečnosť priečinok.

Riadok pridáme na koniec zoznamu:

... 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

Pri pridávaní vlastnosti poskytovateľa je kľúč vlastnosti vo formáte zabezpečovací.poskytovateľ.N kde číslo N je o jeden viac ako posledný na zozname.

Môžeme tiež dynamicky pridať poskytovateľa zabezpečenia BouncyCastle bez úpravy bezpečnostného súboru:

Security.addProvider (nový BouncyCastleProvider ());

Teraz môžeme určiť poskytovateľa počas inicializácie šifry:

Cipher cipher = Cipher.getInstance ("AES / ECB / PKCS5Padding", "BC");

Pred Kr špecifikuje ako poskytovateľa BouncyCastle. Zoznam registrovaných poskytovateľov môžeme získať prostredníctvom Security.getProviders () metóda.

3. Testovanie šifrovania a dešifrovania

Poďme si napísať ukážkový test na ilustráciu šifrovania a dešifrovania správy.

V tomto teste používame šifrovací algoritmus AES so 128-bitovým kľúčom a tvrdíme, že dešifrovaný výsledok sa rovná pôvodnému textu správy:

@ Test public void whenIsEncryptedAndDecrypted_thenDecryptedEqualsOriginal () vyvolá výnimku {String encryptionKeyString = "thisisa128bitkey"; String originalMessage = "Toto je tajná správa"; byte [] encryptionKeyBytes = encryptionKeyString.getBytes (); Šifra šifra = Cipher.getInstance ("AES / ECB / PKCS5Padding"); SecretKey secretKey = nový SecretKeySpec (encryptionKeyBytes, "AES"); cipher.init (Cipher.ENCRYPT_MODE, secretKey); byte [] encryptedMessageBytes = cipher.doFinal (message.getBytes ()); cipher.init (Cipher.DECRYPT_MODE, secretKey); byte [] decryptedMessageBytes = cipher.doFinal (encryptedMessageBytes); assertThat (originalMessage) .isEqualTo (nový reťazec (decryptedMessageBytes)); }

4. Záver

V tomto článku sme diskutovali o Šifra triedy a prezentované príklady použitia. Viac podrobností na webe Šifra triedy a rámec JCE nájdete v dokumentácii triedy a referenčnej príručke Java Cryptography Architecture (JCA).

Implementácia všetkých týchto príkladov a útržkov kódu môže byť najdený cez GitHub. Toto je projekt založený na Maven, takže by malo byť ľahké ho importovať a spustiť tak, ako je.