Package com.google.k2crypto.keyversions

Source Code of com.google.k2crypto.keyversions.AESKeyVersionTest

/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed 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 com.google.k2crypto.keyversions;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

import com.google.k2crypto.SymmetricEncryption;
import com.google.k2crypto.exceptions.BuilderException;
import com.google.k2crypto.exceptions.DecryptionException;
import com.google.k2crypto.exceptions.EncryptionException;
import com.google.k2crypto.keyversions.AESKeyVersion.Mode;
import com.google.k2crypto.keyversions.AESKeyVersion.Padding;
import com.google.k2crypto.keyversions.KeyVersionProto.KeyVersionData;
import com.google.protobuf.ByteString;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.InvalidProtocolBufferException;

import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
* Tests for AESkeyVersion class
*
* @author John Maheswaran (maheswaran@google.com)
*/
public class AESKeyVersionTest {
 
  /**
   * Tests that the AESKeyVersion correctly saves to and loads from proto data.
   */
  @Test
  public void testSaveLoad()
      throws BuilderException, InvalidProtocolBufferException {
   
    // Just generate a key version (use non-defaults where possible)
    AESKeyVersion toSave = new AESKeyVersion.Builder().mode(Mode.ECB).build();
    // Dump its proto data bytes
    ByteString bytes = toSave.buildData().build().toByteString();
   
    // Create a proto extension registry and register AES extension
    // (this will normally be done by KeyVersionRegistry)
    ExtensionRegistry registry = ExtensionRegistry.newInstance();
    AesKeyVersionProto.registerAllExtensions(registry);
   
    // Read the proto
    AESKeyVersion loaded = new AESKeyVersion.Builder()
        .withData(KeyVersionData.parseFrom(bytes, registry), registry).build();
   
    // Make sure the data is the same at a low-level (nothing gets lost)
    assertEquals(bytes, loaded.buildData().build().toByteString());

    // Make sure the important fields are all the same
    assertArrayEquals(
        toSave.getKeyVersionMatter(), loaded.getKeyVersionMatter());
    assertEquals(toSave.getAlgModePadding(), loaded.getAlgModePadding());
  }
 
  /**
   * This tests the encryption and decryption methods of the AESKeyVersion class.
   *
   * @throws BuilderException
   * @throws EncryptionException
   * @throws DecryptionException
   */
  @Test
  public void testEncryptDecrypt() throws BuilderException, EncryptionException,
      DecryptionException {

    // create AES key
    AESKeyVersion keyVersion =
        new AESKeyVersion.Builder().keyVersionLengthInBytes(16).build();
    // call the method to test encrypting and decrypting strings using this key version
    testEncryptDecryptKeyVersion(keyVersion);
  }

  /**
   * This tests loading a keyVersion matter byte array and using it to encrypt and decrypt a
   * message.
   *
   * @throws BuilderException
   * @throws EncryptionException
   * @throws DecryptionException
   */
  @Test
  public void testLoadkeyVersionMatter() throws BuilderException, EncryptionException,
      DecryptionException {
    // create AES key
    AESKeyVersion key1 =
        new AESKeyVersion.Builder().keyVersionLengthInBytes(16).build();
    // obtain the raw keyVersion matter
    byte[] keyVersionMatter = getkeyVersionMatter(key1);
    // obtain the raw initialization vector for first key
    byte[] initvector = getInitVector(key1);

    // create a new keyVersion using the keyVersion matter
    AESKeyVersion key2 = new AESKeyVersion.Builder().keyVersionLengthInBytes(16)
        .matterVector(keyVersionMatter, initvector).build();

    // test text string that we will encrypt and then decrypt
    String testinput = "weak";

    // encrypt the test string using FIRST key
    byte[] encTxt1 = encryptString(key1, testinput);
    // encrypt the test string using SECOND key
    byte[] encTxt2 = encryptString(key2, testinput);

    // test encrypted messages are the same
    assertArrayEquals(encTxt1, encTxt2);

    // test that keyVersion 1 decrypts encrypted message 1
    assertEquals(testinput, decryptString(key1, encTxt1));
    // test that keyVersion 2 decrypts encrypted message 2
    assertEquals(testinput, decryptString(key2, encTxt2));
    // test that keyVersion 2 decrypts encrypted message 1
    assertEquals(testinput, decryptString(key2, encTxt1));
    // test that keyVersion 1 decrypts encrypted message 2
    assertEquals(testinput, decryptString(key1, encTxt2));

  }

