mitm.common.security.KeyEncoderTest.java Source code

Java tutorial

Introduction

Here is the source code for mitm.common.security.KeyEncoderTest.java

Source

/*
 * Copyright (c) 2010-2011, Martijn Brinkers, Djigzo.
 * 
 * This file is part of Djigzo email encryption.
 *
 * Djigzo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License 
 * version 3, 19 November 2007 as published by the Free Software 
 * Foundation.
 *
 * Djigzo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public 
 * License along with Djigzo. If not, see <http://www.gnu.org/licenses/>
 *
 * Additional permission under GNU AGPL version 3 section 7
 * 
 * If you modify this Program, or any covered work, by linking or 
 * combining it with aspectjrt.jar, aspectjweaver.jar, tyrex-1.0.3.jar, 
 * freemarker.jar, dom4j.jar, mx4j-jmx.jar, mx4j-tools.jar, 
 * spice-classman-1.0.jar, spice-loggerstore-0.5.jar, spice-salt-0.8.jar, 
 * spice-xmlpolicy-1.0.jar, saaj-api-1.3.jar, saaj-impl-1.3.jar, 
 * wsdl4j-1.6.1.jar (or modified versions of these libraries), 
 * containing parts covered by the terms of Eclipse Public License, 
 * tyrex license, freemarker license, dom4j license, mx4j license,
 * Spice Software License, Common Development and Distribution License
 * (CDDL), Common Public License (CPL) the licensors of this Program grant 
 * you additional permission to convey the resulting work.
 */
package mitm.common.security;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.security.Key;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

import mitm.common.security.KeyEncoder.KeyWasEncryptedKeyEncoderException;
import mitm.common.security.crypto.Encryptor;
import mitm.common.security.crypto.impl.PasswordBasedEncryptor;
import mitm.common.util.MiscStringUtils;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.PropertyConfigurator;
import org.junit.BeforeClass;
import org.junit.Test;

public class KeyEncoderTest {
    private final static String ENCODED_PRIVATE_KEY = "308204bf020100300d06092a864886f70d0101010500048204a9308204a5"
            + "0201000282010100b7c0b5ac2250390fe9da9b800bdb0a1b7f21614d1e7c"
            + "5db67438a9d1f793c0cf0403a3523981f17885e145dbc0e4c927a184c024"
            + "6e7a79ae29f7ad4e1a36db1db567c793547b96a8275e93d37ad17006ca51"
            + "6f3ed4bfbff9883e2a351d8c5c76a24502344e8711e76843b3ba05f7a551"
            + "5287dba46b05033c7756b531512034845fc7ae350ebc720ed83e7df7ebd8"
            + "ade16b0d961c15277fd5802b724c3d9392a7e99d2d06bf55b5d2516152b1"
            + "d9c249561e3887f075e2bebe8e331cdc3fe5de60af36285e514b14163b34"
            + "af15e6bb48e6b232366f05d73ad261714854833305ba06f1430d5b0c8383"
            + "7c49c9408c8e4d674b9a9494a6b0dc66e0b4d2107d78f26f020301000102"
            + "82010100a857d3d8bca2f47420d1d74e6b0e2467668425496ad9935d5982"
            + "a40a29a062af05c573761c1b7126f2b89cb0a43ab61329c59de68294902f"
            + "c0611994092e22764840a8b5d05b5d7df67b8e40dc2f4e4bda44daff1c18"
            + "03ffcf12ecc636a8e5f905d6e51b18aa63fbb628f85a3fa74efc7ef8da7f"
            + "fa4fe054201cfee90ca2cd98be5ab0de6f631ac574433573a05f797a6c67"
            + "f5f2ebac8abe4acb64ea926971ec6055cd3fffee636146199932f6868fbe"
            + "e39eab7e93c97c930bc8a92c75714459c74d0dc44d6a33660aec06735fa1"
            + "65d18b3511e28a225b513865c881ceb7b968379119a54e4f92c37abfb110"
            + "f760a0e3bc1b6d57141a20877dbd46819686f4f902818100e9188525d800"
            + "37f73d4f3d90a330911820228c29f80a3a63fddb09df82766d6cfdb46bdd"
            + "d163b780246edda6a4e2ec5c65453740e6cd191702afc2178b13123031ae"
            + "fd384383825d8fa60024f9b78d9c9ff1bf6f53e49528e1aba515a91f8066"
            + "54cd9488092a8f730133340dcc402d0b2cea149a3a6fdb1702f1890462a8"
            + "8f6d02818100c9cef9be785397ffbda7df90d7e6bc1d5a607950c4323114"
            + "9636e0b6c0a5ebc281fd0027463cc858fb94f8084baa0f93f1f33f18c40d"
            + "8a47666b7190efff38f869229b8e84eea8fcd559b2349873d96e187b9933"
            + "35ae63034ec926c341eaede9ac696c4b6029969fbeb8194c9f2b44e2c831"
            + "bb7c3a07c1dd5cadbf81f9deb3cb02818073e7e96d63f6d7dd6cf3161df1"
            + "c7989e727c3b4e333482cc6dd2991a36f9447849bf895387671a3bf1e1de"
            + "fd9a47ec58155351a24821fc33e0f61c81307a8f34bfbfcfd2466002571b"
            + "b2e3a77f34b28a0b4e5e6eb13c9c9ef37832628ef2471a9b588e5f068fcf"
            + "3cd47fed865ee61a7fd019a59cfb29dbbb998f191ec1202811028181008e"
            + "753c1937a992f7e632b5fff2589fdc7caaf3988f16fb4c94096331bee6a1"
            + "79a9f725ff93765edb69a52c3df6e3b2a1763f86fffd8dad5a5fb362f4b4"
            + "664f1a146568b7ffa0d5cbbcf3d7778752e85eee8b79870bd2f174294e97"
            + "bd682fe608793be6458339786985e14182b42d803032afe0b07dea71f0c8"
            + "76a264a7358d6702818100b2a67f02d933b860a2675f616a8f163eea3ef9"
            + "d23bc29416fe8b02582635a56b3278af0d98a4a8d7367c1bf21cf06841b8"
            + "f5e7f53e08062d90355aa90c4ff4e07d3eb2a5d356a5b4617e2ff114db1c"
            + "3c429ffaa552264a670b24b12b372558997b8f1fbd6df41efac697c5c9f3"
            + "2571eef344416eb642818b3886a16ec45381a3";

