From 9e75e06b799e2baeae88a9e4b0e16acf0e292965 Mon Sep 17 00:00:00 2001
From: Thomas Lenz <tlenz@iaik.tugraz.at>
Date: Fri, 31 Jan 2014 08:42:39 +0100
Subject: update SessionEncryption to use IAIK JCE and salt for encryption

---
 .../gv/egovernment/moa/id/data/EncryptedData.java  | 58 ++++++++++++++++++++
 .../moa/id/moduls/AuthenticationManager.java       | 29 +---------
 .../id/storage/AuthenticationSessionStoreage.java  | 23 +++++---
 .../moa/id/util/SessionEncrytionUtil.java          | 62 ++++++++++++++++------
 4 files changed, 122 insertions(+), 50 deletions(-)
 create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/EncryptedData.java

(limited to 'id/server/idserverlib/src/main/java')

diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/EncryptedData.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/EncryptedData.java
new file mode 100644
index 000000000..e0484eb1b
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/EncryptedData.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.data;
+
+/**
+ * @author tlenz
+ *
+ */
+public class EncryptedData {
+
+	private byte[] encData = null;
+	private byte[] iv = null;
+	
+	
+	/**
+	 * 
+	 */
+	public EncryptedData(byte[] encdata, byte[] iv) {
+		this.encData = encdata;
+		this.iv = iv;
+		
+	}
+	
+	/**
+	 * @return the encData
+	 */
+	public byte[] getEncData() {
+		return encData;
+	}
+	/**
+	 * @return the iv
+	 */
+	public byte[] getIv() {
+		return iv;
+	}
+	
+	
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java
index 655c507be..90863890f 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java
@@ -271,32 +271,5 @@ public class AuthenticationManager extends AuthServlet {
 			PrintWriter out = new PrintWriter(response.getOutputStream()); 
 			out.print(form);
 			out.flush(); 
-	}
-	
-	
-//	private AuthenticationSession getORCreateMOASession(HttpServletRequest request) throws MOAIDException {
-//		
-//		//String sessionID = request.getParameter(PARAM_SESSIONID); 
-//		String sessionID = (String) request.getSession().getAttribute(MOA_SESSION);
-//		AuthenticationSession moasession;
-//		
-//		try {
-//			moasession = AuthenticationSessionStoreage.getSession(sessionID);
-//			Logger.info("Found existing MOASession with sessionID=" + sessionID 
-//					+ ". This session is used for reauthentification.");
-//			
-//		} catch (MOADatabaseException e) {
-//			try {
-//				moasession = AuthenticationSessionStoreage.createSession();
-//				Logger.info("Create a new MOASession with sessionID=" + moasession.getSessionID() + ".");
-//				
-//			} catch (MOADatabaseException e1) {
-//				Logger.error("Database Error! MOASession are not created.");
-//				throw new MOAIDException("init.04", new Object[] {
-//						"0"});
-//			}
-//		}
-//		
-//		return moasession;
-//	}	
+	}	
 }
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java
index b00df8a86..393b80d04 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java
@@ -39,6 +39,7 @@ import at.gv.egovernment.moa.id.commons.db.dao.session.AuthenticatedSessionStore
 import at.gv.egovernment.moa.id.commons.db.dao.session.OASessionStore;
 import at.gv.egovernment.moa.id.commons.db.dao.session.OldSSOSessionIDStore;
 import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.data.EncryptedData;
 import at.gv.egovernment.moa.id.util.Random;
 import at.gv.egovernment.moa.id.util.SessionEncrytionUtil;
 import at.gv.egovernment.moa.logging.Logger;
