1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.archivers.sevenz;
20
21 import java.security.GeneralSecurityException;
22 import java.security.NoSuchAlgorithmException;
23 import java.security.SecureRandom;
24
25 import javax.crypto.Cipher;
26 import javax.crypto.SecretKey;
27 import javax.crypto.spec.IvParameterSpec;
28 import javax.crypto.spec.SecretKeySpec;
29
30
31
32
33
34
35
36 final class AES256Options {
37
38 private static final byte[] EMPTY_BYTE_ARRAY = {};
39
40 static final String ALGORITHM = "AES";
41
42 static final String TRANSFORMATION = "AES/CBC/NoPadding";
43
44 static SecretKeySpec newSecretKeySpec(final byte[] bytes) {
45 return new SecretKeySpec(bytes, ALGORITHM);
46 }
47
48 private static byte[] randomBytes(final int size) {
49 final byte[] bytes = new byte[size];
50 try {
51 SecureRandom.getInstanceStrong().nextBytes(bytes);
52 } catch (final NoSuchAlgorithmException e) {
53 throw new IllegalStateException("No strong secure random available to generate strong AES key", e);
54 }
55 return bytes;
56 }
57
58 private final byte[] salt;
59 private final byte[] iv;
60
61 private final int numCyclesPower;
62
63 private final Cipher cipher;
64
65
66
67
68 AES256Options(final char[] password) {
69 this(password, EMPTY_BYTE_ARRAY, randomBytes(16), 19);
70 }
71
72
73
74
75
76
77
78
79 AES256Options(final char[] password, final byte[] salt, final byte[] iv, final int numCyclesPower) {
80 this.salt = salt;
81 this.iv = iv;
82 this.numCyclesPower = numCyclesPower;
83
84
85 final byte[] aesKeyBytes = AES256SHA256Decoder.sha256Password(password, numCyclesPower, salt);
86 final SecretKey aesKey = newSecretKeySpec(aesKeyBytes);
87
88 try {
89 cipher = Cipher.getInstance(TRANSFORMATION);
90 cipher.init(Cipher.ENCRYPT_MODE, aesKey, new IvParameterSpec(iv));
91 } catch (final GeneralSecurityException generalSecurityException) {
92 throw new IllegalStateException("Encryption error (do you have the JCE Unlimited Strength Jurisdiction Policy Files installed?)",
93 generalSecurityException);
94 }
95 }
96
97 Cipher getCipher() {
98 return cipher;
99 }
100
101 byte[] getIv() {
102 return iv;
103 }
104
105 int getNumCyclesPower() {
106 return numCyclesPower;
107 }
108
109 byte[] getSalt() {
110 return salt;
111 }
112 }