    private final static String ENCODED_PUBLIC_KEY = "30820122300d06092a864886f70d01010105000382010f003082010a0282"
            + "010100b7c0b5ac2250390fe9da9b800bdb0a1b7f21614d1e7c5db67438a9"
            + "d1f793c0cf0403a3523981f17885e145dbc0e4c927a184c0246e7a79ae29"
            + "f7ad4e1a36db1db567c793547b96a8275e93d37ad17006ca516f3ed4bfbf"
            + "f9883e2a351d8c5c76a24502344e8711e76843b3ba05f7a5515287dba46b"
            + "05033c7756b531512034845fc7ae350ebc720ed83e7df7ebd8ade16b0d96"
            + "1c15277fd5802b724c3d9392a7e99d2d06bf55b5d2516152b1d9c249561e"
            + "3887f075e2bebe8e331cdc3fe5de60af36285e514b14163b34af15e6bb48"
            + "e6b232366f05d73ad261714854833305ba06f1430d5b0c83837c49c9408c"
            + "8e4d674b9a9494a6b0dc66e0b4d2107d78f26f0203010001";

    private final static String BASE64_ENCODED_PUBLIC_KEY = "rO0ABXcEAAAAAXQAA1JTQXQABVguNTA5fnIAJ21pdG0uY29tbW9uLnNlY3VyaXR5LktleUVuY29k"
            + "ZXIkS2V5VHlwZQAAAAAAAAAAEgAAeHIADmphdmEubGFuZy5FbnVtAAAAAAAAAAASAAB4cHQABlBV"
            + "QkxJQ3cBAXVyAAJbQqzzF/gGCFTgAgAAeHAAAAFUlklfx6SWxIkAAAAQqlTT5UeRQPc+wjW7QyKz"
            + "/AAACAAAAAEwlrGiAHd1Z70QrtL6i5Y4bTEKTP6x5DVhG4uLtXBiv4Z2ixvCDlLbjEgGPzM+RTYs"
            + "c0mrNKGIVHYTQhyhJONdgUE/TbpU72K10EEo+73Y6zEvxg0gvzfhXf9c8jase0AesuWxvq8N52OJ"
            + "Cb6y95OSzc8PQau0+I7reqAsoFBSWc1CXGBAFZswNw60Z4zkYLQAflyQ/H18/7L/o83WVkiIj6mf"
            + "QWLP8ve3CfUbZHG6jQ8b666kQy50j1dJ8bS1EMVdco+YBCc7PHpDJ3uaghiDMLgy+ABagFMxYX9s"
            + "H56SgMU5ItIEzCVRFMfEE7VsfdlyGqHsJ+pTT2jvPQyvKtbrQnHzbn5GhwvNS1jxShWJvmzr7ANz"
            + "VTqU9JE2eHioRmDa/sX4i9kqSDMf6GbdKnLluA==";