@@ -110,7 +111,9 @@ public class AuthenticationSessionStoreage {
 			dbsession.setAuthenticated(session.isAuthenticated());
 			byte[] serialized = SerializationUtils.serialize(session);
 			
-			dbsession.setSession(SessionEncrytionUtil.encrypt(serialized));
+			EncryptedData encdata = SessionEncrytionUtil.encrypt(serialized);
+			dbsession.setSession(encdata.getEncData());
+			dbsession.setIv(encdata.getIv());
 			
 			//set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1
 			dbsession.setUpdated(new Date());
@@ -133,7 +136,9 @@ public class AuthenticationSessionStoreage {
 			dbsession.setAuthenticated(session.isAuthenticated());
 			byte[] serialized = SerializationUtils.serialize(session);
 			
-			dbsession.setSession(SessionEncrytionUtil.encrypt(serialized));
+			EncryptedData encdata = SessionEncrytionUtil.encrypt(serialized);
+			dbsession.setSession(encdata.getEncData());
+			dbsession.setIv(encdata.getIv());
 			
 			//set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1
 			dbsession.setUpdated(new Date());
@@ -193,7 +198,9 @@ public class AuthenticationSessionStoreage {
 			
 			byte[] serialized = SerializationUtils.serialize(session);
 			
-			dbsession.setSession(SessionEncrytionUtil.encrypt(serialized));
+			EncryptedData encdata = SessionEncrytionUtil.encrypt(serialized);
+			dbsession.setSession(encdata.getEncData());
+			dbsession.setIv(encdata.getIv());
 			
 			//set Timestamp in this state, because automated timestamp generation is buggy in Hibernate 4.2.1
 			dbsession.setUpdated(new Date());
@@ -291,7 +298,9 @@ public class AuthenticationSessionStoreage {
 			AuthenticatedSessionStore dbsession = searchInDatabase(sessionID);
 			
 			//decrypt Session
-			byte[] decrypted = SessionEncrytionUtil.decrypt(dbsession.getSession());
+			EncryptedData encdata = new EncryptedData(dbsession.getSession(),
+					dbsession.getIv());
+			byte[] decrypted = SessionEncrytionUtil.decrypt(encdata);
 					
 			AuthenticationSession session = (AuthenticationSession) SerializationUtils.deserialize(decrypted);
 
@@ -454,9 +463,11 @@ public class AuthenticationSessionStoreage {
 			  }
 			
 			//decrypt Session
-			byte[] decrypted = SessionEncrytionUtil.decrypt(result.get(0).getSession());
-					
+			EncryptedData encdata = new EncryptedData(result.get(0).getSession(),
+						result.get(0).getIv());
+			byte[] decrypted = SessionEncrytionUtil.decrypt(encdata);			  					
 			return (AuthenticationSession) SerializationUtils.deserialize(decrypted);
+			
 								
 		} catch (Throwable e) {
 			Logger.warn("MOASession deserialization-exception by using MOASessionID=" + pedingRequestID);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SessionEncrytionUtil.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SessionEncrytionUtil.java
index 4b7e46ce7..acc2a7273 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SessionEncrytionUtil.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/util/SessionEncrytionUtil.java
@@ -22,34 +22,58 @@
  *******************************************************************************/
 package at.gv.egovernment.moa.id.util;
 
+import iaik.security.cipher.PBEKey;
+import iaik.security.spec.PBEKeyAndParameterSpec;
+
+import java.security.SecureRandom;
 import java.security.spec.KeySpec;
 
 import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.spec.SecretKeySpec;
 
 import at.gv.egovernment.moa.id.auth.exception.BuildException;
 import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
+import at.gv.egovernment.moa.id.data.EncryptedData;
 import at.gv.egovernment.moa.logging.Logger;
 
 public class SessionEncrytionUtil {
 
-	static SecretKey secret = null;
-
+	private static final String CIPHER_MODE = "AES/CBC/PKCS5Padding";
+	private static final String KEYNAME = "AES";
+	
+	static private SecretKey secret = null;
+	
 	static {
 		try {
 			String key = AuthConfigurationProvider.getInstance().getMOASessionEncryptionKey();
 			
 			if (key != null) {
-				SecretKeyFactory factory;
 
-					factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
-					KeySpec spec = new PBEKeySpec(key.toCharArray(), "TestSALT".getBytes(), 1024, 128);
-					SecretKey tmp = factory.generateSecret(spec);
-					secret = new SecretKeySpec(tmp.getEncoded(), "AES");
+					PBEKeySpec keySpec = new PBEKeySpec(key.toCharArray());
+					SecretKeyFactory factory = SecretKeyFactory.getInstance("PKCS#5", "IAIK");
+					PBEKey pbeKey = (PBEKey)factory.generateSecret(keySpec);
+					
 					
+					SecureRandom random = new SecureRandom();
+					KeyGenerator pbkdf2 = KeyGenerator.getInstance("PBKDF2", "IAIK");
+					
+					PBEKeyAndParameterSpec parameterSpec =
+							   new PBEKeyAndParameterSpec(pbeKey.getEncoded(),
+									   					  "TestSALT".getBytes(),
+							                              2000,
+							                              16);
+						
+					pbkdf2.init(parameterSpec, random);
+					SecretKey derivedKey = pbkdf2.generateKey();
+					
+					SecretKeySpec spec = new SecretKeySpec(derivedKey.getEncoded(), KEYNAME);
+					SecretKeyFactory kf = SecretKeyFactory.getInstance(KEYNAME, "IAIK");
+					secret = kf.generateSecret(spec);
 					
 			} else {
 				Logger.warn("MOASession encryption is deaktivated.");
@@ -61,41 +85,47 @@ public class SessionEncrytionUtil {
 		
 	}
 	
-	public static byte[] encrypt(byte[] data) throws BuildException {
+	public static EncryptedData encrypt(byte[] data) throws BuildException {
 		Cipher cipher;
 		
 		if (secret != null) {
 			try {
-				cipher = Cipher.getInstance("AES/ECB/"+"ISO10126Padding");
+				cipher = Cipher.getInstance(CIPHER_MODE, "IAIK");
 			    cipher.init(Cipher.ENCRYPT_MODE, secret);
 				
 			    Logger.debug("Encrypt MOASession");
-			    return cipher.doFinal(data);
+			    
+			    byte[] encdata = cipher.doFinal(data);
+			    byte[] iv = cipher.getIV();
+			    
+			    return new EncryptedData(encdata, iv);
 			    
 			} catch (Exception e) {
 				Logger.warn("MOASession is not encrypted",e);
 				throw new BuildException("MOASession is not encrypted", new Object[]{}, e);
 			}
 		} else
-			return data;
+			return new EncryptedData(data, null);
 	}
 	
-	public static byte[] decrypt(byte[] data) throws BuildException {
+	public static byte[] decrypt(EncryptedData data) throws BuildException {
 		Cipher cipher;
 		
 		if (secret != null) {
 			try {
-				cipher = Cipher.getInstance("AES/ECB/"+"ISO10126Padding");
-			    cipher.init(Cipher.DECRYPT_MODE, secret);
+				IvParameterSpec iv = new IvParameterSpec(data.getIv());
+				
+				cipher = Cipher.getInstance(CIPHER_MODE, "IAIK");
+			    cipher.init(Cipher.DECRYPT_MODE, secret, iv);
 				
 			    Logger.debug("Decrypt MOASession");
-			    return cipher.doFinal(data);
+			    return cipher.doFinal(data.getEncData());
 			    
 			} catch (Exception e) {
 				Logger.warn("MOASession is not decrypted",e);
 				throw new BuildException("MOASession is not decrypted", new Object[]{}, e);
 			}
 		} else
-		return data;
+		return data.getEncData();
 	}
 }
-- 
cgit v1.2.3