Package org.hive2hive.core.security

Source Code of org.hive2hive.core.security.EncryptionUtilTest

package org.hive2hive.core.security;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
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.IOException;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.SignatureException;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

import org.apache.commons.io.FileUtils;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.encodings.PKCS1Encoding;
import org.bouncycastle.crypto.engines.RSAEngine;
import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.hive2hive.core.H2HJUnitTest;
import org.hive2hive.core.network.NetworkTestUtil;
import org.hive2hive.core.security.EncryptionUtil.AES_KEYLENGTH;
import org.hive2hive.core.security.EncryptionUtil.RSA_KEYLENGTH;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

public class EncryptionUtilTest extends H2HJUnitTest {

  @BeforeClass
  public static void initTest() throws Exception {
    testClass = EncryptionUtilTest.class;
    beforeClass();
  }

  @Test
  public void generateAESKeyTest() {

    // test all key sizes
    AES_KEYLENGTH[] sizes = getAESKeySizes();

    for (int s = 0; s < sizes.length; s++) {

      logger.debug("Testing AES {}-bit key generation.", sizes[s].value());

      // generate AES key
      long start = System.currentTimeMillis();
      SecretKey aesKey = EncryptionUtil.generateAESKey(sizes[s]);
      long stop = System.currentTimeMillis();
      logger.debug("Generated AES key: {}.", EncryptionUtil.toHex(aesKey.getEncoded()));
      logger.debug("Time: {} ms.", stop - start);

      assertNotNull(aesKey);
      assertTrue(aesKey.getAlgorithm().equals("AES"));
    }
  }

  @Test
  public void generateRSAKeyPairTest() {

    // test all key sizes
    RSA_KEYLENGTH[] sizes = getRSAKeySizes();

    for (int s = 0; s < sizes.length; s++) {

      logger.debug("Testing RSA {}-bit key pair generation.", sizes[s].value());

      // generate RSA key pair
      long start = System.currentTimeMillis();
      KeyPair rsaKeyPair = EncryptionUtil.generateRSAKeyPair(sizes[s]);
      long stop = System.currentTimeMillis();

      assertNotNull(rsaKeyPair);
      assertNotNull(rsaKeyPair.getPrivate());
      assertNotNull(rsaKeyPair.getPublic());

      logger.debug("Private Key: {}.", EncryptionUtil.toHex(rsaKeyPair.getPrivate().getEncoded()));
      logger.debug("Public Key: {}.", EncryptionUtil.toHex(rsaKeyPair.getPublic().getEncoded()));
      logger.debug("Time: {} ms.", stop - start);
    }
  }

  @Test
  public void encryptionAESTest() {

    // test all key sizes
    AES_KEYLENGTH[] sizes = getAESKeySizes();

    for (int s = 0; s < sizes.length; s++) {

      logger.debug("Testing AES {}-bit encryption and decryption.", sizes[s].value());

      // generate random sized content (max. 2MB)
      byte[] data = generateRandomContent(2097152);

      // generate AES key
      SecretKey aesKey = EncryptionUtil.generateAESKey(sizes[s]);

      // generate IV
      byte[] initVector = EncryptionUtil.generateIV();

      // encrypt data
      byte[] encryptedData = null;
      try {
        encryptedData = EncryptionUtil.encryptAES(data, aesKey, initVector);
      } catch (DataLengthException | IllegalStateException | InvalidCipherTextException e) {
        logger.error("Exception while testing AES encryption:", e);
        e.printStackTrace();
      }

      assertNotNull(encryptedData);
      assertFalse(Arrays.equals(data, encryptedData));

      // decrypt data
      byte[] decryptedData = null;
      try {
        decryptedData = EncryptionUtil.decryptAES(encryptedData, aesKey, initVector);
      } catch (DataLengthException | IllegalStateException | InvalidCipherTextException e) {
        logger.error("Exception while testing AES decryption:", e);
        e.printStackTrace();
      }

      assertNotNull(decryptedData);
      assertFalse(Arrays.equals(encryptedData, decryptedData));
      assertTrue(Arrays.equals(data, decryptedData));
    }
  }

