co.runrightfast.core.crypto.impl.EncryptionServiceImplTest.java Source code

Java tutorial

Introduction

Here is the source code for co.runrightfast.core.crypto.impl.EncryptionServiceImplTest.java

Source

/*
 Copyright 2015 Alfio Zappala
    
 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 co.runrightfast.core.crypto.impl;

import co.runrightfast.core.security.crypto.AESKeySizes;
import co.runrightfast.core.security.crypto.Decryption;
import co.runrightfast.core.security.crypto.Encryption;
import co.runrightfast.core.security.crypto.EncryptionService;
import co.runrightfast.core.security.crypto.EncryptionServiceException;
import co.runrightfast.core.security.crypto.UnknownSecretKeyException;
import co.runrightfast.core.security.crypto.impl.EncryptionServiceImpl;
import static co.runrightfast.core.security.crypto.impl.EncryptionServiceImpl.toKeyMap;
import co.runrightfast.core.security.messages.SecretKeys;
import co.runrightfast.core.security.messages.test.RunRightFastApplicationInstance;
import com.google.common.collect.ImmutableMap;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.time.Instant;
import java.util.Map;
import java.util.logging.Level;
import lombok.extern.java.Log;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.shiro.crypto.AesCipherService;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.Test;

/**
 *
 * @author alfio
 */
@Log
public class EncryptionServiceImplTest {

    private final RunRightFastApplicationInstance appInstance = RunRightFastApplicationInstance.newBuilder()
            .setAppDeploymentVersion("201509-1").setAppName(getClass().getSimpleName()).setAppVersion("1.0.0")
            .setHost("test-01").setJvmId("123@test-01").setStartedOn(Instant.now().toString()).build();

    private final byte[] appInstanceBytes = appInstance.toByteArray();

    private AesCipherService aesCipherService(final int keySize) {
        final AesCipherService aes = new AesCipherService();
        aes.setKeySize(keySize);
        return aes;
    }

    /**
     * Test of getEncryptionKeys method, of class EncryptionServiceImpl.
     */
    @Test
    public void testGetEncryptionKeys() {
        final AesCipherService aes = new AesCipherService();
        final Map<String, Key> keys = ImmutableMap.<String, Key>builder().put("a", aes.generateNewKey()).build();
        final EncryptionService service = new EncryptionServiceImpl(aes, keys);
        assertThat(service.getEncryptionKeys().size(), is(1));
        assertThat(service.getEncryptionKeys().contains("a"), is(true));
        assertThat(service.getEncryptionKeys().contains("b"), is(false));
    }

    @Test
    public void testDefaultEncryptDecrypt() throws InvalidProtocolBufferException {
        final String METHOD = "testDefaultEncryptDecrypt";
        final AesCipherService aes = new AesCipherService();
        final Map<String, Key> keys = ImmutableMap.<String, Key>builder().put("a", aes.generateNewKey()).build();
        final EncryptionService service = new EncryptionServiceImpl(aes, keys);
        byte[] encrypted = service.encrypt(appInstanceBytes, "a");
        log.logp(Level.INFO, getClass().getName(), METHOD,
                String.format("uncrypted length = %d", appInstanceBytes.length));
        log.logp(Level.INFO, getClass().getName(), METHOD,
                String.format("encrypted length = %d", encrypted.length));

        final byte[] decrypted = service.decrypt(encrypted, "a");
        log.logp(Level.INFO, getClass().getName(), METHOD,
                String.format("decrypted length = %d", appInstanceBytes.length));
        final RunRightFastApplicationInstance appInstance2 = RunRightFastApplicationInstance.parseFrom(decrypted);
        assertThat(appInstance2, is(equalTo(appInstance)));
    }

    @Test
    public void testBasicEncryptionDecryption() throws InvalidProtocolBufferException {
        final String METHOD = "testBasicEncryptionDecryption";
        final AesCipherService aes = new AesCipherService();
        final Map<String, Key> keys = ImmutableMap.<String, Key>builder().put("a", aes.generateNewKey()).build();
        final EncryptionService service = new EncryptionServiceImpl(aes, keys);
        final Encryption encryption = service.encryption("a");
        final Decryption decryption = service.decryption("a");
        byte[] encrypted = encryption.apply(appInstanceBytes);
        log.logp(Level.INFO, getClass().getName(), METHOD,
                String.format("uncrypted length = %d", appInstanceBytes.length));
        log.logp(Level.INFO, getClass().getName(), METHOD,
                String.format("encrypted length = %d", encrypted.length));

        final byte[] decrypted = decryption.apply(encrypted);
        log.logp(Level.INFO, getClass().getName(), METHOD,
                String.format("decrypted length = %d", appInstanceBytes.length));
        final RunRightFastApplicationInstance appInstance2 = RunRightFastApplicationInstance.parseFrom(decrypted);
        assertThat(appInstance2, is(equalTo(appInstance)));
    }

