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