Šifrovanie a dešifrovanie súborov v prostredí Java
Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:
>> SKONTROLUJTE KURZ1. Prehľad
V tomto výučbe sa pozrieme na to, ako šifrovať a dešifrovať súbor pomocou existujúcich rozhraní JDK API.
2. Písanie testu ako prvé
Začneme tým, že napíšeme náš test, TDD štýl. Pretože tu budeme pracovať so súbormi, zdá sa byť vhodný test integrácie.
Pretože používame iba existujúcu funkčnosť JDK, nie sú potrebné žiadne externé závislosti.
Najprv, zašifrujeme obsah pomocou novo vygenerovaného tajného kľúča (ako symetrický šifrovací algoritmus v tomto príklade používame AES, Advanced Encryption Standard).
Upozorňujeme tiež, že v konštruktore definujeme celý transformačný reťazec (Výplň AES / CBC / PKCS5), čo je zreťazenie použitého šifrovania, režimu blokovej šifry a výplne (algoritmus / režim / výplň). Implementácie JDK štandardne podporujú množstvo rôznych transformácií, upozorňujeme však, že nie každá kombinácia môže byť podľa dnešných štandardov stále považovaná za kryptograficky bezpečnú.
Budeme predpokladať náš FileEncrypterDecrypter trieda zapíše výstup do súboru s názvom baz.enc. Potom, dešifrujeme tento súbor pomocou rovnakého tajného kľúča a skontrolujte, či sa dešifrovaný obsah rovná pôvodnému obsahu:
@Test public void whenEncryptingIntoFile_andDecryptingFileAgain_thenOriginalStringIsReturned () {String originalContent = "foobar"; SecretKey secretKey = KeyGenerator.getInstance ("AES"). GenerateKey (); FileEncrypterDecrypter fileEncrypterDecrypter = nový FileEncrypterDecrypter (secretKey, "AES / CBC / PKCS5Padding"); fileEncrypterDecrypter.encrypt (originalContent, "baz.enc"); Reťazec decryptedContent = fileEncrypterDecrypter.decrypt ("baz.enc"); assertThat (decryptedContent, is (originalContent)); nový súbor („baz.enc“). delete (); // vyčistiť }
3. Šifrovanie
Inicializujeme šifru v konštruktore našej FileEncrypterDecrypter triedy pomocou zadanej transformácie String.
To nám umožňuje predčasné zlyhanie v prípade, že bola zadaná nesprávna transformácia:
FileEncrypterDecrypter (SecretKey secretKey, transformácia reťazca) {this.secretKey = secretKey; this.cipher = Cipher.getInstance (transformácia); }
Môžeme potom na vykonanie šifrovania použite inštančnú šifru a poskytnutý tajný kľúč:
void encrypt (String content, String fileName) {cipher.init (Cipher.ENCRYPT_MODE, secretKey); byte [] iv = cipher.getIV (); try (FileOutputStream fileOut = nový FileOutputStream (názov súboru); CipherOutputStream cipherOut = nový CipherOutputStream (fileOut, šifra)) {fileOut.write (iv); cipherOut.write (content.getBytes ()); }}
Java nám to umožňuje využiť pohodlné CipherOutputStream trieda na zápis šifrovaného obsahu do iného OutputStream.
Upozorňujeme, že IV (inicializačný vektor) píšeme na začiatok výstupného súboru. V tomto príklade sa IV generuje automaticky pri inicializácii Šifra.
Pri použití režimu CBC je použitie IV povinné, aby sa náhodne uskutočnil šifrovaný výstup. IV sa však nepovažuje za tajomstvo, takže je v poriadku napísať ho na začiatok súboru.
4. Dešifrovanie
Pre dešifrovanie musíme tiež najskôr prečítať IV. Potom môžeme inicializovať našu šifru a dešifrovať obsah.
Opäť môžeme využiť špeciálnu triedu Java, CipherInputStream, ktorá sa transparentne stará o samotné dešifrovanie:
Reťazec dešifrovať (Reťazec názov súboru) {Obsah reťazca; try (FileInputStream fileIn = new FileInputStream (fileName)) {byte [] fileIv = new byte [16]; fileIn.read (fileIv); cipher.init (Cipher.DECRYPT_MODE, secretKey, nový IvParameterSpec (fileIv)); try (CipherInputStream cipherIn = new CipherInputStream (fileIn, cipher); InputStreamReader inputReader = new InputStreamReader (cipherIn); BufferedReader reader = new BufferedReader (inputReader)) {StringBuilder sb = new StringBuilder (); Šnúrka; while ((line = reader.readLine ())! = null) {sb.append (line); } obsah = sb.toString (); }} vrátiť obsah; }
5. Záver
Videli sme, že môžeme vykonávať základné šifrovanie a dešifrovanie pomocou štandardných tried JDK, ako sú napr Šifra, CipherOutputStream a CipherInputStream.
Úplný kód tohto článku je ako obvykle k dispozícii v našom úložisku GitHub.
Okrem toho tu nájdete zoznam šifier dostupných v JDK.
Nakoniec si všimnite, že tu uvedené príklady kódu nie sú myslené ako kód na úrovni výroby a pri ich používaní je potrebné dôkladne zohľadniť špecifiká vášho systému.
Java dole