    @Test
    public void testDefaultEncryptDecrypt_256KeySize() throws InvalidProtocolBufferException {
        final String METHOD = "testDefaultEncryptDecrypt_256KeySize";
        final AesCipherService aes = aesCipherService(256);
        final Map<String, Key> keys = ImmutableMap.<String, Key>builder().put("a", aes.generateNewKey()).build();
        final EncryptionService service = new EncryptionServiceImpl(aes, keys);
        byte[] encrypted = service.encrypt(appInstanceBytes, "a");
        log.logp(Level.INFO, getClass().getName(), METHOD,
                String.format("uncrypted length = %d", appInstanceBytes.length));
        log.logp(Level.INFO, getClass().getName(), METHOD,
                String.format("encrypted length = %d", encrypted.length));

        final byte[] decrypted = service.decrypt(encrypted, "a");
        log.logp(Level.INFO, getClass().getName(), METHOD,
                String.format("decrypted length = %d", appInstanceBytes.length));
        final RunRightFastApplicationInstance appInstance2 = RunRightFastApplicationInstance.parseFrom(decrypted);
        assertThat(appInstance2, is(equalTo(appInstance)));
    }

    @Test(expected = UnknownSecretKeyException.class)
    public void testInvalidSecretKey_cipherFunctions() {
        final AesCipherService aes = new AesCipherService();
        final Map<String, Key> keys = ImmutableMap.<String, Key>builder().put("a", aes.generateNewKey()).build();
        final EncryptionService service = new EncryptionServiceImpl(aes, keys);
        service.cipherFunctions("b");
    }

    @Test(expected = UnknownSecretKeyException.class)
    public void testInvalidSecretKey_encrypt() {
        final AesCipherService aes = new AesCipherService();
        final Map<String, Key> keys = ImmutableMap.<String, Key>builder().put("a", aes.generateNewKey()).build();
        final EncryptionService service = new EncryptionServiceImpl(aes, keys);
        service.encrypt("data".getBytes(), "b");
    }

    @Test(expected = UnknownSecretKeyException.class)
    public void testInvalidSecretKey_encryption() {
        final AesCipherService aes = new AesCipherService();
        final Map<String, Key> keys = ImmutableMap.<String, Key>builder().put("a", aes.generateNewKey()).build();
        final EncryptionService service = new EncryptionServiceImpl(aes, keys);
        service.encryption("b");
    }

    @Test(expected = UnknownSecretKeyException.class)
    public void testInvalidSecretKey_decrypt() {
        final AesCipherService aes = new AesCipherService();
        final Map<String, Key> keys = ImmutableMap.<String, Key>builder().put("a", aes.generateNewKey()).build();
        final EncryptionService service = new EncryptionServiceImpl(aes, keys);
        service.decrypt(service.encrypt("data".getBytes(), "a"), "b");
    }

    @Test(expected = UnknownSecretKeyException.class)
    public void testInvalidSecretKey_decryption() {
        final AesCipherService aes = new AesCipherService();
        final Map<String, Key> keys = ImmutableMap.<String, Key>builder().put("a", aes.generateNewKey()).build();
        final EncryptionService service = new EncryptionServiceImpl(aes, keys);
        service.decryption("b");
    }

    @Test(expected = EncryptionServiceException.class)
    public void testInvalidSecretKey_decrypt_with_wrong_key() {
        final AesCipherService aes = new AesCipherService();
        final Map<String, Key> keys = ImmutableMap.<String, Key>builder().put("a", aes.generateNewKey())
                .put("b", aes.generateNewKey()).build();
        final EncryptionService service = new EncryptionServiceImpl(aes, keys);
        service.decrypt(service.encrypt("data".getBytes(), "a"), "b");
    }

    @Test
    public void testStoringSecretKeys() throws IOException {
        final AesCipherService cipherService = new AesCipherService();
        cipherService.setKeySize(AESKeySizes.KEY_SIZE_256);

        final Key key = cipherService.generateNewKey();
        final byte[] keyBytes = SerializationUtils.serialize(key);
        final ByteString keyByteString = ByteString.copyFrom(keyBytes);

        final String keyName = "GLOBAL";
        final SecretKeys keys = SecretKeys.newBuilder().putAllKeys(ImmutableMap.of(keyName, keyByteString)).build();

        final EncryptionService service1 = new EncryptionServiceImpl(cipherService, toKeyMap(keys));

        final byte[] encryptedData = service1.encrypt("data".getBytes(), keyName);
        assertThat("data", is(new String(service1.decrypt(encryptedData, keyName))));

        final File secretKeysFile = new File("build/temp/secretKeys");
        secretKeysFile.getParentFile().mkdirs();
        try (final OutputStream os = new FileOutputStream(secretKeysFile)) {
            keys.writeTo(os);
        }

        final AesCipherService cipherService2 = new AesCipherService();
        cipherService2.setKeySize(AESKeySizes.KEY_SIZE_256);
        try (final InputStream is = new FileInputStream(secretKeysFile)) {
            final EncryptionService service2 = new EncryptionServiceImpl(cipherService2,
                    toKeyMap(SecretKeys.parseFrom(is)));
            assertThat("data", is(new String(service2.decrypt(encryptedData, keyName))));
        }
    }

}