  /**
   * Test the AESKeyVersion encrypting and decrypting streams
   *
   * @throws BuilderException
   * @throws DecryptionException
   * @throws EncryptionException
   */
  @Test
  public void testAESKeyVersionStream() throws BuilderException, EncryptionException,
      DecryptionException {
    AESKeyVersion keyversion;

    /*
     *test all keyVersion version length WITHOUT mode
     */
    for (Integer keyVersionLength : new Integer[] {16, 24, 32}) {
      // test keyVersion version length of 16 and PKCS5 padding and ECB mode
      keyversion = new AESKeyVersion.Builder()
          .keyVersionLengthInBytes(keyVersionLength)
          .padding(Padding.PKCS5).build();
      testEncryptDecryptStream(keyversion);

    }

    /*
     *test all keyVersion version length and mode combinations
     */
    for (Integer keyVersionLength : new Integer[] {16, 24, 32}) {
      for (Mode mode : Mode.values()) {
        // test keyVersion version length of 16 and PKCS5 padding and ECB mode
        keyversion = new AESKeyVersion.Builder()
            .keyVersionLengthInBytes(keyVersionLength)
            .padding(Padding.PKCS5).mode(mode).build();
        testEncryptDecryptStream(keyversion);
      }
    }
  }

  /**
   * Helper method to test encrypting and decrypting a stream using an AESKeyVersion
   *
   * @param keyVersion The AESKeyVersion to use to encrypt and decrypt a stream
   * @throws EncryptionException
   * @throws DecryptionException
   */
  private void testEncryptDecryptStream(AESKeyVersion keyVersion) throws EncryptionException,
      DecryptionException {
    /*
     *test the encryption decryption STREAMS. Loop over an array of test input Strings to encrypt
     * and the decrypt
     */
    for (String testinput : new String[] {"weak", "test", "", "1234", "32980342yhio#$@^U"}) {
      // the input stream
      ByteArrayOutputStream inputStream = new ByteArrayOutputStream();

      // convert the test String to an input stream and encrypt it using the keyVersion
      SymmetricEncryption.encryptStream(keyVersion, new ByteArrayInputStream(testinput.getBytes()),
          inputStream);
      // convert the OutputStream (called inputStream) back to an InputStream (called
      // encryptedStream)
      ByteArrayInputStream encryptedStream = new ByteArrayInputStream(inputStream.toByteArray());

      // Initialize another OutputStream for our decrypted output
      ByteArrayOutputStream decryptedStream = new ByteArrayOutputStream();

      // use the keyVersion to decrypt the encrypted stream
      SymmetricEncryption.decryptStream(keyVersion, encryptedStream, decryptedStream);

      // convert the decrypted stream back to a String
      String output = new String(decryptedStream.toByteArray());

      // now check that the input matches the decrypted output
      assertEquals(testinput, output);
    }
  }

