Java - пример криптографии с симметричным ключом
Криптография с симметричным ключом - это система шифрования, в которой один и тот же ключ используется для кодирования и декодирования данных. Безопасное распространение ключа - один из недостатков этого метода, но недостаток безопасности он выигрывает во временной сложности.
Всегда следует исходить из того, что алгоритмы шифрования общеизвестны и не полагаются на «безопасность через неизвестность». Самыми популярными симметричными алгоритмами являются DES, Triple-DES, AES, Blowfish, RC2, RC4 (ARCFOUR), RC5, RC6.
1. Пример использования криптографии с симметричным ключом
Ниже вы можете увидеть код приложения, которое использует криптографию с симметричным ключом для шифрования или дешифрования предварительно заданного каталога. Конструктор инициализируется паролем, длиной ключа и алгоритмом, который будет использоваться для шифра. Чтобы узнать больше о длинах ключей для каждого алгоритма, обратитесь кImport Limits on Cryptographic Algorithms.
Note
Если вы хотите узнать больше об алгоритмах шифрования, обратитесь кPerformance
Analysis of Data Encryption Algorithms: 2.5 Compared Algorithms
В этом примере мы используем AES, поскольку он считается серебряной накладкой между скоростью и безопасностью.
SymmetricKeyExample.java
package com.techfou.symmetric; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; import javax.swing.JOptionPane; public class SymmetricKeyExample { private SecretKeySpec secretKey; private Cipher cipher; public SymmetricKeyExample(String secret, int length, String algorithm) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException { byte[] key = new byte[length]; key = fixSecret(secret, length); this.secretKey = new SecretKeySpec(key, algorithm); this.cipher = Cipher.getInstance(algorithm); } private byte[] fixSecret(String s, int length) throws UnsupportedEncodingException { if (s.length() < length) { int missingLength = length - s.length(); for (int i = 0; i < missingLength; i++) { s += " "; } } return s.substring(0, length).getBytes("UTF-8"); } public void encryptFile(File f) throws InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException { System.out.println("Encrypting file: " + f.getName()); this.cipher.init(Cipher.ENCRYPT_MODE, this.secretKey); this.writeToFile(f); } public void decryptFile(File f) throws InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException { System.out.println("Decrypting file: " + f.getName()); this.cipher.init(Cipher.DECRYPT_MODE, this.secretKey); this.writeToFile(f); } public void writeToFile(File f) throws IOException, IllegalBlockSizeException, BadPaddingException { FileInputStream in = new FileInputStream(f); byte[] input = new byte[(int) f.length()]; in.read(input); FileOutputStream out = new FileOutputStream(f); byte[] output = this.cipher.doFinal(input); out.write(output); out.flush(); out.close(); in.close(); } public static void main(String[] args) { File dir = new File("src/cryptodir"); File[] filelist = dir.listFiles(); SymmetricKeyExample ske; try { ske = new SymmetricKeyExample("!@#$MySecr3tPassw0rd", 16, "AES"); int choice = -2; while (choice != -1) { String[] options = { "Encrypt All", "Decrypt All", "Exit" }; choice = JOptionPane.showOptionDialog(null, "Select an option", "Options", 0, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); switch (choice) { case 0: Arrays.asList(filelist).forEach(file -> { try { ske.encryptFile(file); } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | IOException e) { System.err.println("Couldn't encrypt " + file.getName() + ": " + e.getMessage()); } }); System.out.println("Files encrypted successfully"); break; case 1: Arrays.asList(filelist).forEach(file -> { try { ske.decryptFile(file); } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | IOException e) { System.err.println("Couldn't decrypt " + file.getName() + ": " + e.getMessage()); } }); System.out.println("Files decrypted successfully"); break; default: choice = -1; break; } } } catch (UnsupportedEncodingException ex) { System.err.println("Couldn't create key: " + ex.getMessage()); } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { System.err.println(e.getMessage()); } } }
Выход
Когда нажата кнопка «Зашифровать все».
Encrypting file: Hello world.docx Encrypting file: Hello world.pdf Encrypting file: Smiley.png Encrypting file: Text.txt Files encrypted successfully
Когда нажата кнопка «Расшифровать все».
Decrypting file: Hello world.docx Decrypting file: Hello world.pdf Decrypting file: Smiley.png Decrypting file: Text.txt Files decrypted successfully
Исходный текстовый файл.
src/Text.txt
This is a text file.
Текстовый файл зашифрован.
src/Text.txt
‡(?ê?z@ou7ÿ—pø"é³.Õ0Ò;jVi¶‚
Обратите внимание: перед запуском этого кода создается отдельный каталог с файлами только для целей этого примера. Загрузите приведенный ниже исходный код, если вы точно не знаете, что делаете.