Šifriranje i dešifriranje datoteka u Javi

Java Top

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

1. Pregled

U ovom ćemo uputstvu pogledati kako šifrirati i dešifrirati datoteku pomoću postojećih JDK API-ja.

2. Prvo pisanje testa

Za početak ćemo napisati naš test, TDD stil. Budući da ćemo ovdje raditi s datotekama, čini se da je prikladan test integracije.

Kako samo koristimo postojeću JDK funkcionalnost, nisu potrebne vanjske ovisnosti.

Prvi, šifrirat ćemo sadržaj pomoću novo generiranog tajnog ključa (u ovom primjeru koristimo AES, Advanced Encryption Standard, kao simetrični algoritam šifriranja).

Također imajte na umu da definiramo kompletni niz transformacije u konstruktoru (AES / CBC / PKCS5Dopadanje), što je spajanje korištene šifriranja, načina blok-šifre i dodavanja (algoritam / način / podmetanje). JDK implementacije podržavaju brojne različite transformacije prema zadanim postavkama, ali imajte na umu da se prema današnjim standardima ne može svaka kombinacija i dalje smatrati kriptografski sigurnom.

Pretpostavit ćemo naše FileEncrypterDecrypter klasa će zapisati izlaz u datoteku pod nazivom baz.enc. Poslije, dešifriramo ovu datoteku istim tajnim ključem i provjerite je li dešifrirani sadržaj jednak izvornom sadržaju:

@Test public void whenEncryptingIntoFile_andDecryptingFileAgain_thenOriginalStringIsReturned () {String originalContent = "foobar"; SecretKey secretKey = KeyGenerator.getInstance ("AES"). Generirajte Key (); FileEncrypterDecrypter fileEncrypterDecrypter = novi FileEncrypterDecrypter (secretKey, "AES / CBC / PKCS5Padding"); fileEncrypterDecrypter.encrypt (originalContent, "baz.enc"); Niz decryptedContent = fileEncrypterDecrypter.decrypt ("baz.enc"); assertThat (decryptedContent, is (originalContent)); nova datoteka ("baz.enc"). delete (); // počistiti }

3. Šifriranje

Inicijalizirat ćemo šifru u konstruktoru našeg FileEncrypterDecrypter klasa pomoću navedene transformacije Niz.

To nam omogućuje rani neuspjeh u slučaju da je navedena pogrešna transformacija:

FileEncrypterDecrypter (SecretKey secretKey, String transformacija) {this.secretKey = secretKey; this.cipher = Cipher.getInstance (transformacija); }

Tada možemo upotrijebite instanciranu šifru i priloženi tajni ključ za izvođenje šifriranja:

void encrypt (Sadržaj niza, StringName file) {cipher.init (Cipher.ENCRYPT_MODE, secretKey); bajt [] iv = šifra.getIV (); isprobajte (FileOutputStream fileOut = new FileOutputStream (fileName); CipherOutputStream cipherOut = new CipherOutputStream (fileOut, cipher)) {fileOut.write (iv); cipherOut.write (content.getBytes ()); }}

Java nam to omogućuje iskoristiti pogodno CipherOutputStream klasa za pisanje šifriranog sadržaja u drugu Izlazni tok.

Imajte na umu da IV (Vekt inicijalizacije) pišemo na početak izlazne datoteke. U ovom se primjeru IV automatski generira prilikom inicijalizacije Šifra.

Korištenje IV je obavezno kada se koristi CBC način rada, kako bi se nasumično šifrirani izlaz. IV se, međutim, ne smatra tajnom, pa je u redu da ga napišete na početku datoteke.

4. Dešifriranje

Za dešifriranje također moramo prvo pročitati IV. Nakon toga možemo inicijalizirati šifru i dešifrirati sadržaj.

Opet možemo koristiti posebnu Java klasu, CipherInputStream, koji se transparentno brine o stvarnom dešifriranju:

Dešifriranje niza (StringName datoteke) {Sadržaj niza; probajte (FileInputStream fileIn = new FileInputStream (fileName)) {byte [] fileIv = novi byte [16]; fileIn.read (fileIv); cipher.init (Cipher.DECRYPT_MODE, secretKey, novi IvParameterSpec (fileIv)); try (CipherInputStream cipherIn = new CipherInputStream (fileIn, cipher); InputStreamReader inputReader = new InputStreamReader (cipherIn); BufferedReader reader = new BufferedReader (inputReader)) {StringBuilder sb = new StringBuild; Linija niza; while ((line = čitač.readLine ())! = null) {sb.append (line); } sadržaj = sb.toString (); }} vratiti sadržaj; }

5. Zaključak

Vidjeli smo da možemo izvoditi osnovno šifriranje i dešifriranje koristeći standardne JDK klase, kao što je Šifra, CipherOutputStream i CipherInputStream.

Kao i obično, cjeloviti kôd za ovaj članak dostupan je u našem GitHub spremištu.

Osim toga, ovdje možete pronaći popis šifri dostupnih u JDK.

Na kraju, imajte na umu da primjeri kodova ovdje nisu zamišljeni kao proizvodni kôd te da se prilikom njihovog korištenja moraju temeljito uzeti u obzir specifičnosti vašeg sustava.

Dno Java

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