  @Test
  public void encryptionRSATest() {

    // test all key sizes
    RSA_KEYLENGTH[] sizes = getRSAKeySizes();

    for (int s = 0; s < sizes.length; s++) {

      logger.debug("Testing RSA {}-bit encryption and decryption.", sizes[s].value());

      // generate random sized content (max. (key size / 8) - 11 bytes)
      byte[] data = generateRandomContent((sizes[s].value() / 8) - 11);

      logger.debug("Testing RSA encryption of a sample {} byte file with a {} bit key.", data.length,
          sizes[s].value());
      printBytes("Original Data", data);

      // generate RSA key pair
      KeyPair rsaKeyPair = EncryptionUtil.generateRSAKeyPair(sizes[s]);

      // encrypt data with public key
      byte[] encryptedData = null;
      try {
        encryptedData = EncryptionUtil.encryptRSA(data, rsaKeyPair.getPublic());
      } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
        logger.error("Exception while testing RSA encryption:", e);
        e.printStackTrace();
        e.printStackTrace();
      }

      assertNotNull(encryptedData);
      assertFalse(Arrays.equals(data, encryptedData));

      printBytes("Encrypted Data:", encryptedData);

      // decrypt data with private key
      byte[] decryptedData = null;

      try {
        decryptedData = EncryptionUtil.decryptRSA(encryptedData, rsaKeyPair.getPrivate());
      } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
        logger.error("Exception while testing RSA decryption:", e);
        e.printStackTrace();
      }

      assertNotNull(decryptedData);
      assertTrue(Arrays.equals(data, decryptedData));