    private static SecurityFactory securityFactory;
    private static KeyFactory keyFactory;
    private static Encryptor encryptor;
    private static PublicKey publicKey;
    private static PrivateKey privateKey;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        PropertyConfigurator.configure("conf/log4j.properties");

        securityFactory = SecurityFactoryFactory.getSecurityFactory();

        keyFactory = securityFactory.createKeyFactory("RSA");

        publicKey = decodePublicKey(ENCODED_PUBLIC_KEY);
        privateKey = decodePrivateKey(ENCODED_PRIVATE_KEY);

        encryptor = new PasswordBasedEncryptor("test");
    }

    private static PrivateKey decodePrivateKey(String encoded) throws DecoderException, InvalidKeySpecException {
        byte[] rawKey = Hex.decodeHex(encoded.toCharArray());

        KeySpec keySpec = new PKCS8EncodedKeySpec(rawKey);

        return keyFactory.generatePrivate(keySpec);
    }

    private static PublicKey decodePublicKey(String encoded) throws DecoderException, InvalidKeySpecException {
        byte[] rawKey = Hex.decodeHex(encoded.toCharArray());

        KeySpec keySpec = new X509EncodedKeySpec(rawKey);

        return keyFactory.generatePublic(keySpec);
    }

    @Test
    public void testSerializePublicKey() throws Exception {
        byte[] serialized = KeyEncoder.encode(publicKey, encryptor);

        assertNotNull(serialized);

        Key key = KeyEncoder.decode(serialized, encryptor);

        assertEquals(publicKey, key);
    }

    @Test
    public void testSerializePublicKeyNoEncrypt() throws Exception {
        byte[] serialized = KeyEncoder.encode(publicKey);

        assertNotNull(serialized);

        Key key = KeyEncoder.decode(serialized);

        assertEquals(publicKey, key);
    }

    @Test(expected = KeyWasEncryptedKeyEncoderException.class)
    public void testDeserializeKeyMissingPassword() throws Exception {
        byte[] serialized = KeyEncoder.encode(publicKey, encryptor);

        assertNotNull(serialized);

        KeyEncoder.decode(serialized);
    }

    @Test
    public void testSerializePrivateKey() throws Exception {
        byte[] serialized = KeyEncoder.encode(privateKey, encryptor);

        assertNotNull(serialized);

        Key key = KeyEncoder.decode(serialized, encryptor);

        assertEquals(privateKey, key);
    }

    @Test
    public void testSerializeSecretKey() throws Exception {
        PBEKeySpec keySpec = new PBEKeySpec("test".toCharArray(), new byte[] { 1 }, 1);

        SecretKeyFactory secretKeyFactory = securityFactory
                .createSecretKeyFactory("PBEWITHSHA256AND128BITAES-CBC-BC");

        Key secretKey = secretKeyFactory.generateSecret(keySpec);

        byte[] serialized = KeyEncoder.encode(secretKey, encryptor);

        assertNotNull(serialized);

        Key key = KeyEncoder.decode(serialized, encryptor);

        assertTrue(key instanceof SecretKey);

        assertTrue(ArrayUtils.isEquals(secretKey.getEncoded(), key.getEncoded()));
    }

    @Test
    public void testDeSerializePublicKey() throws Exception {
        Key key = KeyEncoder.decode(Base64.decodeBase64(MiscStringUtils.toAsciiBytes(BASE64_ENCODED_PUBLIC_KEY)),
                encryptor);

        assertTrue(key instanceof PublicKey);

        assertTrue(ArrayUtils.isEquals(publicKey.getEncoded(), key.getEncoded()));
    }
}