Updated client registration (store client secret hashcode).

Change-Id: Ifa14f1439b617be2b1c37c31a8c40298efcc6314
diff --git a/full/Changes b/full/Changes
index 31f8127..b0fd244 100644
--- a/full/Changes
+++ b/full/Changes
@@ -6,6 +6,7 @@
 	- implemented public client deregistration task (margaretha)
 	- added client registration and deregistration tests (margaretha)
 	- implemented confidential client deregistration task (margaretha)
+	- fixed storing client secret (margaretha)
 	
 version 0.60.1
 28/03/2018
diff --git a/full/pom.xml b/full/pom.xml
index 3667b80..5587931 100644
--- a/full/pom.xml
+++ b/full/pom.xml
@@ -156,7 +156,7 @@
 		<dependency>
 			<groupId>de.ids_mannheim.korap</groupId>
 			<artifactId>Kustvakt-core</artifactId>
-			<version>0.60.1</version>
+			<version>0.60.2</version>
 		</dependency>
 		<!-- LDAP -->
 		<dependency>
diff --git a/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java b/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
index f5f04ad..61b158e 100644
--- a/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
+++ b/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
@@ -6,6 +6,8 @@
 import java.util.Properties;
 import java.util.regex.Pattern;
 
+import de.ids_mannheim.korap.interfaces.EncryptionIface;
+
 /** Configuration for Kustvakt full version including properties concerning
  *  authentication and licenses. 
  * 
@@ -42,6 +44,8 @@
     private boolean isSoftDeleteGroup;
     private boolean isSoftDeleteGroupMember;
 
+    private EncryptionIface.Encryption encryption;
+    
     public FullConfiguration (Properties properties) throws IOException {
         super(properties);
     }
@@ -59,6 +63,8 @@
         setMailConfiguration(properties);
         ldapConfig = properties.getProperty("ldap.config");
 
+        setEncryption(Enum.valueOf(EncryptionIface.Encryption.class,
+                properties.getProperty("security.encryption", "BCRYPT")));
     }
 
     private void setMailConfiguration (Properties properties) {
@@ -283,4 +289,12 @@
         this.emailAddressRetrieval = emailAddressRetrieval;
     }
 
+    public EncryptionIface.Encryption getEncryption () {
+        return encryption;
+    }
+
+    public void setEncryption (EncryptionIface.Encryption encryption) {
+        this.encryption = encryption;
+    }
+
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
index 21b3e2a..5ab083f 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
@@ -26,7 +26,7 @@
     @PersistenceContext
     private EntityManager entityManager;
 
-    public void registerClient (String id, String secret, String name,
+    public void registerClient (String id, String secretHashcode, String name,
             OAuth2ClientType type, String url, int urlHashCode,
             String redirectURI, String registeredBy) throws KustvaktException {
         ParameterChecker.checkStringValue(id, "client id");
@@ -39,7 +39,7 @@
         OAuth2Client client = new OAuth2Client();
         client.setId(id);
         client.setName(name);
-        client.setSecret(secret);
+        client.setSecret(secretHashcode);
         client.setType(type);
         client.setUrl(url);
         client.setUrlHashCode(urlHashCode);
diff --git a/full/src/main/java/de/ids_mannheim/korap/encryption/DefaultEncryption.java b/full/src/main/java/de/ids_mannheim/korap/encryption/DefaultEncryption.java
new file mode 100644
index 0000000..0f18f20
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/encryption/DefaultEncryption.java
@@ -0,0 +1,80 @@
+package de.ids_mannheim.korap.encryption;
+
+import de.ids_mannheim.korap.config.ContextHolder;
+import de.ids_mannheim.korap.config.Configurable;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import de.ids_mannheim.korap.user.User;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 05/06/2015
+ */
+@Configurable(ContextHolder.KUSTVAKT_ENCRYPTION)
+public class DefaultEncryption implements EncryptionIface {
+
+    private SecureRandom randomizer;
+
+
+    public DefaultEncryption () {
+        randomizer = new SecureRandom();
+    }
+
+
+    @Override
+    public String secureHash (String input, String salt)
+            throws KustvaktException {
+        return null;
+    }
+
+
+    @Override
+    public String secureHash (String input) throws NoSuchAlgorithmException,
+            UnsupportedEncodingException, KustvaktException {
+        return null;
+    }
+
+
+    @Override
+    public boolean checkHash (String plain, String hash, String salt) {
+        return false;
+    }
+
+
+    @Override
+    public boolean checkHash (String plain, String hash) {
+        return false;
+    }
+
+
+    @Override
+    public String createToken (boolean hash, Object ... obj) {
+        return createToken();
+
+    }
+
+
+    @Override
+    public String createToken () {
+        return new BigInteger(100, randomizer).toString(20);
+    }
+
+
+    @Override
+    public String createRandomNumber (Object ... obj) {
+        return createToken();
+    }
+
+
+    @Override
+    public String encodeBase () {
+        return null;
+    }
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/encryption/KustvaktEncryption.java b/full/src/main/java/de/ids_mannheim/korap/encryption/KustvaktEncryption.java
new file mode 100644
index 0000000..b73a524
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/encryption/KustvaktEncryption.java
@@ -0,0 +1,299 @@
+package de.ids_mannheim.korap.encryption;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import org.apache.commons.codec.EncoderException;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang.RandomStringUtils;
+import org.mindrot.jbcrypt.BCrypt;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.ids_mannheim.korap.config.FullConfiguration;
+import de.ids_mannheim.korap.interfaces.EncryptionIface;
+
+public class KustvaktEncryption implements EncryptionIface {
+
+    private static final String ALGORITHM = "SHA-256";
+    private static Logger jlog = LoggerFactory
+            .getLogger(KustvaktEncryption.class);
+
+    private final FullConfiguration config;
+
+
+    public KustvaktEncryption (FullConfiguration config) {
+        jlog.info("initializing KorAPEncryption implementation");
+        this.config = config;
+    }
+
+
+    public static boolean matchTokenByteCode (Object param) {
+        if (!(param instanceof String))
+            return false;
+        String token = (String) param;
+        byte[] bytes = token.getBytes();
+        return 64 == bytes.length;
+    }
+
+
+    private String encodeBase (byte[] bytes) throws EncoderException {
+        return Base64.encodeBase64String(bytes);
+    }
+
+
+    @Override
+    public String encodeBase () {
+        try {
+            return encodeBase(this.createSecureRandom(24));
+        }
+        catch (EncoderException e) {
+            return "";
+        }
+    }
+
+
+    public String secureHash (String input) {
+        return secureHash(input, "");
+    }
+
+
+    @Override
+    public String secureHash (String input, String salt) {
+        String hashString = "";
+        switch (config.getEncryption()) {
+            case ESAPICYPHER:
+                break;
+            case SIMPLE:
+                try {
+                    MessageDigest md = MessageDigest.getInstance("SHA-256");
+                    md.update(input.getBytes("UTF-8"));
+                    byte[] digest = md.digest();
+
+                    for (byte b : digest)
+                        hashString += String.format("%02x", b);
+                }
+                catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
+                    e.printStackTrace();
+                }
+                break;
+            case BCRYPT:
+                hashString = bcryptHash(input, salt);
+                break;
+            default:
+                jlog.warn("Invalid value: {}", config.getEncryption());
+                break;
+        }
+        return hashString;
+    }
+
+
+
+    public String hash (String input) {
+        String hashString = "";
+        MessageDigest md;
+        try {
+            md = MessageDigest.getInstance(ALGORITHM);
+            md.update(input.getBytes("UTF-8"));
+        }
+        catch (NoSuchAlgorithmException e) {
+            return "";
+        }
+        catch (UnsupportedEncodingException e) {
+            return "";
+        }
+
+        byte[] digest = md.digest();
+
+        for (byte b : digest) {
+            hashString += String.format("%02x", b);
+        }
+        return hashString;
+    }
+
+
+    /**
+     * // some sort of algorithm to create token and isSystem
+     * regularly the integrity
+     * // of the token
+     * public String createAuthToken() {
+     * final byte[] rNumber = SecureRGenerator
+     * .getNextSecureRandom(SecureRGenerator.TOKEN_RANDOM_SIZE);
+     * String hash;
+     * try {
+     * hash = produceSimpleHash(SecureRGenerator.toHex(rNumber));
+     * } catch (NoSuchAlgorithmException |
+     * UnsupportedEncodingException e) {
+     * return "";
+     * }
+     * return hash;
+     * }
+     */
+
+    private byte[] createSecureRandom (int size) {
+        return SecureRGenerator.getNextSecureRandom(size);
+    }
+
+
+    /**
+     * does this need to be equal for every iteration?!
+     * @param hash
+     * @param obj
+     * @return
+     */
+    @Override
+    public String createToken (boolean hash, Object ... obj) {
+        StringBuffer b = new StringBuffer();
+        try {
+            for (Object o : obj) {
+                b.append(" | ");
+                b.append(o);
+            }
+            if (hash)
+                return encodeBase(hash(b.toString().trim()).getBytes());
+            else
+                return encodeBase(b.toString().trim().getBytes());
+        }
+        catch (EncoderException e) {
+            return "";
+        }
+
+    }
+
+
+    @Override
+    public String createToken () {
+        return RandomStringUtils.randomAlphanumeric(64);
+        
+        // EM: code from MH
+//        String encoded;
+//        String v = RandomStringUtils.randomAlphanumeric(64);
+//        encoded = hash(v);
+//        jlog.trace("creating new token {}", encoded);
+//        return encoded;
+    }
+
+
+    @Override
+    public String createRandomNumber (Object ... obj) {
+        final byte[] rNumber = SecureRGenerator
+                .getNextSecureRandom(SecureRGenerator.CORPUS_RANDOM_SIZE);
+        if (obj.length == 0) {
+            obj = new Object[1];
+            obj[0] = rNumber;
+        }
+        return createToken(false, obj);
+    }
+
+
+    @Override
+    public boolean checkHash (String plain, String hash, String salt) {
+        String pw = "";
+        switch (config.getEncryption()) {
+            case ESAPICYPHER:
+                pw = secureHash(plain, salt);
+                break;
+            case BCRYPT:
+                try {
+                    return BCrypt.checkpw(plain, hash);
+                }
+                catch (IllegalArgumentException e) {
+                    return false;
+                }
+            case SIMPLE:
+                pw = hash(plain);
+                break;
+        }
+        return pw.equals(hash);
+    }
+
+
+    @Override
+    public boolean checkHash (String plain, String hash) {
+        switch (config.getEncryption()) {
+            case ESAPICYPHER:
+                return secureHash(plain).equals(hash);
+            case BCRYPT:
+                try {
+                    return BCrypt.checkpw(plain, hash);
+                }
+                catch (IllegalArgumentException e) {
+                    return false;
+                }
+            case SIMPLE:
+                return hash(plain).equals(hash);
+        }
+        return false;
+    }
+
+
+    private String bcryptHash (String text, String salt) {
+        if (salt == null || salt.isEmpty())
+            salt = BCrypt.gensalt(config.getLoadFactor());
+        return BCrypt.hashpw(text, salt);
+    }
+
+
+    @Override
+    public String toString () {
+        return this.getClass().getCanonicalName();
+    }
+
+    public static class SecureRGenerator {
+        private static final String SHA1_PRNG = "SHA1PRNG";
+        protected static final int DEFAULT_RANDOM_SIZE = 128;
+        protected static final int TOKEN_RANDOM_SIZE = 128;
+        protected static final int USERID_RANDOM_SIZE = 64;
+        protected static final int CORPUS_RANDOM_SIZE = 48;
+        private static final char[] HEX_DIGIT = { '0', '1', '2', '3', '4', '5',
+                '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'z', 'x',
+                'h', 'q', 'w' };
+        private static final SecureRandom sRandom__;
+
+        static {
+            try {
+                sRandom__ = SecureRandom.getInstance("SHA1PRNG");
+            }
+            catch (NoSuchAlgorithmException e) {
+                throw new Error(e);
+            }
+        }
+
+
+        public static byte[] getNextSecureRandom (int bits) {
+            if (bits % 8 != 0) {
+                throw new IllegalArgumentException(
+                        "Size is not divisible by 8!");
+            }
+
+            byte[] bytes = new byte[bits / 8];
+
+            sRandom__.nextBytes(bytes);
+
+            return bytes;
+        }
+
+
+        public static String toHex (byte[] bytes) {
+            if (bytes == null) {
+                return null;
+            }
+
+            StringBuilder buffer = new StringBuilder(bytes.length * 2);
+            for (byte thisByte : bytes) {
+                buffer.append(byteToHex(thisByte));
+            }
+
+            return buffer.toString();
+        }
+
+
+        private static String byteToHex (byte b) {
+            char[] array = { HEX_DIGIT[(b >> 4 & 0xF)], HEX_DIGIT[(b & 0xF)] };
+            return new String(array);
+        }
+    }
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java b/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
index c6d179f..35b6dce 100644
--- a/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
@@ -24,6 +24,7 @@
     @Id
     private String id;
     private String name;
+    // Secret hashcode is stored instead of plain secret
     private String secret;
     @Enumerated(EnumType.STRING)
     private OAuth2ClientType type;
diff --git a/full/src/main/java/de/ids_mannheim/korap/interfaces/EncryptionIface.java b/full/src/main/java/de/ids_mannheim/korap/interfaces/EncryptionIface.java
new file mode 100644
index 0000000..134ebdb
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/interfaces/EncryptionIface.java
@@ -0,0 +1,76 @@
+package de.ids_mannheim.korap.interfaces;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.user.User;
+
+import java.io.UnsupportedEncodingException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Map;
+
+public interface EncryptionIface {
+
+    public enum Encryption {
+                @Deprecated
+        SIMPLE, ESAPICYPHER, BCRYPT
+    }
+
+
+    /**
+     * One-way hashing of String input. Used to canonicalize
+     * 
+     * @param input
+     * @param salt
+     * @return
+     */
+    public String secureHash (String input, String salt)
+            throws KustvaktException;
+
+
+    public String secureHash (String input) throws NoSuchAlgorithmException,
+            UnsupportedEncodingException, KustvaktException;
+
+
+    /**
+     * @param plain
+     * @param hash
+     * @param salt
+     * @return
+     */
+    public boolean checkHash (String plain, String hash, String salt);
+
+
+    public boolean checkHash (String plain, String hash);
+
+
+    /**
+     * create random String to be used as authentication token
+     * 
+     * @return
+     */
+    public String createToken (boolean hash, Object ... obj);
+
+
+    public String createToken ();
+
+
+    /**
+     * create a random Integer to be used as ID for databases
+     * 
+     * @return
+     */
+    public String createRandomNumber (Object ... obj);
+
+
+    public String encodeBase ();
+
+
+   // @Deprecated
+    //public Map<String, Object> validateMap (Map<String, Object> map)
+    //        throws KustvaktException;
+
+
+    //@Deprecated
+    //public String validateEntry (String input, String type)
+    //        throws KustvaktException;
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
index c6c732b..fe27503 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
@@ -9,6 +9,7 @@
 
 import de.ids_mannheim.korap.authentication.http.AuthorizationData;
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
+import de.ids_mannheim.korap.config.FullConfiguration;
 import de.ids_mannheim.korap.constant.AuthenticationScheme;
 import de.ids_mannheim.korap.constant.OAuth2ClientType;
 import de.ids_mannheim.korap.dao.AdminDao;
@@ -34,6 +35,8 @@
     private EncryptionIface encryption;
     @Autowired
     private HttpAuthorizationHandler authorizationHandler;
+    @Autowired
+    private FullConfiguration config;
 
 
     public OAuth2ClientDto registerClient (OAuth2ClientJson clientJson,
@@ -49,6 +52,7 @@
         }
 
         String secret = null;
+        String secretHashcode = null;
         if (clientJson.getType().equals(OAuth2ClientType.CONFIDENTIAL)) {
             // RFC 6749:
             // The authorization server MUST NOT issue client passwords or other
@@ -61,11 +65,13 @@
             // specific device.
 
             secret = encryption.createToken();
+            secretHashcode = encryption.secureHash(secret,
+                    config.getPasscodeSaltField());
         }
 
         String id = encryption.createRandomNumber();
         try {
-            clientDao.registerClient(id, secret, clientJson.getName(),
+            clientDao.registerClient(id, secretHashcode, clientJson.getName(),
                     clientJson.getType(), clientJson.getUrl(),
                     clientJson.getUrl().hashCode(), clientJson.getRedirectURI(),
                     registeredBy);
@@ -162,7 +168,9 @@
                     .equals(AuthenticationScheme.BASIC)) {
                 authorizationHandler.parseBasicToken(authData);
                 if (!client.getId().equals(clientId)
-                        || !client.getSecret().equals(authData.getPassword())) {
+                        || !encryption.checkHash(authData.getPassword(),
+                                client.getSecret(),
+                                config.getPasscodeSaltField())) {
                     throw new KustvaktException(
                             StatusCodes.AUTHENTICATION_FAILED,
                             "Client credentials are incorrect.");
diff --git a/full/src/main/resources/default-config.xml b/full/src/main/resources/default-config.xml
index b3bf566..76917d4 100644
--- a/full/src/main/resources/default-config.xml
+++ b/full/src/main/resources/default-config.xml
@@ -196,7 +196,7 @@
 	</bean>
 
 	<bean name="kustvakt_encryption"
-		class="de.ids_mannheim.korap.interfaces.defaults.KustvaktEncryption">
+		class="de.ids_mannheim.korap.encryption.KustvaktEncryption">
 		<constructor-arg ref="kustvakt_config" />
 	</bean>
 
diff --git a/full/src/test/java/de/ids_mannheim/korap/config/ConfigTest.java b/full/src/test/java/de/ids_mannheim/korap/config/ConfigTest.java
index 8fd00ef..ac3a131 100644
--- a/full/src/test/java/de/ids_mannheim/korap/config/ConfigTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/config/ConfigTest.java
@@ -3,17 +3,12 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.security.NoSuchAlgorithmException;
 import java.util.Map;
 import java.util.Properties;
 
-import org.codehaus.plexus.util.IOUtil;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -43,22 +38,6 @@
         assertNotNull(p);
     }
 
-
-    @Test
-    public void testAdminHash () throws IOException, KustvaktException,
-            NoSuchAlgorithmException {
-        AdminSetup setup = AdminSetup.getInstance();
-        String hash = setup.getHash();
-        File f = new File("./admin_token");
-        FileInputStream stream = new FileInputStream(f);
-        String token = IOUtil.toString(stream);
-        assertNotEquals("", hash);
-        assertNotEquals("", token);
-        EncryptionIface crypto = helper().getContext().getEncryption();
-        assertTrue(crypto.checkHash(token, hash));
-    }
-
-
     @Test
     public void testServiceInfo () {
         String version = ServiceInfo.getInfo().getVersion();
@@ -89,16 +68,6 @@
     }
 
     @Test
-    @Ignore
-    public void testKustvaktValueValidation() {
-        Map m = KustvaktConfiguration.KUSTVAKT_USER;
-        EncryptionIface crypto = helper().getContext().getEncryption();
-
-
-    }
-
-
-    @Test
     public void testBootConfigDependencyOrder () {
         // todo:
 
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/OAuth2HandlerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/OAuth2HandlerTest.java
index a8742fa..24d468f 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/OAuth2HandlerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/OAuth2HandlerTest.java
@@ -11,6 +11,7 @@
 import de.ids_mannheim.korap.config.BeanConfigTest;
 import de.ids_mannheim.korap.config.ClientInfo;
 import de.ids_mannheim.korap.config.ContextHolder;
+import de.ids_mannheim.korap.encryption.KustvaktEncryption;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.handlers.OAuth2Handler;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
@@ -23,6 +24,7 @@
  * @date 13/05/2015
  */
 @Ignore
+@Deprecated
 public class OAuth2HandlerTest extends BeanConfigTest {
 
     private static ClientInfo info;
@@ -33,14 +35,20 @@
     @Test
     public void testStoreAuthorizationCodeThrowsNoException ()
             throws KustvaktException {
-        String auth_code = helper().getContext().getEncryption().createToken();
-        AuthCodeInfo codeInfo = new AuthCodeInfo(info.getClient_id(), auth_code);
+        
+        EncryptionIface crypto = new KustvaktEncryption(
+                helper().getContext().getConfiguration());
+        
+        String auth_code = crypto.createToken();
+        AuthCodeInfo codeInfo =
+                new AuthCodeInfo(info.getClient_id(), auth_code);
         codeInfo.setScopes(SCOPES);
 
-        OAuth2Handler handler = new OAuth2Handler(helper().getContext()
-                .getPersistenceClient());
+        OAuth2Handler handler =
+                new OAuth2Handler(helper().getContext().getPersistenceClient());
         handler.authorize(codeInfo, helper().getUser());
-        assertTrue("couldn't find entry in cache", handler.hasCacheEntry(codeInfo.getCode()));
+        assertTrue("couldn't find entry in cache",
+                handler.hasCacheEntry(codeInfo.getCode()));
         codeInfo = handler.getAuthorization(auth_code);
         assertNotNull("client is null!", codeInfo);
     }
@@ -49,15 +57,19 @@
     @Test
     public void testAuthorizationCodeRemoveThrowsNoException ()
             throws KustvaktException {
-        String auth_code = helper().getContext().getEncryption().createToken();
-        AuthCodeInfo codeInfo = new AuthCodeInfo(info.getClient_id(), auth_code);
+        EncryptionIface crypto = new KustvaktEncryption(
+                helper().getContext().getConfiguration());
+        
+        String auth_code = crypto.createToken();
+        AuthCodeInfo codeInfo =
+                new AuthCodeInfo(info.getClient_id(), auth_code);
         codeInfo.setScopes(SCOPES);
 
-        OAuth2Handler handler = new OAuth2Handler(helper().getContext()
-                .getPersistenceClient());
+        OAuth2Handler handler =
+                new OAuth2Handler(helper().getContext().getPersistenceClient());
         handler.authorize(codeInfo, helper().getUser());
-        String t = helper().getContext().getEncryption().createToken();
-        String refresh = helper().getContext().getEncryption().createToken();
+        String t = crypto.createToken();
+        String refresh = crypto.createToken();
         handler.addToken(codeInfo.getCode(), t, refresh, 7200);
 
         TokenContext ctx = handler.getPersistenceHandler().getContext(t);
@@ -76,8 +88,11 @@
 
     @Test
     public void testStoreAccessCodeViaAuthCodeThrowsNoException () {
-        String auth_code = helper().getContext().getEncryption().createToken();
-        AuthCodeInfo codeInfo = new AuthCodeInfo(info.getClient_id(), auth_code);
+        String auth_code =
+                new KustvaktEncryption(helper().getContext().getConfiguration())
+                        .createToken();
+        AuthCodeInfo codeInfo =
+                new AuthCodeInfo(info.getClient_id(), auth_code);
         codeInfo.setScopes(SCOPES);
 
     }
@@ -112,14 +127,17 @@
     public void initMethod () throws KustvaktException {
         helper().setupAccount();
 
-        EncryptionIface crypto = helper().getContext().getEncryption();
-        info = new ClientInfo(crypto.createRandomNumber(), crypto.createToken());
+        EncryptionIface crypto = new KustvaktEncryption(
+                helper().getContext().getConfiguration());
+        info = new ClientInfo(crypto.createRandomNumber(),
+                crypto.createToken());
         info.setConfidential(true);
         //todo: support for subdomains?!
         info.setUrl("http://localhost:8080/api/v0.1");
         info.setRedirect_uri("testwebsite/login");
         PersistenceClient cl = helper().getBean(ContextHolder.KUSTVAKT_DB);
         OAuth2Handler handler = new OAuth2Handler(cl);
-        handler.getPersistenceHandler().registerClient(info, helper().getUser());
+        handler.getPersistenceHandler().registerClient(info,
+                helper().getUser());
     }
 }
diff --git a/full/src/test/resources/test-config.xml b/full/src/test/resources/test-config.xml
index ffd8c9e..562c3bb 100644
--- a/full/src/test/resources/test-config.xml
+++ b/full/src/test/resources/test-config.xml
@@ -195,7 +195,7 @@
 	</bean>
 
 	<bean name="kustvakt_encryption"
-		class="de.ids_mannheim.korap.interfaces.defaults.KustvaktEncryption">
+		class="de.ids_mannheim.korap.encryption.KustvaktEncryption">
 		<constructor-arg ref="kustvakt_config" />
 	</bean>