1 /*
2 * Title: S/MIME Project
3 * Description: S/MIME email sending capabilities
4 * @Author Vladan Obradovic
5 * @Version 2.0.1
6 */
7
8
9 package org.webdocwf.util.smime.crypto;
10
11
12 import java.security.SecureRandom;
13 import java.security.Key;
14 import javax.crypto.SecretKey;
15 import javax.crypto.KeyGenerator;
16 import javax.crypto.Cipher;
17 import javax.crypto.spec.IvParameterSpec;
18 import javax.crypto.spec.SecretKeySpec;
19 import org.webdocwf.util.smime.exception.SMIMEException;
20 import org.webdocwf.util.smime.exception.ErrorStorage;
21
22
23 /***
24 * SymmetricEncryption class is used for symmetric encryption large amounts
25 * of data. Algorithm names and corresponding key lengths are:<BR>
26 * DES - 56<BR>
27 * DES_EDE3_CBC - 128, 192<BR>
28 * RC2_CBC - 40, 64, 128<BR>
29 */
30 public class SymmetricEncryption {
31
32 /***
33 * Storage for initialization vector (iv).
34 */
35 private byte[] iv = null;
36
37 /***
38 * Storage for symmetric key.
39 */
40 private byte[] symmetricKey = null;
41
42 /***
43 * Storage for symetric key length.
44 */
45 private int symmetricKeyLength = 0;
46
47 /***
48 * Storage for symetric algorithm name.
49 */
50 private String algorithmName = null;
51
52 /***
53 * Container for encrypted message.
54 */
55 private byte[] encryptedValue = null;
56
57 /***
58 * Container for decrypted message.
59 */
60 private byte[] decryptedValue = null;
61
62 /***
63 * Construction with the given algorithm name and key size in bits.
64 * @param algorithmName0 is name of algorithm: "DES", "DES_EDE3_CBC" or "RC2_CBC".
65 * @param keyLength is key size in bits.
66 * @exception SMIMEException thrown in case of invalid algorithm names, or in
67 * case of wrong key sizes in bits.
68 */
69 public SymmetricEncryption(String algorithmName0, int keyLength0) throws SMIMEException {
70 Algorithm alg = new Algorithm(algorithmName0, keyLength0);
71
72 symmetricKeyLength = alg.getKeySize();
73 algorithmName = alg.getAlgorithmName();
74 }
75
76 /***
77 * Encryption of the byte array with random generated key
78 * @param forEncrypt0 is byte array for encryption
79 * @exception SMIMEException caused by non SMIMEException which can be one of
80 * the following: NoSuchPaddingException, NoSuchProviderException,
81 * NoSuchAlgorithmException, InvalidKeyException, BadPaddingException,
82 * IllegalBlockSizeException.
83 */
84 public void encryption(byte[] forEncrypt0) throws SMIMEException {
85 try {
86 SecureRandom rand = SecureRandom.getInstance("SHA1PRNG", "SUN");
87 KeyGenerator keyGen = KeyGenerator.getInstance(algorithmName, "BC"); // Construct key and cipher for Symmetric Cipher and choosed algorithm
88
89 keyGen.init(symmetricKeyLength);
90 Key key = keyGen.generateKey();
91 Cipher cipher = Cipher.getInstance(algorithmName + "/CBC/PKCS5Padding", "BC");
92
93 cipher.init(Cipher.ENCRYPT_MODE, key, rand);
94 iv = cipher.getIV();
95 symmetricKey = key.getEncoded();
96 encryptedValue = cipher.doFinal(forEncrypt0);
97 } catch (Exception e) {
98 throw SMIMEException.getInstance(this, e, "encryption");
99 }
100 }
101
102 /***
103 * Encryption of the byte array with the given symmetric key
104 * @param forEncrypt0 is byte array for encryption
105 * @param simKey0 symmetric key
106 * @exception SMIMEException if number of bytes in imported symmetric Key is
107 * incorect. Also, can be caused by non SMIMEException which can be one of the following:
108 * NoSuchPaddingException, NoSuchProviderException, NoSuchAlgorithmException,
109 * InvalidKeyException, BadPaddingException, IllegalBlockSizeException.
110 */
111 public void encryption(byte[] forEncrypt0, byte[] simKey0) throws SMIMEException {
112 try {
113 if (simKey0.length != symmetricKeyLength)
114 throw new SMIMEException(this, 1011);
115 SecureRandom rand = SecureRandom.getInstance("SHA1PRNG", "SUN");
116 SecretKeySpec secSpec = new SecretKeySpec(simKey0, algorithmName);
117 Cipher cipher = Cipher.getInstance(algorithmName + "/CBC/PKCS5Padding", "BC");
118
119 cipher.init(Cipher.ENCRYPT_MODE, (SecretKey) secSpec, rand);
120 iv = cipher.getIV();
121 symmetricKey = simKey0;
122 encryptedValue = cipher.doFinal(forEncrypt0);
123 } catch (Exception e) {
124 throw SMIMEException.getInstance(this, e, "encryption");
125 }
126 }
127
128 /***
129 * Returns the algorithm name used for symmetric encryption.
130 * @return Name of the chosen algorithm for symmetric encryption.
131 */
132 public String getAlgorithmName() {
133 return algorithmName;
134 }
135
136 /***
137 * Returns the key size in bits used for chosen algorithm name.
138 * @return Key size in bits for the chosen algorithm for symmetric
139 * encryption.
140 */
141 public int getKeyLength() {
142 return symmetricKeyLength;
143 }
144
145 /***
146 * Returns the initialization vector (IV) used for Symmetric Cipher and
147 * the chosen algorithm.
148 * @return IV as a byte array.
149 */
150 public byte[] getIV() {
151 return iv;
152 }
153
154 /***
155 * Returns the generated symmetric key in bytes.
156 * @return Symmetric key in byte array.
157 */
158 public byte[] getSymmetricKey() {
159 return symmetricKey;
160 }
161
162 /***
163 * Returns the encrypted content.
164 * @return Encrypted content as byte array.
165 */
166 public byte[] getEncryptedValue() {
167 return encryptedValue;
168 }
169
170 /***
171 * Decription of the byte array with the symmetric key and IV previously
172 * generated by the process of encryption in the same session with the same
173 * object. This method is mainly used in testing purposes.
174 * @param forDecrypt previosly encrypted byte array
175 * @exception SMIMEException caused by non SMIMEException which can be one of the following:
176 * NoSuchPaddingException, NoSuchProviderException, NoSuchAlgorithmException,
177 * InvalidKeyException, BadPaddingException, IllegalBlockSizeException.
178 */
179 public void decryption(byte[] forDecrypt) throws SMIMEException {
180 try {
181 SecretKeySpec secSpec = new SecretKeySpec(symmetricKey, algorithmName);
182 Cipher symCipher = Cipher.getInstance(algorithmName + "/CBC/PKCS5Padding", "BC");
183
184 symCipher.init(Cipher.DECRYPT_MODE, (SecretKey) secSpec, new IvParameterSpec(iv));
185 decryptedValue = symCipher.doFinal(forDecrypt);
186 } catch (Exception e) {
187 throw SMIMEException.getInstance(this, e, "decryption");
188 }
189 }
190
191 /***
192 * Decription of the byte array with the given symmetric key and
193 * initialization vector (IV)
194 * @param forDecrypt byte array for encryption
195 * @param simKey0 imported symetric key
196 * @param iv0 imported initialization vector
197 * @exception SMIMEException if number of bytes in imported symmetric key is
198 * incorect, or if number of bytes in imported IV isn't 8. Also, can be caused
199 * by non SMIMEException which can be one of the following:
200 * NoSuchPaddingException, NoSuchProviderException, NoSuchAlgorithmException,
201 * InvalidKeyException, BadPaddingException, IllegalBlockSizeException.
202 */
203 public void decryption(byte[] forDecrypt, byte[] simKey0, byte[] iv0) throws SMIMEException {
204 try {
205 if (simKey0.length * 8 != symmetricKeyLength)
206 throw new SMIMEException(this, 1011);
207 if (iv0.length != 8)
208 throw new SMIMEException(this, 1012);
209 SecretKeySpec secSpec = new SecretKeySpec(simKey0, algorithmName);
210 Cipher symCipher = Cipher.getInstance(algorithmName + "/CBC/PKCS5Padding", "BC");
211
212 symCipher.init(Cipher.DECRYPT_MODE, (SecretKey) secSpec, new IvParameterSpec(iv0));
213 decryptedValue = symCipher.doFinal(forDecrypt);
214 } catch (Exception e) {
215 throw SMIMEException.getInstance(this, e, "decryption");
216 }
217 }
218
219 /***
220 * Returns the decrypted content
221 * @return Decrypted content as a byte array.
222 */
223 public byte[] getDecryptedValue() {
224 return decryptedValue;
225 }
226
227 /***
228 * Resets (sets to null) all private attributes in generated instance of
229 * the class.
230 */
231 public void reset() {
232 iv = null;
233 symmetricKey = null;
234 symmetricKeyLength = 0;
235 String algorithmName = null;
236
237 encryptedValue = null;
238 decryptedValue = null;
239 }
240 }
241
This page was automatically generated by Maven