Java - Exemple de cryptographie à clé symétrique

Java - Exemple de cryptographie à clé symétrique

La cryptographie à clé symétrique est un système de cryptage dans lequel la même clé est utilisée pour le codage et le décodage des données. La distribution sûre de la clé est l'un des inconvénients de cette méthode, mais ce qui lui manque en sécurité, elle le gagne en complexité en temps.

Il faut toujours supposer que les algorithmes de cryptage sont connus du public et ne reposent pas sur la «sécurité par l'obscurité». Les algorithmes symétriques les plus populaires sont DES, Triple-DES, AES, Blowfish, RC2, RC4 (ARCFOUR), RC5, RC6.

1. Cas d'utilisation de la cryptographie à clé symétrique

Ci-dessous, vous pouvez voir le code d'une application qui utilise la cryptographie à clé symétrique pour crypter ou décrypter un répertoire prédéfini. Le constructeur est initialisé avec le mot de passe, la longueur de la clé et l'algorithme qui sera utilisé pour le chiffrement. Pour en savoir plus sur les longueurs de clé de chaque algorithme, reportez-vous àImport Limits on Cryptographic Algorithms.

Note
Si vous voulez en savoir plus sur les algorithmes de chiffrement, reportez-vous àPerformance Analysis of Data Encryption Algorithms: 2.5 Compared Algorithms

Dans cet exemple, nous utilisons AES car il est considéré comme la doublure argentée entre vitesse et sécurité.

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());
        }
    }
}

Sortie

java-symmetrickey-output-1

Lorsque vous cliquez sur le bouton «Crypter tout».

Encrypting file: Hello world.docx
Encrypting file: Hello world.pdf
Encrypting file: Smiley.png
Encrypting file: Text.txt
Files encrypted successfully

Lorsque le bouton «Décrypter tout» est cliqué.

Decrypting file: Hello world.docx
Decrypting file: Hello world.pdf
Decrypting file: Smiley.png
Decrypting file: Text.txt
Files decrypted successfully

Fichier texte original.

src/Text.txt

This is a text file.

Le fichier texte est crypté.

src/Text.txt

‡(?ê?z@ou7ÿ—pø"é³.Õ0Ò;jVi¶‚

Attention: avant d'exécuter ce code crée un répertoire séparé avec des fichiers uniquement pour les besoins de cet exemple. Téléchargez le code source ci-dessous si vous ne savez pas exactement ce que vous faites.

2. Répertoire des projets

java-symmetrickey-example

Télécharger le code source