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