Browse Source

Merge branch '0.5.1'

Conflicts:
	main/core/pom.xml
	main/crypto-aes/pom.xml
	main/crypto-api/pom.xml
	main/pom.xml
	main/ui/pom.xml
Sebastian Stenzel 10 years ago
parent
commit
5bd38d31bf

+ 14 - 34
main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java

@@ -25,7 +25,6 @@ import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Random;
 import java.util.UUID;
 
 import javax.crypto.BadPaddingException;
@@ -58,19 +57,19 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 
 public class Aes256Cryptor extends AbstractCryptor implements AesCryptographicConfiguration, FileNamingConventions {
 
-	/**
-	 * PRNG for cryptographically secure random numbers. Defaults to SHA1-based number generator.
-	 * 
-	 * @see http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SecureRandom
-	 */
-	private static final SecureRandom SECURE_PRNG;
-
 	/**
 	 * Defined in static initializer. Defaults to 256, but falls back to maximum value possible, if JCE Unlimited Strength Jurisdiction
 	 * Policy Files isn't installed. Those files can be downloaded here: http://www.oracle.com/technetwork/java/javase/downloads/.
 	 */
 	private static final int AES_KEY_LENGTH_IN_BITS;
 
+	/**
+	 * PRNG for cryptographically secure random numbers. Defaults to SHA1-based number generator.
+	 * 
+	 * @see http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SecureRandom
+	 */
+	private final SecureRandom securePrng;
+
 	/**
 	 * Jackson JSON-Mapper.
 	 */
@@ -89,7 +88,6 @@ public class Aes256Cryptor extends AbstractCryptor implements AesCryptographicCo
 
 	static {
 		try {
-			SECURE_PRNG = SecureRandom.getInstance(PRNG_ALGORITHM);
 			final int maxKeyLength = Cipher.getMaxAllowedKeyLength(AES_KEY_ALGORITHM);
 			AES_KEY_LENGTH_IN_BITS = (maxKeyLength >= PREF_MASTER_KEY_LENGTH_IN_BITS) ? PREF_MASTER_KEY_LENGTH_IN_BITS : maxKeyLength;
 		} catch (NoSuchAlgorithmException e) {
@@ -101,33 +99,16 @@ public class Aes256Cryptor extends AbstractCryptor implements AesCryptographicCo
 	 * Creates a new Cryptor with a newly initialized PRNG.
 	 */
 	public Aes256Cryptor() {
-		SECURE_PRNG.setSeed(SECURE_PRNG.generateSeed(PRNG_SEED_LENGTH));
 		byte[] bytes = new byte[AES_KEY_LENGTH_IN_BITS / Byte.SIZE];
 		try {
-			SECURE_PRNG.nextBytes(bytes);
+			securePrng = SecureRandom.getInstance(PRNG_ALGORITHM);
+			securePrng.setSeed(securePrng.generateSeed(PRNG_SEED_LENGTH));
+			securePrng.nextBytes(bytes);
 			this.primaryMasterKey = new SecretKeySpec(bytes, AES_KEY_ALGORITHM);
-
-			SECURE_PRNG.nextBytes(bytes);
-			this.hMacMasterKey = new SecretKeySpec(bytes, HMAC_KEY_ALGORITHM);
-		} finally {
-			Arrays.fill(bytes, (byte) 0);
-		}
-	}
-
-	/**
-	 * Creates a new Cryptor with the given PRNG.<br/>
-	 * <strong>DO NOT USE IN PRODUCTION</strong>. This constructor must only be used in in unit tests. Do not change method visibility.
-	 * 
-	 * @param prng Fast, possibly insecure PRNG.
-	 */
-	Aes256Cryptor(Random prng) {
-		byte[] bytes = new byte[AES_KEY_LENGTH_IN_BITS / Byte.SIZE];
-		try {
-			prng.nextBytes(bytes);
-			this.primaryMasterKey = new SecretKeySpec(bytes, AES_KEY_ALGORITHM);
-
-			prng.nextBytes(bytes);
+			securePrng.nextBytes(bytes);
 			this.hMacMasterKey = new SecretKeySpec(bytes, HMAC_KEY_ALGORITHM);
+		} catch (NoSuchAlgorithmException e) {
+			throw new IllegalStateException("PRNG algorithm should exist.", e);
 		} finally {
 			Arrays.fill(bytes, (byte) 0);
 		}
@@ -266,8 +247,7 @@ public class Aes256Cryptor extends AbstractCryptor implements AesCryptographicCo
 
 	private byte[] randomData(int length) {
 		final byte[] result = new byte[length];
-		SECURE_PRNG.setSeed(SECURE_PRNG.generateSeed(PRNG_SEED_LENGTH));
-		SECURE_PRNG.nextBytes(result);
+		securePrng.nextBytes(result);
 		return result;
 	}
 

+ 1 - 1
main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/AesCryptographicConfiguration.java

@@ -33,7 +33,7 @@ interface AesCryptographicConfiguration {
 	/**
 	 * Number of bytes used as seed for the PRNG.
 	 */
-	int PRNG_SEED_LENGTH = 16;
+	int PRNG_SEED_LENGTH = 32;
 
 	/**
 	 * Algorithm used for random number generation.

+ 8 - 11
main/crypto-aes/src/test/java/org/cryptomator/crypto/aes256/Aes256CryptorTest.java

@@ -17,7 +17,6 @@ import java.nio.channels.SeekableByteChannel;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Random;
 
 import org.apache.commons.io.IOUtils;
 import org.cryptomator.crypto.CryptorIOSupport;
@@ -29,17 +28,15 @@ import org.junit.Test;
 
 public class Aes256CryptorTest {
 
-	private static final Random TEST_PRNG = new Random();
-
 	@Test
 	public void testCorrectPassword() throws IOException, WrongPasswordException, DecryptFailedException, UnsupportedKeyLengthException {
 		final String pw = "asd";
-		final Aes256Cryptor cryptor = new Aes256Cryptor(TEST_PRNG);
+		final Aes256Cryptor cryptor = new Aes256Cryptor();
 		final ByteArrayOutputStream out = new ByteArrayOutputStream();
 		cryptor.encryptMasterKey(out, pw);
 		cryptor.swipeSensitiveData();
 
-		final Aes256Cryptor decryptor = new Aes256Cryptor(TEST_PRNG);
+		final Aes256Cryptor decryptor = new Aes256Cryptor();
 		final InputStream in = new ByteArrayInputStream(out.toByteArray());
 		decryptor.decryptMasterKey(in, pw);
 
@@ -50,7 +47,7 @@ public class Aes256CryptorTest {
 	@Test
 	public void testWrongPassword() throws IOException, DecryptFailedException, WrongPasswordException, UnsupportedKeyLengthException {
 		final String pw = "asd";
-		final Aes256Cryptor cryptor = new Aes256Cryptor(TEST_PRNG);
+		final Aes256Cryptor cryptor = new Aes256Cryptor();
 		final ByteArrayOutputStream out = new ByteArrayOutputStream();
 		cryptor.encryptMasterKey(out, pw);
 		cryptor.swipeSensitiveData();
@@ -58,7 +55,7 @@ public class Aes256CryptorTest {
 
 		// all these passwords are expected to fail.
 		final String[] wrongPws = {"a", "as", "asdf", "sdf", "das", "dsa", "foo", "bar", "baz"};
-		final Aes256Cryptor decryptor = new Aes256Cryptor(TEST_PRNG);
+		final Aes256Cryptor decryptor = new Aes256Cryptor();
 		for (final String wrongPw : wrongPws) {
 			final InputStream in = new ByteArrayInputStream(out.toByteArray());
 			try {
@@ -79,7 +76,7 @@ public class Aes256CryptorTest {
 		final InputStream plaintextIn = new ByteArrayInputStream(plaintextData);
 
 		// init cryptor:
-		final Aes256Cryptor cryptor = new Aes256Cryptor(TEST_PRNG);
+		final Aes256Cryptor cryptor = new Aes256Cryptor();
 
 		// encrypt:
 		final ByteBuffer encryptedData = ByteBuffer.allocate(96);
@@ -111,7 +108,7 @@ public class Aes256CryptorTest {
 		final InputStream plaintextIn = new ByteArrayInputStream(plaintextData);
 
 		// init cryptor:
-		final Aes256Cryptor cryptor = new Aes256Cryptor(TEST_PRNG);
+		final Aes256Cryptor cryptor = new Aes256Cryptor();
 
 		// encrypt:
 		final ByteBuffer encryptedData = ByteBuffer.allocate(96);
@@ -150,7 +147,7 @@ public class Aes256CryptorTest {
 		final InputStream plaintextIn = new ByteArrayInputStream(plaintextData);
 
 		// init cryptor:
-		final Aes256Cryptor cryptor = new Aes256Cryptor(TEST_PRNG);
+		final Aes256Cryptor cryptor = new Aes256Cryptor();
 
 		// encrypt:
 		final ByteBuffer encryptedData = ByteBuffer.allocate((int) (64 + plaintextData.length * 1.2));
@@ -178,7 +175,7 @@ public class Aes256CryptorTest {
 	@Test
 	public void testEncryptionOfFilenames() throws IOException, DecryptFailedException {
 		final CryptorIOSupport ioSupportMock = new CryptoIOSupportMock();
-		final Aes256Cryptor cryptor = new Aes256Cryptor(TEST_PRNG);
+		final Aes256Cryptor cryptor = new Aes256Cryptor();
 
 		// short path components
 		final String originalPath1 = "foo/bar/baz";