cert-encoder.git

ref: 8e6434d3fe106afc2bbb1982d9520723b8dbf7af

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