You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2018/07/09 19:21:37 UTC
wicket git commit: WICKET-6563 enhance encryption
Repository: wicket
Updated Branches:
refs/heads/WICKET-6563 fd7b26bac -> ee21d9974
WICKET-6563 enhance encryption
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/ee21d997
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/ee21d997
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/ee21d997
Branch: refs/heads/WICKET-6563
Commit: ee21d99744ceeb2dadfd61bc44483eca77c7abf1
Parents: fd7b26b
Author: Sven Meier <sv...@apache.org>
Authored: Mon Jul 9 21:17:00 2018 +0200
Committer: Sven Meier <sv...@apache.org>
Committed: Mon Jul 9 21:17:09 2018 +0200
----------------------------------------------------------------------
.../wicket/DefaultPageManagerProvider.java | 6 +-
.../wicket/pageStore/CryptingPageStore.java | 103 +++---------------
.../wicket/pageStore/InSessionPageStore.java | 2 +-
.../wicket/pageStore/crypt/DefaultCrypter.java | 108 +++++++++++++++++++
.../apache/wicket/pageStore/crypt/ICrypter.java | 28 +++++
.../apache/wicket/settings/StoreSettings.java | 31 +++---
6 files changed, 176 insertions(+), 102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/ee21d997/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java b/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
index c453be9..1f120f1 100644
--- a/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
+++ b/wicket-core/src/main/java/org/apache/wicket/DefaultPageManagerProvider.java
@@ -166,6 +166,10 @@ public class DefaultPageManagerProvider implements IPageManagerProvider
Bytes maxSizePerSession = storeSettings.getMaxSizePerSession();
File fileStoreFolder = storeSettings.getFileStoreFolder();
- return new DiskPageStore(application.getName(), fileStoreFolder, maxSizePerSession, getSerializer());
+ if (storeSettings.isEncrypted()) {
+ return new SerializingPageStore(new CryptingPageStore(new DiskPageStore(application.getName(), fileStoreFolder, maxSizePerSession)), getSerializer());
+ } else {
+ return new DiskPageStore(application.getName(), fileStoreFolder, maxSizePerSession, getSerializer());
+ }
}
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/ee21d997/wicket-core/src/main/java/org/apache/wicket/pageStore/CryptingPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/CryptingPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/CryptingPageStore.java
index e1014d8..c294d5c 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/CryptingPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/CryptingPageStore.java
@@ -17,18 +17,12 @@
package org.apache.wicket.pageStore;
import java.io.Serializable;
-import java.security.GeneralSecurityException;
-import java.util.UUID;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.PBEKeySpec;
-import javax.crypto.spec.PBEParameterSpec;
import org.apache.wicket.MetaDataKey;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.page.IManageablePage;
+import org.apache.wicket.pageStore.crypt.DefaultCrypter;
+import org.apache.wicket.pageStore.crypt.ICrypter;
import org.apache.wicket.serialize.ISerializer;
/**
@@ -44,13 +38,6 @@ import org.apache.wicket.serialize.ISerializer;
*/
public class CryptingPageStore extends DelegatingPageStore
{
- public static final String DEFAULT_CRYPT_METHOD = "PBEWithMD5AndDES";
-
- private final static byte[] DEFAULT_SALT = { (byte)0x15, (byte)0x8c, (byte)0xa3, (byte)0x4a,
- (byte)0x66, (byte)0x51, (byte)0x2a, (byte)0xbc };
-
- private final static int DEFAULT_ITERATION_COUNT = 17;
-
private static final MetaDataKey<SessionData> KEY = new MetaDataKey<SessionData>()
{
};
@@ -86,53 +73,16 @@ public class CryptingPageStore extends DelegatingPageStore
{
context.bind();
- data = context.setSessionData(KEY, new SessionData(createCipherKey(context)));
+ data = context.setSessionData(KEY, new SessionData(newCrypter(context)));
}
return data;
}
/**
- * Create a cipher key for the given context.
- *
- * @param context
- * context
- * @return random UUID by default
+ * Create a new {@link ICrypter} for the given context.
*/
- protected String createCipherKey(IPageContext context)
- {
- return UUID.randomUUID().toString();
- }
-
- /**
- * Create a secret key.
- *
- * @param cipherKey
- * cipher key
- * @return secret key
- * @throws GeneralSecurityException
- */
- protected SecretKey createSecretKey(String cipherKey) throws GeneralSecurityException
- {
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DEFAULT_CRYPT_METHOD);
-
- return keyFactory.generateSecret(new PBEKeySpec(cipherKey.toCharArray()));
- }
-
- /**
- * Create a cipher
- *
- * @param mode
- * mode
- * @param secret
- * secret
- * @return cipher
- * @throws GeneralSecurityException
- */
- protected Cipher createCipher(int mode, SecretKey secret) throws GeneralSecurityException
- {
- Cipher cipher = Cipher.getInstance(DEFAULT_CRYPT_METHOD);
- cipher.init(mode, secret, new PBEParameterSpec(DEFAULT_SALT, DEFAULT_ITERATION_COUNT));
- return cipher;
+ protected ICrypter newCrypter(IPageContext context) {
+ return new DefaultCrypter();
}
@Override
@@ -149,7 +99,7 @@ public class CryptingPageStore extends DelegatingPageStore
SerializedPage serializedPage = (SerializedPage)page;
byte[] encrypted = serializedPage.getData();
- byte[] decrypted = getSessionData(context).crypt(this, encrypted, Cipher.DECRYPT_MODE);
+ byte[] decrypted = getSessionData(context).decrypt(encrypted);
page = new SerializedPage(page.getPageId(), serializedPage.getPageType(), decrypted);
}
@@ -168,7 +118,7 @@ public class CryptingPageStore extends DelegatingPageStore
SerializedPage serializedPage = (SerializedPage)page;
byte[] decrypted = serializedPage.getData();
- byte[] encrypted = getSessionData(context).crypt(this, decrypted, Cipher.ENCRYPT_MODE);
+ byte[] encrypted = getSessionData(context).encrypt(decrypted);
page = new SerializedPage(page.getPageId(), serializedPage.getPageType(), encrypted);
@@ -178,44 +128,21 @@ public class CryptingPageStore extends DelegatingPageStore
private static class SessionData implements Serializable
{
- private final String cipherKey;
-
- private transient SecretKey secretKey;
+ private ICrypter cypter;
- public SessionData(String cipherKey)
+ public SessionData(ICrypter crypter)
{
- this.cipherKey = cipherKey;
+ this.cypter= crypter;
}
- protected Cipher createCipher(CryptingPageStore store, int mode) throws GeneralSecurityException
+ public byte[] encrypt(byte[] decrypted)
{
- SecretKey secret = getSecretKey(store);
-
- return store.createCipher(mode, secret);
- }
-
- protected synchronized SecretKey getSecretKey(CryptingPageStore store) throws GeneralSecurityException
- {
- if (secretKey == null)
- {
- secretKey = store.createSecretKey(cipherKey);
- }
-
- return secretKey;
+ return cypter.encrypt(decrypted);
}
- public byte[] crypt(CryptingPageStore store, byte[] bytes, int mode)
+ public byte[] decrypt(byte[] encrypted)
{
- try
- {
- Cipher cipher = createCipher(store, mode);
-
- return cipher.doFinal(bytes);
- }
- catch (GeneralSecurityException ex)
- {
- throw new WicketRuntimeException(ex);
- }
+ return cypter.decrypt(encrypted);
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/ee21d997/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
index e526155..032fa4f 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/InSessionPageStore.java
@@ -219,7 +219,7 @@ public class InSessionPageStore extends DelegatingPageStore
}
candidate = (IManageablePage)serializer.deserialize(((SerializedPage)candidate).getData());
- pages.set(id, candidate);
+ pages.set(p, candidate);
}
page = candidate;
http://git-wip-us.apache.org/repos/asf/wicket/blob/ee21d997/wicket-core/src/main/java/org/apache/wicket/pageStore/crypt/DefaultCrypter.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/crypt/DefaultCrypter.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/crypt/DefaultCrypter.java
new file mode 100644
index 0000000..8d06339
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/crypt/DefaultCrypter.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.pageStore.crypt;
+
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+import org.apache.wicket.WicketRuntimeException;
+
+/**
+ * Default encryption and decryption implementation.
+ */
+public class DefaultCrypter implements ICrypter
+{
+ private final SecureRandom random;
+
+ private final SecretKey key;
+
+ public DefaultCrypter()
+ {
+ try
+ {
+ random = SecureRandom.getInstance("SHA1PRNG", "SUN");
+
+ KeyGenerator generator = KeyGenerator.getInstance("AES");
+ generator.init(256, random);
+ key = generator.generateKey();
+ }
+ catch (GeneralSecurityException ex)
+ {
+ throw new WicketRuntimeException(ex);
+ }
+ }
+
+ protected Cipher getCipher() throws GeneralSecurityException
+ {
+ return Cipher.getInstance("AES/CBC/PKCS5Padding");
+ }
+
+ @Override
+ public byte[] encrypt(byte[] decrypted)
+ {
+ try
+ {
+ Cipher cipher = getCipher();
+ cipher.init(Cipher.ENCRYPT_MODE, key, random);
+
+ AlgorithmParameters params = cipher.getParameters();
+ byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
+
+ byte[] ciphertext = cipher.doFinal(decrypted);
+
+ byte[] encrypted = Arrays.copyOf(iv, iv.length + ciphertext.length);
+ System.arraycopy(ciphertext, 0, encrypted, iv.length, ciphertext.length);
+
+ return encrypted;
+ }
+ catch (GeneralSecurityException ex)
+ {
+ throw new WicketRuntimeException(ex);
+ }
+ }
+
+ @Override
+ public byte[] decrypt(byte[] encrypted)
+ {
+ try
+ {
+ byte[] iv = new byte[16];
+ byte[] ciphertext = new byte[encrypted.length - 16];
+ System.arraycopy(encrypted, 0, iv, 0, iv.length);
+ System.arraycopy(encrypted, 16, ciphertext, 0, ciphertext.length);
+
+ Cipher cipher = getCipher();
+ cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
+ byte[] decrypted = cipher.doFinal(ciphertext);
+
+ return decrypted;
+ }
+ catch (GeneralSecurityException ex)
+ {
+ throw new WicketRuntimeException(ex);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/ee21d997/wicket-core/src/main/java/org/apache/wicket/pageStore/crypt/ICrypter.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/crypt/ICrypter.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/crypt/ICrypter.java
new file mode 100644
index 0000000..f5b37d9
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/crypt/ICrypter.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.pageStore.crypt;
+
+import java.io.Serializable;
+
+/**
+ * An encrypter and decrypter of pages.
+ */
+public interface ICrypter extends Serializable {
+ byte[] encrypt(byte[] bytes);
+
+ byte[] decrypt(byte[] bytes);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/ee21d997/wicket-core/src/main/java/org/apache/wicket/settings/StoreSettings.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/settings/StoreSettings.java b/wicket-core/src/main/java/org/apache/wicket/settings/StoreSettings.java
index 63a5499..6e911d3 100644
--- a/wicket-core/src/main/java/org/apache/wicket/settings/StoreSettings.java
+++ b/wicket-core/src/main/java/org/apache/wicket/settings/StoreSettings.java
@@ -38,14 +38,6 @@ import org.apache.wicket.util.lang.Bytes;
*/
public class StoreSettings
{
- /**
- * By default the second level cache is disabled.
- *
- * @see <a href="https://issues.apache.org/jira/browse/WICKET-5554">WICKET-5554</a>
- * @see <a href="https://cwiki.apache.org/confluence/x/qIaoAQ">Wicket Page storages</a>
- */
- private static final int DEFAULT_CACHE_SIZE = 0;
-
private static final Bytes DEFAULT_MAX_SIZE_PER_SESSION = Bytes.megabytes(10);
private static final int DEFAULT_ASYNCHRONOUS_QUEUE_CAPACITY = 100;
@@ -56,7 +48,9 @@ public class StoreSettings
private int asynchronousQueueCapacity = DEFAULT_ASYNCHRONOUS_QUEUE_CAPACITY;
- private boolean isAsynchronous = true;
+ private boolean asynchronous = true;
+
+ private boolean encrypted = false;
/**
* Construct.
@@ -177,15 +171,28 @@ public class StoreSettings
*/
public StoreSettings setAsynchronous(boolean async)
{
- isAsynchronous = async;
+ asynchronous = async;
return this;
}
/**
- * @return {@code true} if the storing of page's bytes is asynchronous
+ * @return {@code true} if the storing of page is asynchronous
*/
public boolean isAsynchronous()
{
- return isAsynchronous;
+ return asynchronous;
+ }
+
+ public void setEncrypted(boolean encrypted)
+ {
+ this.encrypted = encrypted;
+ }
+
+ /**
+ * @return {@code true} if the storing of page is encrypted
+ */
+ public boolean isEncrypted()
+ {
+ return encrypted;
}
}