  /**
   * This tests creating an AESKeyVersion using the builder, then using that KeyVersion to encrypt
   * and decrypt a message
   *
   * @throws BuilderException
   * @throws EncryptionException
   * @throws DecryptionException
   */
  @Test
  public void testAESKeyVersionBuilder() throws BuilderException, EncryptionException,
      DecryptionException {

    // test using the default keyVersion builder
    AESKeyVersion keyversion = new AESKeyVersion.Builder().build();
    testEncryptDecryptKeyVersion(keyversion);

    /*
     *test all keyVersion version length WITHOUT mode
     */
    for (Integer keyVersionLength : new Integer[] {16, 24, 32}) {
      // test keyVersion version length of 16 and PKCS5 padding and ECB mode
      keyversion = new AESKeyVersion.Builder()
          .keyVersionLengthInBytes(keyVersionLength)
          .padding(Padding.PKCS5).build();
      testEncryptDecryptKeyVersion(keyversion);

    }

    /*
     * test all keyVersion version length and mode combinations
     */
    for (Integer keyVersionLength : new Integer[] {16, 24, 32}) {
      for (Mode mode : Mode.values()) {
        // test keyVersion version length of 16 and PKCS5 padding and ECB mode
        keyversion = new AESKeyVersion.Builder()
            .keyVersionLengthInBytes(keyVersionLength)
            .padding(Padding.PKCS5).mode(mode).build();
        testEncryptDecryptKeyVersion(keyversion);
      }
    }

  }

  /**
   * This is a helper method used by the testAESKeyVersionBuilder test to testthe encryption and
   * decryption methods of the AESKeyVersion class using a SPECIFIC KEYVERSION (specified by the
   * parameter)
   *
   * @param keyVersion The AESKeyVersion to use to test encryption and decryption
   * @throws EncryptionException
   * @throws DecryptionException
   */
  public void testEncryptDecryptKeyVersion(AESKeyVersion keyVersion) throws EncryptionException,
      DecryptionException {

    // test text string that we will encrypt and then decrypt
    String testinput = "weak";
    // encrypt the test string
    byte[] encTxt = encryptString(keyVersion, testinput);
    // decrypt the message
    String result = decryptString(keyVersion, encTxt);
    // test that the decrypted result is the same as the encryption input
    assertEquals(testinput, result);

    // empty string test
    testinput = "";
    // encrypt the test string
    encTxt = encryptString(keyVersion, testinput);
    // decrypt the message
    result = decryptString(keyVersion, encTxt);
    // test that the decrypted result is the same as the encryption input
    assertEquals(testinput, result);
  }


  /**
   * Helper method to return the key version matter of an AESKeyVersion. Used to help test loading
   * an AESKeyVersion from a byte array
   *
   * @param kv The AESKeyVersion from which we want to read the key version matter
   * @return The byte array representation of the key version matter
   */
  private byte[] getkeyVersionMatter(AESKeyVersion kv) {
    return kv.getKeyVersionMatter();
  }

  /**
   * Helper method to return the initialization vector to other classes.
   *
   * @param kv The AESKeyVersion from which we want to read the key version matter
   * @return The byte array representation of the initialization vector
   */
  private byte[] getInitVector(AESKeyVersion kv) {
    return kv.getInitVector();
  }

  /**
   * Helper method to encrypt a string using the AES key version. This is used to make testing
   * encrypting a byte array easier so we can read the input string and decrypted string easily.
   *
   * @param kv The AESKeyVersion that we want to use to encrypt the String
   * @param input The input string that we want to encrypt
   * @return The byte array representation of the AES encrypted version of the strings
   * @throws EncryptionException
   */
  private byte[] encryptString(AESKeyVersion kv, String input) throws EncryptionException {
    // Convert the input string to bytes
    byte[] data = input.getBytes();
    // call the encrypt bytes method to encrypt the data
    byte[] encData = SymmetricEncryption.encryptBytes(kv, data);

    // return the encrypted string
    return encData;
  }

  /**
   * Helper method that decrypts an encrypted string
   *
   * @param kv The AESKeyVersion that we want to use to decrypt the String
   * @param input byte array representation of encrypted message
   * @return String representation of decrypted message
   * @throws DecryptionException
   */
  private String decryptString(AESKeyVersion kv, byte[] input) throws DecryptionException {
    // call decrypt bytes method
    byte[] outputData = SymmetricEncryption.decryptBytes(kv, input);
    // convert to string
    String result = new String(outputData);
    // return result
    return result;
  }

}
TOP

Related Classes of com.google.k2crypto.keyversions.AESKeyVersionTest

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.