diff --git a/magnolia-core/pom.xml b/magnolia-core/pom.xml
index 73b9aa0..1cae0ae 100644
--- a/magnolia-core/pom.xml
+++ b/magnolia-core/pom.xml
@@ -40,14 +40,10 @@
org.mindrot
jbcrypt
-
- org.bouncycastle
- bcprov-ext-jdk16
-
-
- org.bouncycastle
- bcpg-jdk16
-
+
+ org.bouncycastle
+ bcprov-jdk15on
+
com.google.inject
guice
diff --git a/magnolia-core/src/main/java/info/magnolia/cms/security/SecurityUtil.java b/magnolia-core/src/main/java/info/magnolia/cms/security/SecurityUtil.java
index 9c7056e..eee24d8 100644
--- a/magnolia-core/src/main/java/info/magnolia/cms/security/SecurityUtil.java
+++ b/magnolia-core/src/main/java/info/magnolia/cms/security/SecurityUtil.java
@@ -47,34 +47,32 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.math.BigInteger;
import java.security.DigestInputStream;
import java.security.DigestOutputStream;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
+import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.commons.lang.StringUtils;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.crypto.AsymmetricBlockCipher;
+import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.engines.RSABlindedEngine;
+import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
+import org.bouncycastle.crypto.util.PrivateKeyFactory;
+import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
+import org.bouncycastle.crypto.util.PublicKeyFactory;
+import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
import org.mindrot.jbcrypt.BCrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -92,6 +90,10 @@
public static final String SHA1 = "SHA-1"; //$NON-NLS-1$
public static final String MD5 = "MD5"; //$NON-NLS-1$
+
+ /** defaults as in default jce KeyGenerator */
+ final static BigInteger defaultPublicExponent = BigInteger.valueOf(0x10001);
+ final static int defaultTests = 12;
/**
* There are five (5) FIPS-approved* algorithms for generating a condensed representation of a message (message
@@ -101,17 +103,7 @@
public static final String SHA384 = "SHA-384"; //$NON-NLS-1$
public static final String SHA512 = "SHA-512"; //$NON-NLS-1$
- /**
- * Encryption algorithm used ... if you are ever changing this, keep in mind underlying impl relies on padding!
- */
-
- private static final String ALGORITHM = "RSA";
-
private static Logger log = LoggerFactory.getLogger(SecurityUtil.class);
-
- static {
- Security.addProvider(new BouncyCastleProvider());
- }
/**
* Checks if the currently acting user is anonymous.
@@ -128,6 +120,10 @@
public static String decrypt(String pass) throws SecurityException {
return decrypt(pass, getPublicKey());
+ }
+
+ private static AsymmetricBlockCipher createCipher(){
+ return new RSABlindedEngine();
}
public static String decrypt(String message, String encodedKey) throws SecurityException {
@@ -140,21 +136,14 @@
byte[] binaryKey = hexToByteArray(encodedKey);
// create RSA public key cipher
- Cipher pkCipher = Cipher.getInstance(ALGORITHM, "BC");
- try {
- // create private key
- X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(binaryKey);
- KeyFactory kf = KeyFactory.getInstance(ALGORITHM, "BC");
- PublicKey pk = kf.generatePublic(publicKeySpec);
- pkCipher.init(Cipher.DECRYPT_MODE, pk);
-
- } catch (InvalidKeySpecException e) {
- // decrypting with private key?
- PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(binaryKey);
- KeyFactory kf = KeyFactory.getInstance(ALGORITHM, "BC");
- PrivateKey pk = kf.generatePrivate(privateKeySpec);
- pkCipher.init(Cipher.DECRYPT_MODE, pk);
- }
+ AsymmetricBlockCipher pkCipher = createCipher();
+ AsymmetricKeyParameter params;
+ try{
+ params = PublicKeyFactory.createKey(binaryKey);
+ }catch(IOException ex){
+ params = PrivateKeyFactory.createKey(binaryKey);
+ }
+ pkCipher.init(false, params);
// decrypt
String[] chunks = StringUtils.split(message, ";");
@@ -164,28 +153,16 @@
StringBuilder clearText = new StringBuilder();
for (String chunk : chunks) {
byte[] byteChunk = hexToByteArray(chunk);
- clearText.append(new String(pkCipher.doFinal(byteChunk), "UTF-8"));
+ clearText.append(new String(pkCipher.processBlock(byteChunk, 0, byteChunk.length), "UTF-8"));
}
return clearText.toString();
} catch (NumberFormatException e) {
throw new SecurityException("The encrypted information is corrupted or incomplete. Please make sure someone is not trying to intercept or modify encrypted message.", e);
} catch (IOException e) {
throw new SecurityException("Failed to read authentication string. Please use Java version with cryptography support.", e);
- } catch (NoSuchAlgorithmException e) {
- throw new SecurityException("Failed to read authentication string. Please use Java version with cryptography support.", e);
- } catch (NoSuchPaddingException e) {
- throw new SecurityException("Failed to read authentication string. Please use Java version with cryptography support.", e);
- } catch (InvalidKeySpecException e) {
- throw new SecurityException("Failed to read authentication string. Please use Java version with cryptography support.", e);
- } catch (InvalidKeyException e) {
- throw new SecurityException("Failed to read authentication string. Please use Java version with cryptography support.", e);
- } catch (NoSuchProviderException e) {
- throw new SecurityException("Failed to find encryption provider. Please use Java version with cryptography support.", e);
- } catch (IllegalBlockSizeException e) {
- throw new SecurityException("Failed to decrypt message. It might have been corrupted during transport.", e);
- } catch (BadPaddingException e) {
- throw new SecurityException("Failed to decrypt message. It might have been corrupted during transport.", e);
- }
+ } catch (InvalidCipherTextException e) {
+ throw new SecurityException("Failed to decrypt message. It might have been corrupted during transport.", e);
+ }
}
@@ -203,23 +180,14 @@
}
byte[] binaryKey = hexToByteArray(encodedKey);
- // create RSA public key cipher
- Cipher pkCipher = Cipher.getInstance(ALGORITHM, "BC");
- try {
- // create private key
- PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(binaryKey);
- KeyFactory kf = KeyFactory.getInstance(ALGORITHM, "BC");
- PrivateKey pk = kf.generatePrivate(privateKeySpec);
-
- pkCipher.init(Cipher.ENCRYPT_MODE, pk);
- } catch (InvalidKeySpecException e) {
- // encrypting with public key?
- X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(binaryKey);
- KeyFactory kf = KeyFactory.getInstance(ALGORITHM, "BC");
- PublicKey pk = kf.generatePublic(publicKeySpec);
-
- pkCipher.init(Cipher.ENCRYPT_MODE, pk);
- }
+ AsymmetricBlockCipher pkCipher = createCipher();
+ AsymmetricKeyParameter params;
+ try{
+ params = PrivateKeyFactory.createKey(binaryKey);
+ }catch(IOException ex){
+ params = PublicKeyFactory.createKey(binaryKey);
+ }
+ pkCipher.init(true, params);
// encrypt
byte[] bytes = message.getBytes("UTF-8");
@@ -230,7 +198,7 @@
byte[] tmp = new byte[Math.min(bytes.length - start, binaryKey.length / 8)];
System.arraycopy(bytes, start, tmp, 0, tmp.length);
start += tmp.length;
- byte[] encrypted = pkCipher.doFinal(tmp);
+ byte[] encrypted = pkCipher.processBlock(tmp, 0, tmp.length);
chaos.append(byteArrayToHex(encrypted));
chaos.append(";");
}
@@ -240,21 +208,9 @@
} catch (IOException e) {
throw new SecurityException("Failed to create authentication string. Please use Java version with cryptography support.", e);
- } catch (NoSuchAlgorithmException e) {
- throw new SecurityException("Failed to create authentication string. Please use Java version with cryptography support.", e);
- } catch (NoSuchPaddingException e) {
- throw new SecurityException("Failed to create authentication string. Please use Java version with cryptography support.", e);
- } catch (InvalidKeySpecException e) {
- throw new SecurityException("Failed to create authentication string. Please use Java version with cryptography support.", e);
- } catch (InvalidKeyException e) {
- throw new SecurityException("Failed to create authentication string. Please use Java version with cryptography support.", e);
- } catch (NoSuchProviderException e) {
- throw new SecurityException("Failed to find encryption provider. Please use Java version with cryptography support.", e);
- } catch (IllegalBlockSizeException e) {
+ } catch (InvalidCipherTextException e) {
throw new SecurityException("Failed to encrypt string. Please use Java version with cryptography support.", e);
- } catch (BadPaddingException e) {
- throw new SecurityException("Failed to encrypt string. Please use Java version with cryptography support.", e);
- }
+ }
}
public static String getPrivateKey() {
@@ -340,10 +296,19 @@
}
public static MgnlKeyPair generateKeyPair(int keyLength) throws NoSuchAlgorithmException {
- KeyPairGenerator kgen = KeyPairGenerator.getInstance(ALGORITHM);
- kgen.initialize(keyLength);
- KeyPair key = kgen.genKeyPair();
- return new MgnlKeyPair(byteArrayToHex(key.getPrivate().getEncoded()), byteArrayToHex(key.getPublic().getEncoded()));
+ RSAKeyPairGenerator kgen = new RSAKeyPairGenerator();
+ kgen.init(new RSAKeyGenerationParameters(defaultPublicExponent,
+ new SecureRandom(), keyLength, defaultTests));
+ AsymmetricCipherKeyPair key = kgen.generateKeyPair();
+ try {
+ String privateKeyHex = byteArrayToHex(PrivateKeyInfoFactory
+ .createPrivateKeyInfo(key.getPrivate()).getEncoded());
+ String publicKeyHex = byteArrayToHex(SubjectPublicKeyInfoFactory
+ .createSubjectPublicKeyInfo(key.getPublic()).getEncoded());
+ return new MgnlKeyPair(privateKeyHex, publicKeyHex);
+ } catch (IOException e) {
+ throw new NoSuchAlgorithmException(e);
+ }
}
/**
diff --git a/pom.xml b/pom.xml
index 880705c..f4d51b1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -314,9 +314,15 @@
org.bouncycastle
- bcprov-jdk16
+ bcprov-jdk16
1.46
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.49
+
+
org.bouncycastle
bcprov-ext-jdk16