      printBytes("Decrypted Data:", decryptedData);
    }
  }

  @Test
  public void encryptionHybridTest() {

    RSA_KEYLENGTH[] rsaSizes = getRSAKeySizes();
    AES_KEYLENGTH[] aesSizes = getAESKeySizes();

    // test all RSA key sizes
    for (int s1 = 0; s1 < rsaSizes.length; s1++) {

      // test all AES key sizes
      for (int s2 = 0; s2 < aesSizes.length; s2++) {

        // generate random content (50 MB)
        byte[] data = generateFixedContent(52428800);

        logger.debug(
            "Testing hybrid encryption and decryption of a sample {} byte file with a {} bit RSA and a {} bit AES key.",
            data.length, rsaSizes[s1].value(), aesSizes[s2].value());

        // generate RSA key pair
        long start = System.currentTimeMillis();
        KeyPair rsaKeyPair = EncryptionUtil.generateRSAKeyPair(rsaSizes[s1]);
        long stop = System.currentTimeMillis();
        logger.debug("RSA Key Generation Time: {} ms.", stop - start);

        // encrypt data with public key
        HybridEncryptedContent encryptedData = null;
        try {
          start = System.currentTimeMillis();
          encryptedData = EncryptionUtil.encryptHybrid(data, rsaKeyPair.getPublic(), aesSizes[s2]);
          stop = System.currentTimeMillis();
          logger.debug("Hybrid Encryption Time: {} ms.", stop - start);
        } catch (DataLengthException | InvalidKeyException | IllegalStateException
            | InvalidCipherTextException | IllegalBlockSizeException | BadPaddingException e) {
          logger.error("Exception while testing hybrid encryption:", e);
          e.printStackTrace();
        }

        assertNotNull(encryptedData);
        assertNotNull(encryptedData.getEncryptedData());
        assertNotNull(encryptedData.getEncryptedParameters());
        assertFalse(Arrays.equals(data, encryptedData.getEncryptedData()));

        // decrypt data with private key
        byte[] decryptedData = null;
        try {
          start = System.currentTimeMillis();
          decryptedData = EncryptionUtil.decryptHybrid(encryptedData, rsaKeyPair.getPrivate());
          stop = System.currentTimeMillis();
          logger.debug("Hybrid Decryption Time: {} ms.", stop - start);
        } catch (InvalidKeyException | DataLengthException | IllegalBlockSizeException
            | BadPaddingException | IllegalStateException | InvalidCipherTextException e) {
          logger.error("Exception while testing hybrid decryption:", e);
          e.printStackTrace();
        }

        assertNotNull(decryptedData);
        assertTrue(Arrays.equals(data, decryptedData));
      }
    }
  }

  @Test
  public void signatureTest() {

    // test all key sizes
    RSA_KEYLENGTH[] sizes = getRSAKeySizes();

    for (int s = 0; s < sizes.length; s++) {

      logger.debug("Testing SHA-1 with RSA {}-bit signing and verificiation.", sizes[s].value());

      // generate random sized content (max. 100 bytes)
      byte[] data = generateRandomContent(100);
      printBytes("Original Data:", data);

      // generate RSA key pair
      KeyPair rsaKeyPair = EncryptionUtil.generateRSAKeyPair(sizes[s]);

      // sign data with private key
      byte[] signature = null;
      try {
        signature = EncryptionUtil.sign(data, rsaKeyPair.getPrivate());
      } catch (InvalidKeyException | SignatureException e) {
        logger.error("Exception while testing signing:", e);
        e.printStackTrace();
      }

      assertNotNull(signature);

      printBytes("Signature:", signature);

      // verify data with public key
      boolean isVerified = false;
      try {
        isVerified = EncryptionUtil.verify(data, signature, rsaKeyPair.getPublic());
      } catch (InvalidKeyException | SignatureException e) {
        logger.error("Exception while testing verification:", e);
        e.printStackTrace();
      }

      assertTrue(isVerified);
    }
  }

  @Test
  public void md5DataTest() {
    String data = generateRandomString(1000);
    byte[] md5 = EncryptionUtil.generateMD5Hash(data.getBytes());
    assertNotNull(md5);

    // assert that hashing twice results in the same md5 hash
    assertEquals(new String(md5), new String(EncryptionUtil.generateMD5Hash(data.getBytes())));

    // assert that different data is hashed to different md5 hashes
    String data2 = generateRandomString(1000);
    assertNotEquals(data, data2);
    assertNotEquals(new String(md5), new String(EncryptionUtil.generateMD5Hash(data2.getBytes())));
  }

  @Test
  public void md5StreamTest() throws IOException {
    String data = generateRandomString(5 * 1024);
    File file = new File(System.getProperty("java.io.tmpdir"), NetworkTestUtil.randomString());
    FileUtils.writeStringToFile(file, data);

    byte[] md5 = EncryptionUtil.generateMD5Hash(file);
    assertNotNull(md5);

    // assert that hashing twice results in the same md5 hash
    assertEquals(new String(md5), new String(EncryptionUtil.generateMD5Hash(file)));

    // assert that different data is hashed to different md5 hashes
    String data2 = generateRandomString(1000);
    assertNotEquals(data, data2);
    assertNotEquals(new String(md5), new String(EncryptionUtil.generateMD5Hash(data2.getBytes())));
  }

  @Test
  public void serializationTest() throws IOException, ClassNotFoundException {

    String data = generateRandomString(1000);
    logger.debug("Testing data serialization.");
    logger.debug("Test String: {}.", data);

    byte[] serializedData = EncryptionUtil.serializeObject(data);
    assertNotNull(serializedData);
    printBytes("Serialized Data:", serializedData);

    String deserializedData = (String) EncryptionUtil.deserializeObject(serializedData);
    assertNotNull(deserializedData);
    assertEquals(data, deserializedData);
  }

  @Test
  public void testIVGeneration() {
    for (int i = 0; i < 100000; i++)
      Assert.assertNotEquals(0, EncryptionUtil.generateIV()[0]);
  }

  @Test
  @Ignore
  public void testPureLightweightBouncyCastle() throws IOException, InvalidKeyException, IllegalBlockSizeException,
      BadPaddingException, DataLengthException, IllegalStateException, InvalidCipherTextException,
      NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
      InvalidAlgorithmParameterException {

    long startTime = System.currentTimeMillis();

    Security.addProvider(new BouncyCastleProvider());

    // generate RSA keys
    RSAKeyPairGenerator gen = new RSAKeyPairGenerator();
    gen.init(new RSAKeyGenerationParameters(new BigInteger("10001", 16), new SecureRandom(), 2048, 80));
    AsymmetricCipherKeyPair keyPair = gen.generateKeyPair();

    // some data where first entry is 0
    byte[] data = { 10, 122, 12, 127, 35, 58, 87, 56, -6, 73, 10, -13, -78, 4, -122, -61 };

    // encrypt data asymmetrically
    AsymmetricBlockCipher cipher = new RSAEngine();
    cipher = new PKCS1Encoding(cipher);
    cipher.init(true, keyPair.getPublic());
    byte[] rsaEncryptedData = cipher.processBlock(data, 0, data.length);

    Assert.assertFalse(Arrays.equals(data, rsaEncryptedData));

    // decrypt data asymmetrically
    cipher.init(false, keyPair.getPrivate());
    byte[] dataBack = cipher.processBlock(rsaEncryptedData, 0, rsaEncryptedData.length);

    assertTrue(Arrays.equals(data, dataBack));

    long stopTime = System.currentTimeMillis();
    long elapsedTime = stopTime - startTime;
    logger.debug("elapsed time = {}", elapsedTime);
  }

  public static AES_KEYLENGTH[] getAESKeySizes() {
    AES_KEYLENGTH[] sizes = new AES_KEYLENGTH[AES_KEYLENGTH.values().length];
    for (int i = 0; i < sizes.length; i++) {
      sizes[i] = AES_KEYLENGTH.values()[i];
    }
    return sizes;
  }

  public static RSA_KEYLENGTH[] getRSAKeySizes() {
    RSA_KEYLENGTH[] sizes = new RSA_KEYLENGTH[RSA_KEYLENGTH.values().length];
    for (int i = 0; i < sizes.length; i++) {
      sizes[i] = RSA_KEYLENGTH.values()[i];
    }
    return sizes;
  }

  @AfterClass
  public static void endTest() throws Exception {
    afterClass();
  }
}
TOP

Related Classes of org.hive2hive.core.security.EncryptionUtilTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.