Bonsoir à tous.

Tout d'abord, toutes mes excuses si le sujet est mal placé, il me semblait que cette section était la plus appropriée, étant donné que je suis un débutant en Java.

Mon problème concerne le cryptage et le décryptage avec une paire de clés RSA.
J'ai tout d'abord crypté et décrypté un fichier, puis affiché le contenu de ce décryptage dans le terminal (ce qui s'est très bien déroulé).

En ce qui concerne la gestion de clés, je génère des clés de taille 2048, que je vais stocker dans un fichier public.key et .private.key
Puis, je récupère ces clés dans une nouvelle KeyPair afin de tester cette fonctionnalité, qui m'est demandée.

Dans un dernier temps, mon but est de récupérer le contenu d'un fichier d'entrée, le crypter et envoyer ce contenu crypté dans un nouveau fichier (ce qui est fait).
Mon problème vient alors lors de la décryption, quand j'essaye de reprendre les données binaires de ce fichier ainsi crypté, je n'arrive pas à les décrypter.

J'aimerais avoir votre avis sur le problème si possible.

Voila mon code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
package com.bodom.ghosty;
 
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.List;
 
public class EncryptionUtil {
 
    /**
     * Generate a pair of RSA keys
     *
     * @return A keypair of RSA keys
     * @throws NoSuchAlgorithmException
     */
    public static KeyPair keyGenerate() throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        return keyGen.genKeyPair();
    }
 
 
    /**
     * Crypt data
     *
     * @param data      Data to encrypt
     * @param publicKey PublicKey used to crypt
     * @return          The crypted data
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    private static byte[] rsaEncryption(byte[] data, PublicKey publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data); //Encrypte data avec le cipher, tel qu'il a été paramétré, ici en mode RSA, en encryption, encryption qui va utiliser la clé publique.
    }
 
 
    /**
     * Encrypt a file
     *
     * @param file      Path of the file to crypt
     * @param charset   Charset used to read the file
     * @param publicKey PublicKey used to crypt the file
     * @return          A byte array which contains the crypted lines of the file
     * @throws IOException
     * @throws IllegalBlockSizeException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     */
    public static byte[] encryption (Path file, Charset charset, PublicKey publicKey) throws IOException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        List<String> lines = Files.readAllLines(file, charset); //Récupère toutes les lignes du fichier
        byte[] cryptedfile = null; //contiendra les bytes cryptés du fichier
        for(String line : lines) { //on parcourt toutes les lignes
            byte[] crypt = rsaEncryption(line.getBytes(), publicKey); //On crypte la ligne du fichier
            byte[] tmp;
            tmp = cryptedfile; //variable temporaire qui contiendra les bytes cryptés précédemment
 
            if (tmp != null) { //on initialise cryptedfile pour qu'il accueille les bytes cryptées précédemment + les courants
                cryptedfile = new byte[crypt.length + tmp.length];
            }
            else cryptedfile = new byte[crypt.length];
 
            System.arraycopy(crypt, 0, cryptedfile, 0, crypt.length); //Concaténation des tableaux de bytes
            if (tmp != null) {
                System.arraycopy(tmp, 0, cryptedfile, crypt.length, tmp.length);
            }
        }
        return cryptedfile;
    }
 
 
    /**
     * Decrypt data
     *
     * @param crypteddata Crypted data to decrypt
     * @param privateKey  PrivateKey used to decrypt
     * @return            The decrypted data
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    private static byte[] rsaDecryption(byte[] crypteddata, PrivateKey privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding"); //cipher en mode RSA
        cipher.init(Cipher.DECRYPT_MODE, privateKey); //cipher en mode Decryptage, avec la clé privée en param
        return cipher.doFinal(crypteddata); //décryptage du tableau de bytes et on renvoie un tableau de bytes décryptées
    }
 
 
    /**
     * Read the bytes of a file
     *
     * @param file is the file to read
     * @return     the bytes of the file
     * @throws IOException
     */
    private static byte[] readBytesInFile (Path file) throws IOException {
        byte[] result = new byte[(int)Files.size(file)];
        try {
            try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file.getFileName().toString()))) {
                int bytesRead = 0;
                while (bytesRead < result.length) {
                    int bytesLeft = result.length - bytesRead;
                    int bytesGet = inputStream.read(result, bytesRead, bytesLeft);
                    if (bytesGet > 0) {
                        bytesRead += bytesGet;
                    }
                }
            }
        } catch (IOException e) {
            System.out.println(e);
        }
        return result;
    }
 
    /**
     * Decrypt a file
     *
     * @param file       Path of the file to decrypt
     * @param privateKey PrivateKey used to decrypt the file
     * @return           A byte array which contains the decrypted lines of the file
     * @throws IOException
     * @throws IllegalBlockSizeException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     */
    public static byte[] decryption(Path file, PrivateKey privateKey) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
        byte[] crypteddata = readBytesInFile(file); //lecture des bytes du fichier spécifié
        int offset = 0;
        byte[] decryptedfile = null;
 
        //Parcours de tous les bytes du fichier
        while (offset < crypteddata.length) {
            byte[] outputBytes;
            byte[] tmp;
 
            //Si il reste moins de 200 bytes
            if(crypteddata.length - offset < 200 ) {
                //Copie du contenu restant de crypteddata dans outputBytes
                outputBytes = new byte[crypteddata.length - offset];
                System.arraycopy(crypteddata, offset, outputBytes, 0, crypteddata.length - offset);
 
                //Decryptage de la partie de bytes
                byte[] decrypt = rsaDecryption(outputBytes, privateKey);
 
                //Update de la taille pour recevoir la concaténation
                tmp = decryptedfile;
                if (tmp != null) {
                    decryptedfile = new byte[decrypt.length + tmp.length];
                }
                else decryptedfile = new byte[decrypt.length];
 
                //Concaténation des bytes décryptés
                System.arraycopy(decrypt, 0, decryptedfile, 0, decrypt.length);
                if (tmp != null) {
                    System.arraycopy(tmp, 0, decryptedfile, decrypt.length, tmp.length);
                }
                break;
            }
 
            //Création de la partie de bytes, et copie du contenu de crypteddata de offset à offset+200 et mise dans outputBytes de 0 à 200
            outputBytes = new byte[200];
            System.arraycopy(crypteddata, offset, outputBytes, 0, 200);
 
            //Decryptage de la partie de bytes
            byte[] decrypt = rsaDecryption(outputBytes, privateKey);
 
            //Update de la taille pour recevoir la concaténation
            tmp = decryptedfile;
            if (tmp != null) {
                decryptedfile = new byte[decrypt.length + tmp.length];
            }
            else decryptedfile = new byte[decrypt.length];
 
            //Concaténation dans decryptedfile de la partie de bytes
            System.arraycopy(decrypt, 0, decryptedfile, 0, decrypt.length);
            if (tmp != null) {
                System.arraycopy(tmp, 0, decryptedfile, decrypt.length, tmp.length);
            }
            offset +=200 ;
        }
        return decryptedfile;
    }
 
    /**
     * Save a key in a file
     *
     * @param modulus  Modulus of the key to save
     * @param exponent Exponent of the key to save
     * @param filename File used to save the keys
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    private static void saveKeyToFile (BigInteger modulus, BigInteger exponent, String filename) throws IOException, NoSuchAlgorithmException {
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(filename)))) {
            objectOutputStream.writeObject(modulus);
            objectOutputStream.writeObject(exponent);
        }
    }
 
    /**
     * Save a KeyPair in two files
     *
     * @param keyPair KeyPair to save
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void saveKeyPair(KeyPair keyPair) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
 
        RSAPublicKeySpec rsaPublicKeySpec = keyFactory.getKeySpec(keyPair.getPublic(), RSAPublicKeySpec.class);
        saveKeyToFile(rsaPublicKeySpec.getModulus(), rsaPublicKeySpec.getPublicExponent(), "keys/public.key");
 
        RSAPrivateKeySpec rsaPrivateKeySpec = keyFactory.getKeySpec(keyPair.getPrivate(), RSAPrivateKeySpec.class);
        saveKeyToFile(rsaPrivateKeySpec.getModulus(), rsaPrivateKeySpec.getPrivateExponent(), "keys/.private.key");
    }
 
    /**
     * Get a PublicKey from a file
     *
     * @param filename File where the PublicKey is saved
     * @return         The PublicKey get in the file
     * @throws IOException
     * @throws ClassNotFoundException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    private static PublicKey getPublicKeyFromFile (String filename) throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException {
        try (ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream(filename)))) {
            BigInteger modulus = (BigInteger) objectInputStream.readObject();
            BigInteger exponent = (BigInteger) objectInputStream.readObject();
 
            RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, exponent);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePublic(rsaPublicKeySpec);
        }
    }
 
    /**
     * Get a PrivateKey from a file
     *
     * @param filename File where the PrivateKey is saved
     * @return         The PrivateKey get in the file
     * @throws IOException
     * @throws ClassNotFoundException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    private static PrivateKey getPrivateKeyFromFile (String filename) throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException {
        try (ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream(filename)))) {
            BigInteger modulus = (BigInteger) objectInputStream.readObject();
            BigInteger exponent = (BigInteger) objectInputStream.readObject();
 
            RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(modulus, exponent);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePrivate(rsaPrivateKeySpec);
        }
    }
 
    /**
     * Get the RSA keypair from the files
     *
     * @return The Keypair which contains the public and the private key
     * @throws IOException
     * @throws ClassNotFoundException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static KeyPair getKeysFromFiles () throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException{
        PublicKey publicKey = getPublicKeyFromFile("keys/public.key");
        PrivateKey privateKey = getPrivateKeyFromFile("keys/.private.key");
        return new KeyPair(publicKey, privateKey);
    }
 
    public static void main(String[] args) throws InvalidKeySpecException, NoSuchAlgorithmException {
        // Initialization MARCHE
        KeyPair kp = null;
        try {
            kp = EncryptionUtil.keyGenerate();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
 
        //Saving keys part MARCHE
        try {
            saveKeyPair(kp);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException| IOException e) {
            System.out.println("Error during the storage of the keys : " + e);
        }
 
        //Getting keys part MARCHE
        KeyPair keyPair = null;
 
        try {
            keyPair = getKeysFromFiles();
        } catch (ClassNotFoundException | NoSuchAlgorithmException | InvalidKeySpecException | IOException e) {
            System.out.println("Error during the loading of the keys : " + e);
        }
 
        // Crypt part
        byte[] uncrypt = null;
        try {
            if (keyPair != null) {
                //Cryptage
                byte[] crypt = encryption(Paths.get("file"), Charset.forName("UTF-8"), keyPair.getPublic());
 
                //Inscription dans le fichier (même systeme pour DriveUtil)
                Files.write(Paths.get("cryptedfile"), crypt, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
 
                //Decryptage
                uncrypt = decryption(Paths.get("cryptedfile"), keyPair.getPrivate());
            }
        } catch (InvalidKeyException | NoSuchAlgorithmException
                | NoSuchPaddingException | IllegalBlockSizeException
                | BadPaddingException | IOException e) {
            System.out.println(e);
        }
 
        String s = new String(uncrypt);
        System.out.println(s);
    }
}
Le problème de décryptage est donc surement dans la méthode decryption(), qui s'effectue bien mais ne décrypte pas ; lorsque j'affiche ce qu'elle doit renvoyer, j'obtiens des bytes.
En même temps que ce problème de décryptage, je rappelle que je suis un débutant en Java.
Tous conseils en ce qui concerne ma manière de coder ainsi que les conventions de Java sont les bienvenus!

Merci d'avance pour votre aide.