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

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