cert-encoder.git

ref: d648729baf797b2d84f8afdfc9e49c7670af47e9

src/main/java/net/lulli/encrypt/symmetric/SymmetricEncryptionManager.java


 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
/* 
 * This file is part of cert-encoder
 * Copyright (c) 2024 Paolo Lulli.
 * 
 * This program is free software: you can redistribute it and/or modify  
 * it under the terms of the GNU General Public License as published by  
 * the Free Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License 
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package net.lulli.encrypt.symmetric;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.SecureRandom;

public class SymmetricEncryptionManager {
    public static final SymmetricEncryptionManager INSTANCE = new SymmetricEncryptionManager();
    private SymmetricEncryptionManager() {}

    public byte[] encrypt(String plainText, byte[] key) {
        try {
            byte[] clean = plainText.getBytes();

            int ivSize = 16;
            byte[] iv = new byte[ivSize];
            var random = new SecureRandom();
            random.nextBytes(iv);
            var ivParameterSpec = new IvParameterSpec(iv);

            // Hashing key.
            var messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(key);
            byte[] keyBytes = new byte[16];
            System.arraycopy(messageDigest.digest(), 0, keyBytes, 0, keyBytes.length);
            var secretKeySpec = new SecretKeySpec(keyBytes, "AES");

            // Encrypt.
            var cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] encrypted = cipher.doFinal(clean);

            // Combine IV and encrypted part.
            byte[] encryptedIVAndText = new byte[ivSize + encrypted.length];
            System.arraycopy(iv, 0, encryptedIVAndText, 0, ivSize);
            System.arraycopy(encrypted, 0, encryptedIVAndText, ivSize, encrypted.length);

            return encryptedIVAndText;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage());
        }
    }

    public byte[] decrypt(byte[] encryptedIvTextBytes, byte[] key) {
        try {
            int ivSize = 16;
            int keySize = 16;

            // Extract IV.
            byte[] iv = new byte[ivSize];
            System.arraycopy(encryptedIvTextBytes, 0, iv, 0, iv.length);
            var ivParameterSpec = new IvParameterSpec(iv);

            // Extract encrypted part.
            int encryptedSize = encryptedIvTextBytes.length - ivSize;
            byte[] encryptedBytes = new byte[encryptedSize];
            System.arraycopy(encryptedIvTextBytes, ivSize, encryptedBytes, 0, encryptedSize);

            // Hash key.
            byte[] keyBytes = new byte[keySize];
            var messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(key);
            System.arraycopy(messageDigest.digest(), 0, keyBytes, 0, keyBytes.length);
            var secretKeySpec = new SecretKeySpec(keyBytes, "AES");

            // Decrypt.
            var cipherDecrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

            return cipherDecrypt.doFinal(encryptedBytes);

        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage());
        }
    }
}