From 9e75e06b799e2baeae88a9e4b0e16acf0e292965 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 31 Jan 2014 08:42:39 +0100 Subject: update SessionEncryption to use IAIK JCE and salt for encryption --- .../templates/pvp_postbinding_template.html | 51 ++++++++++++++++++ .../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 ++++++++++++++++------ .../db/dao/session/AuthenticatedSessionStore.java | 19 +++++++ 6 files changed, 192 insertions(+), 50 deletions(-) create mode 100644 id/oa/bin/src/main/resources/templates/pvp_postbinding_template.html create mode 100644 id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/data/EncryptedData.java (limited to 'id') diff --git a/id/oa/bin/src/main/resources/templates/pvp_postbinding_template.html b/id/oa/bin/src/main/resources/templates/pvp_postbinding_template.html new file mode 100644 index 000000000..1215c2b58 --- /dev/null +++ b/id/oa/bin/src/main/resources/templates/pvp_postbinding_template.html @@ -0,0 +1,51 @@ +## +## Velocity Template for SAML 2 HTTP-POST binding +## +## Velocity context may contain the following properties +## action - String - the action URL for the form +## RelayState - String - the relay state for the message +## SAMLRequest - String - the Base64 encoded SAML Request +## SAMLResponse - String - the Base64 encoded SAML Response + + + + + + + +
Your login is being processed. Thank you for waiting.
+ + + +
+
+ #if($RelayState)#end + + #if($SAMLRequest)#end + + #if($SAMLResponse)#end + +
+ +
+ + + \ No newline at end of file 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(); } } diff --git a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java index 64f543973..730a328ab 100644 --- a/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java +++ b/id/server/moa-id-commons/src/main/java/at/gv/egovernment/moa/id/commons/db/dao/session/AuthenticatedSessionStore.java @@ -74,6 +74,9 @@ public class AuthenticatedSessionStore implements Serializable{ @Column(name = "session", nullable=false) @Lob private byte [] session; + @Column(name = "iv", nullable=true) + @Lob private byte [] iv; + @Column(name = "isAuthenticated", nullable=false) private boolean isAuthenticated = false; @@ -205,5 +208,21 @@ public class AuthenticatedSessionStore implements Serializable{ this.pendingRequestID = pendingRequestID; } + /** + * @return the iv + */ + public byte[] getIv() { + return iv; + } + + /** + * @param iv the iv to set + */ + public void setIv(byte[] iv) { + this.iv = iv; + } + + + } -- cgit v1.2.3