extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/crypto/CryptoUtil.java

Code
Comments
Other
Rev Date Author Line
5332 20 Mar 19 nicklas 1 package net.sf.basedb.reggie.crypto;
5332 20 Mar 19 nicklas 2
5332 20 Mar 19 nicklas 3 import java.security.GeneralSecurityException;
5332 20 Mar 19 nicklas 4 import java.util.Random;
5332 20 Mar 19 nicklas 5
5332 20 Mar 19 nicklas 6 import javax.crypto.Cipher;
5332 20 Mar 19 nicklas 7 import javax.crypto.SecretKey;
5332 20 Mar 19 nicklas 8 import javax.crypto.SecretKeyFactory;
5332 20 Mar 19 nicklas 9 import javax.crypto.spec.IvParameterSpec;
5332 20 Mar 19 nicklas 10 import javax.crypto.spec.PBEKeySpec;
5332 20 Mar 19 nicklas 11 import javax.crypto.spec.SecretKeySpec;
5332 20 Mar 19 nicklas 12
5332 20 Mar 19 nicklas 13 import net.sf.basedb.core.SessionControl;
5332 20 Mar 19 nicklas 14
5332 20 Mar 19 nicklas 15 /**
5332 20 Mar 19 nicklas 16   Helper class for crypt-related things.
5332 20 Mar 19 nicklas 17   @author nicklas
5332 20 Mar 19 nicklas 18   @since 4.22
5332 20 Mar 19 nicklas 19 */
5332 20 Mar 19 nicklas 20 public class CryptoUtil 
5332 20 Mar 19 nicklas 21 {
5332 20 Mar 19 nicklas 22
5332 20 Mar 19 nicklas 23   /**
5332 20 Mar 19 nicklas 24     Create a cipher that can be used to encrypt or decrypt the given report.
5332 20 Mar 19 nicklas 25     The cipher uses information in the current session (ID and logged in user)
5332 20 Mar 19 nicklas 26     and the given password to create a secret key, which should make it impossible
5332 20 Mar 19 nicklas 27     for other users to get access to the encrypted data. 
5332 20 Mar 19 nicklas 28     
5332 20 Mar 19 nicklas 29     Use this cipher only for temporary data that is supposed to be decrypted (=downloaded)
5332 20 Mar 19 nicklas 30     during the same session. Once the user logs out the session information is lost and it 
5332 20 Mar 19 nicklas 31     will no longer be possible to decrypt the data.
5332 20 Mar 19 nicklas 32     
5332 20 Mar 19 nicklas 33     The mode paramater should be Cipher.ENCRYPT_MODE for encryption and Cipher.DECRYPT_MODE
5332 20 Mar 19 nicklas 34     for decryption.
5332 20 Mar 19 nicklas 35   */
5332 20 Mar 19 nicklas 36   public static Cipher createSessionCipher(SessionControl sc, int mode, String password)
5332 20 Mar 19 nicklas 37     throws GeneralSecurityException
5332 20 Mar 19 nicklas 38   {
5332 20 Mar 19 nicklas 39     // The ID of the current session and report type is used as password
5332 20 Mar 19 nicklas 40     password = sc.getId()+"-"+password;
5332 20 Mar 19 nicklas 41     
5332 20 Mar 19 nicklas 42     // The SALT and IV is used to initialize the cipher
5332 20 Mar 19 nicklas 43     // The should be "random" but deterministic for a given user
5332 20 Mar 19 nicklas 44     // We use the ID of the logged in user.
5332 20 Mar 19 nicklas 45     byte[] salt = new byte[16];
5332 20 Mar 19 nicklas 46     Random random = new Random(sc.getLoggedInUserId()); 
5332 20 Mar 19 nicklas 47     random.nextBytes(salt);
5332 20 Mar 19 nicklas 48   
5332 20 Mar 19 nicklas 49     byte[] iv = new byte[16];
5332 20 Mar 19 nicklas 50     random.nextBytes(iv);
5332 20 Mar 19 nicklas 51     
5332 20 Mar 19 nicklas 52     PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10000, 128);
5332 20 Mar 19 nicklas 53     SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
5332 20 Mar 19 nicklas 54     SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
5332 20 Mar 19 nicklas 55   
5332 20 Mar 19 nicklas 56     Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
5332 20 Mar 19 nicklas 57     aes.init(mode, key, new IvParameterSpec(iv));
5332 20 Mar 19 nicklas 58     return aes;
5332 20 Mar 19 nicklas 59   }
5332 20 Mar 19 nicklas 60 }