package be.iminds.ilabt.jfed.util;

import org.testng.Assert;
import org.testng.annotations.Test;

import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

/**
 * KeyUtilTest
 */
public class KeyUtilTest {
    @Test
    public void testPKCS12() throws Exception {
        //create Random key
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048);
        KeyPair keyPair = generator.genKeyPair();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();

        Assert.assertTrue(rsaPrivateKey instanceof RSAPrivateCrtKey);
        RSAPrivateCrtKey rsaPrivateCrtKey = (RSAPrivateCrtKey) rsaPrivateKey;

        //Create self-singed cert
        X509Certificate cert = KeyUtil.makeSelfSigned(keyPair, "test", 1);
        Assert.assertNotNull(cert);

        char[] keyStorePass = "testpass".toCharArray();
        KeyStore keyStore = KeyStore.getInstance("jks");
        keyStore.load(null/*inputstream*/, null/*pass*/);
        Certificate[] chain = {cert};
        keyStore.setKeyEntry("test", keyPair.getPrivate(), keyStorePass/*pass*/, chain);

        byte[] pkcs12 = KeyUtil.keyStoreToPKCS12Bytes(keyStore, "testpass", "testpass2");

        KeyStore keyStore2 = KeyUtil.pkcs12BytesToKeyStore(pkcs12, "testpass", "testpass2");

        Enumeration eAliases = keyStore2.aliases();
        Assert.assertTrue(eAliases.hasMoreElements());
        Assert.assertEquals(eAliases.nextElement(), "test");
        Assert.assertFalse(eAliases.hasMoreElements());

        Key key2 = keyStore2.getKey("test", "testpass".toCharArray());
        Certificate[] chain2 = keyStore2.getCertificateChain("test");
        Assert.assertEquals(chain2.length, 1);
        Assert.assertEquals(chain2[0], cert);
        Assert.assertEquals(keyPair.getPrivate(), key2);
    }


    //handy code to convert a local PEM file to PK12.
//    @Test
//    public void testPKCS12Removeme() throws Exception {
//        File pemFile = new File("infile.pem");
//        File pkcs12File = new File("outfile.p12");
//
//        String pem = IOUtils.fileToString(pemFile);
//        List<X509Certificate> certs = KeyUtil.pemToX509CertificateChain(pem);
//        Certificate[] chain = new Certificate[certs.size()];
//        for (int i = 0; i < certs.size(); i++) chain[i] = certs.get(i);
//        PrivateKey key = KeyUtil.pemToAnyPrivateKey(pem, null/*pass*/);
//
//        char[] keyStorePass = "testpass".toCharArray();
//        KeyStore keyStore = KeyStore.getInstance("jks");
//        keyStore.load(null/*inputstream*/, null/*pass*/);
//        keyStore.setKeyEntry("test", key, keyStorePass/*pass*/, chain);
//
//        byte[] pkcs12 = KeyUtil.keyStoreToPKCS12Bytes(keyStore, "testpass", "testpass2");
//        IOUtils.byteArrayToFile(pkcs12File, pkcs12);
//    }


    @Test(description = "Test converting between RsaPrivateKey and PEM \"RSA PRIVATE KEY\"")
    public void testRsaPrivateKeyPEM() throws NoSuchAlgorithmException, KeyUtil.PEMDecodingException {
        //create Random key
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048);
        KeyPair keyPair = generator.genKeyPair();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();

        Assert.assertTrue(rsaPrivateKey instanceof RSAPrivateCrtKey);
        RSAPrivateCrtKey rsaPrivateCrtKey = (RSAPrivateCrtKey) rsaPrivateKey;

        //convert to PEM "RSA PRIVATE KEY"
        String pem = new String(KeyUtil.rsaPrivateKeyToPem(rsaPrivateCrtKey));
        System.out.println("pem=" + pem);

        Assert.assertTrue(pem.startsWith("-----BEGIN RSA PRIVATE KEY-----"));
        Assert.assertTrue(pem.trim().endsWith("-----END RSA PRIVATE KEY-----"));

        //convert back to PrivateKey   (should be RSAPrivateCrtKey: data is lost in other classes)
        RSAPrivateKey recreatedRsaPrivateKey = KeyUtil.pemToRsaPrivateKey(pem, null);

        Assert.assertEquals(recreatedRsaPrivateKey.getPrivateExponent(), rsaPrivateCrtKey.getPrivateExponent());
        Assert.assertEquals(recreatedRsaPrivateKey.getModulus(), rsaPrivateCrtKey.getModulus());

        System.out.print("recreatedRsaPrivateKey class=" + recreatedRsaPrivateKey.getClass().getName());

        Assert.assertTrue(recreatedRsaPrivateKey instanceof RSAPrivateCrtKey);
        RSAPrivateCrtKey recreatedRsaPrivateCrtKey = (RSAPrivateCrtKey) recreatedRsaPrivateKey;
        Assert.assertEquals(recreatedRsaPrivateCrtKey.getCrtCoefficient(), rsaPrivateCrtKey.getCrtCoefficient());
        Assert.assertEquals(recreatedRsaPrivateCrtKey.getPrimeExponentP(), rsaPrivateCrtKey.getPrimeExponentP());
        Assert.assertEquals(recreatedRsaPrivateCrtKey.getPrimeExponentQ(), rsaPrivateCrtKey.getPrimeExponentQ());
        Assert.assertEquals(recreatedRsaPrivateCrtKey.getPrimeP(), rsaPrivateCrtKey.getPrimeP());
        Assert.assertEquals(recreatedRsaPrivateCrtKey.getPrimeQ(), rsaPrivateCrtKey.getPrimeQ());
        Assert.assertEquals(recreatedRsaPrivateCrtKey.getPublicExponent(), rsaPrivateCrtKey.getPublicExponent());
    }

    @Test(description = "Test method to check if keys match")
    public void testMatchingKeys() throws NoSuchAlgorithmException, KeyUtil.PEMDecodingException {
        //create Random key
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048);
        KeyPair keyPair = generator.genKeyPair();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();

        Assert.assertTrue(KeyUtil.matchingKeys(rsaPublicKey, rsaPrivateKey));

        //create Random key 2
        KeyPairGenerator generator2 = KeyPairGenerator.getInstance("RSA");
        generator2.initialize(2048);
        KeyPair keyPair2 = generator2.genKeyPair();
        RSAPrivateKey rsaPrivateKey2 = (RSAPrivateKey) keyPair2.getPrivate();
        RSAPublicKey rsaPublicKey2 = (RSAPublicKey) keyPair2.getPublic();

        Assert.assertTrue(KeyUtil.matchingKeys(rsaPublicKey2, rsaPrivateKey2));


        Assert.assertFalse(KeyUtil.matchingKeys(rsaPublicKey2, rsaPrivateKey));
        Assert.assertFalse(KeyUtil.matchingKeys(rsaPublicKey, rsaPrivateKey2));
    }

    @Test(description = "Test if storing and restoring PEM private keys with password works")
    public void testPemPassword() throws NoSuchAlgorithmException, KeyUtil.PEMDecodingException {
        //create Random key
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048);
        KeyPair keyPair = generator.genKeyPair();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();

        //first to and from PEM without password
        char[] pemKey = KeyUtil.privateKeyToAnyPem(rsaPrivateKey);
        String pemKeyString = new String(pemKey);
        Assert.assertFalse(KeyUtil.isPemPrivateKeyEncrypted(pemKeyString));

        RSAPrivateKey restoredRsaPrivateKey = KeyUtil.pemToRsaPrivateKey(pemKeyString, null);

        Assert.assertEquals(restoredRsaPrivateKey, rsaPrivateKey);

        //check lines lengths
        String[] pemKeyLines = pemKeyString.split("\n");
        Assert.assertEquals(pemKeyLines[1].length(), 64, pemKeyString);
        Assert.assertEquals(pemKeyLines[2].length(), 64, pemKeyString);
        Assert.assertEquals(pemKeyLines[3].length(), 64, pemKeyString);

        //then try the same with password
        String passwordString = "justAtest";

        pemKey = KeyUtil.privateKeyToAnyPem(rsaPrivateKey, passwordString.toCharArray());
        pemKeyString = new String(pemKey);
        System.out.println("Generated encrypted PEM: "+pemKeyString);
        Assert.assertTrue(KeyUtil.isPemPrivateKeyEncrypted(pemKeyString));

        restoredRsaPrivateKey = KeyUtil.pemToRsaPrivateKey(pemKeyString, passwordString.toCharArray());

        Assert.assertEquals(restoredRsaPrivateKey, rsaPrivateKey);

        //check lines lengths
        pemKeyLines = pemKeyString.split("\n");
        Assert.assertEquals(pemKeyLines[4].length(), 64, pemKeyString);
        Assert.assertEquals(pemKeyLines[5].length(), 64, pemKeyString);
        Assert.assertEquals(pemKeyLines[6].length(), 64, pemKeyString);
    }

    @Test
    public void wrapTest() {
        String a = "abcdefghijklmnopqrstuvwxyz";

        for (int i = 2; i < 15; i++) {
            String w = TextUtil.wrap(a, i);
            String[] s = w.split("\n");
            boolean hasPartial = a.length() % i > 0;
            int fulllines = Math.floorDiv(a.length(), i);
            int totallines = fulllines + (hasPartial? 1 : 0);

            Assert.assertEquals(s.length, totallines, "Expected string of length "+a.length()+" wrapped to "+i+" to be split into "+totallines+" parts. wrapped string=\""+w+"\"");
            for (int j = 0; j < fulllines; j++)
                Assert.assertEquals(s[j].length(), i, "Expected string of length "+a.length()+" wrapped to "+i+" to be split into "+fulllines+" parts of "+i+" but part "+j+" has length "+s[j].length());
            if (hasPartial)
                Assert.assertEquals(s[fulllines].length(), a.length() % i, "Expected string of length "+a.length()+" wrapped to "+i+" to be split into "+fulllines+" parts with the last part having length "+(a.length() % i));
        }


        String b = "abcdefghijkl\nmnopqrstuvwxyz";
        for (int i = 2; i < 15; i++) {
            String w = TextUtil.wrap(a, i);
            String[] s = w.split("\n");
            for (int j = 0; j < s.length; j++) {
                String line = s[j];
                Assert.assertTrue(line.length() <= i);
            }
        }
    }

    @Test(description = "Test hexToByteArray converting String of hex chars to byte array, and back")
    public void testBigIntHexConversion() {
        List<String> examples = new ArrayList<String>();
        examples.add("0F770FF6FE8576B7");
        examples.add("9848D06D94A23648");
        examples.add("7B8D82583EFFE7F0");

        for (String example : examples) {
            System.out.println("Testing HEX String conversion on: \"" + example + "\" length=" + example.length());
            Assert.assertEquals(example.length() % 2, 0);

//            byte[] bytes = new BigInteger(example, 16).toByteArray();
            byte[] bytes = KeyUtil.hexToByteArray(example);
            Assert.assertEquals(example.length() / 2, bytes.length);

            String reconstructed = "";
            for (int i = 0; i < bytes.length; i++)
                reconstructed += String.format("%02X", bytes[i]);
            Assert.assertEquals(example, reconstructed);
        }
    }

    @Test(description = "Test reading PEM \"RSA PRIVATE KEY\" with encrypted key", dependsOnMethods = {
            "testBigIntHexConversion", "testRsaPrivateKeyPEM"})
    public void testReadEncryptedRsaPrivateKeyPEM() throws NoSuchAlgorithmException, KeyUtil.PEMDecodingException {
        //currently bugged, so we need a test!

        //TODO encrypted test create key(s) with openssl (same key encoded and decoded), read them here and compare them.

        {
            RSAPrivateKey privateKeyWithPass =
                    KeyUtil.pemToRsaPrivateKey(openSshPrivateRsaKeyPem, openSshPrivateRsaKeyPassword.toCharArray());
            Assert.assertTrue(privateKeyWithPass instanceof RSAPrivateCrtKey);
            RSAPrivateCrtKey rsaPrivateCrtKeyWithPass = (RSAPrivateCrtKey) privateKeyWithPass;

            RSAPrivateKey privateKeyNoPass = KeyUtil.pemToRsaPrivateKey(openSshPrivateRsaKeyPemNoPassword, null);
            Assert.assertTrue(privateKeyNoPass instanceof RSAPrivateCrtKey);
            RSAPrivateCrtKey rsaPrivateCrtKeyNoPass = (RSAPrivateCrtKey) privateKeyNoPass;

            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getCrtCoefficient(), rsaPrivateCrtKeyNoPass.getCrtCoefficient());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeExponentP(), rsaPrivateCrtKeyNoPass.getPrimeExponentP());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeExponentQ(), rsaPrivateCrtKeyNoPass.getPrimeExponentQ());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeP(), rsaPrivateCrtKeyNoPass.getPrimeP());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeQ(), rsaPrivateCrtKeyNoPass.getPrimeQ());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPublicExponent(), rsaPrivateCrtKeyNoPass.getPublicExponent());

            RSAPublicKey pubKey = KeyUtil.openSshAuthorizedKeysFormatRsaPublicKey(openSshPublicRsaKeyPem);
            Assert.assertEquals(pubKey.getModulus(), rsaPrivateCrtKeyNoPass.getModulus());
            Assert.assertEquals(pubKey.getPublicExponent(), rsaPrivateCrtKeyNoPass.getPublicExponent());
        }

        {
            RSAPrivateKey privateKeyWithPass =
                    KeyUtil.pemToRsaPrivateKey(openSslPrivateRsaKeyPem, openSslPrivateRsaKeyPassword.toCharArray());
            Assert.assertTrue(privateKeyWithPass instanceof RSAPrivateCrtKey);
            RSAPrivateCrtKey rsaPrivateCrtKeyWithPass = (RSAPrivateCrtKey) privateKeyWithPass;

            RSAPrivateKey privateKeyNoPass = KeyUtil.pemToRsaPrivateKey(openSslPrivateRsaKeyPemNoPassword, null);
            Assert.assertTrue(privateKeyNoPass instanceof RSAPrivateCrtKey);
            RSAPrivateCrtKey rsaPrivateCrtKeyNoPass = (RSAPrivateCrtKey) privateKeyNoPass;

            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getCrtCoefficient(), rsaPrivateCrtKeyNoPass.getCrtCoefficient());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeExponentP(), rsaPrivateCrtKeyNoPass.getPrimeExponentP());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeExponentQ(), rsaPrivateCrtKeyNoPass.getPrimeExponentQ());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeP(), rsaPrivateCrtKeyNoPass.getPrimeP());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeQ(), rsaPrivateCrtKeyNoPass.getPrimeQ());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPublicExponent(), rsaPrivateCrtKeyNoPass.getPublicExponent());

            //TODO: implement reading of PEM public key
//            RSAPublicKey pubKey = KeyUtil.pemToPublicKey(openSslPublicRsaKeyPem);
//            Assert.assertEquals(pubKey.getModulus(), rsaPrivateCrtKeyNoPass.getModulus());
//            Assert.assertEquals(pubKey.getPublicExponent(), rsaPrivateCrtKeyNoPass.getPublicExponent());
        }

        {
            RSAPrivateKey privateKeyWithPass =
                    KeyUtil.pemToRsaPrivateKey(openSslPrivateRsaKeyPem2, openSslPrivateRsaKeyPassword2.toCharArray());
            Assert.assertTrue(privateKeyWithPass instanceof RSAPrivateCrtKey);
            RSAPrivateCrtKey rsaPrivateCrtKeyWithPass = (RSAPrivateCrtKey) privateKeyWithPass;

            RSAPrivateKey privateKeyNoPass = KeyUtil.pemToRsaPrivateKey(openSslPrivateRsaKeyPemNoPassword2, null);
            Assert.assertTrue(privateKeyNoPass instanceof RSAPrivateCrtKey);
            RSAPrivateCrtKey rsaPrivateCrtKeyNoPass = (RSAPrivateCrtKey) privateKeyNoPass;

            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getCrtCoefficient(), rsaPrivateCrtKeyNoPass.getCrtCoefficient());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeExponentP(), rsaPrivateCrtKeyNoPass.getPrimeExponentP());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeExponentQ(), rsaPrivateCrtKeyNoPass.getPrimeExponentQ());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeP(), rsaPrivateCrtKeyNoPass.getPrimeP());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPrimeQ(), rsaPrivateCrtKeyNoPass.getPrimeQ());
            Assert.assertEquals(rsaPrivateCrtKeyWithPass.getPublicExponent(), rsaPrivateCrtKeyNoPass.getPublicExponent());

            //TODO: implement reading of PEM public key
//            RSAPublicKey pubKey = KeyUtil.pemToPublicKey(openSslPublicRsaKeyPem2);
//            Assert.assertEquals(pubKey.getModulus(), rsaPrivateCrtKeyNoPass.getModulus());
//            Assert.assertEquals(pubKey.getPublicExponent(), rsaPrivateCrtKeyNoPass.getPublicExponent());
        }
    }

    @Test
    public void testPrivateKey() throws KeyUtil.PEMDecodingException {
        //test keys beginning with "BEGIN PRIVATE KEY"
//        PublicKey pub = KeyUtil.pemToPublicKey(openSslPrivateKeyPemNoPassPubKey, null);

        PrivateKey pk = KeyUtil.pemToAnyPrivateKey(openSslPrivateKeyPemNoPass, null);
        assertThat(pk, instanceOf(RSAPrivateKey.class));
        PublicKey publicKey = KeyUtil.rsaPrivateKeyToRsaPublicKey((RSAPrivateKey)pk);

        assertThat(publicKey, is(notNullValue()));

        PrivateKey rsaPk = KeyUtil.pemToRsaPrivateKey(openSslPrivateKeyPemNoPass, null);
        KeyPair pair = KeyUtil.pemToRsaKeyPair(openSslPrivateKeyPemNoPass, null);
        assertThat(pair, is(nullValue()));
        assertThat(rsaPk, is(nullValue()));
    }

    @Test
    public void testDerLength() {
        for (int i = 0; i < 127; i++) {
            List<Byte> len = KeyUtil.derLength(i);
            assertThat("bad len encoding for "+i, len, hasSize(1));
            assertThat("bad len encoding for "+i, len.get(0), is((byte) i));
            assertThat("bad len encoding for "+i, len.get(0) & 0x80, is(0));
        }
        for (int i = 128; i < 255; i++) {
            List<Byte> len = KeyUtil.derLength(i);
            assertThat("bad len encoding for "+i, len, hasSize(2));
            assertThat("bad len encoding for "+i, len.get(0) & 0x80, is(0x80));
            assertThat("bad len encoding for "+i, len.get(0) & 0x7F, is(1));
            assertThat("bad len encoding for "+i, len.get(1), is((byte)i));
        }
        for (int i = 256; i < 2048; i++) {
            List<Byte> len = KeyUtil.derLength(i);
            assertThat("bad len encoding for "+i, len, hasSize(3));
            assertThat("bad len encoding for "+i, len.get(0) & 0x80, is(0x80));
            assertThat("bad len encoding for "+i, len.get(0) & 0x7F, is(2));
            int high = Byte.toUnsignedInt(len.get(1));
            int low = Byte.toUnsignedInt(len.get(2));
            assertThat("bad len encoding for "+i+"  high="+
                    high+" ("+String.format("%02x", high)+")"+"  low="+
                    low+" ("+String.format("%02x", low)+")", (high << 8) | low, is(i));
        }
    }

    //only strings used in the tests here

    /*
     * keypair generated with
     *  ssh-keygen -t rsa
     *
     *  openssl rsa < /home/wim/debug_openssh_private_rsa_key > /home/wim/debug_NOPASS_openssh_private_rsa_key
     */
    private static final String openSshPrivateRsaKeyPemNoPassword = "-----BEGIN RSA PRIVATE KEY-----\n" +
            "MIIEoQIBAAKCAQEAvE+tykIsQMlqiCy569sG0EeKKzWwF4sm8TAIpoQctr4/a7SW\n" +
            "AcoTw24UiQPSA+VK71XvVcovPfbn3YWavag8YWl81VUvWWmM+IOwZwMIacC9P55p\n" +
            "LdipvAQ06wQNDFeFySW7Qaq07/hWxukDf5FrE89eSJuFE6/DsyKPOsZ1BTBRMJ4E\n" +
            "4Ltg7wfqAXQ/bl+bIj7aedb0JcL9TJbS54RHFuhDelUu0596Xm1rN5N2XgGO9IZj\n" +
            "y3jYI18E9qfov2JqEScINEWEkSEXSSwHbQubBEl6lGv+jLfVQk0z2XAcJ4kvE4Y1\n" +
            "U71e7EMFeYfUj5xawGGMSxUBfIKdWc6rqZ11MwIBIwKCAQBF8bWURHbWPC7iHz2+\n" +
            "AOVGC/F9w3vrfNPzLxkn5+1ocoyVuBp1sXUOEvGvO+7rgQ00Ux5hsX9C5q3kkLXR\n" +
            "al+R5VpAm/uk3g/KBQcBsKtaesnzDvPd1CHJfefFAYEweEeie7qUu7+MVO0IDWez\n" +
            "CiB1EoIa9++ZmQ4sl87MsBzWCf59yjbZdvVQt/u2WGyBux+jLhqPIkEvjxAtEUZF\n" +
            "rUa2ynGGSqeE6zyAwMioQtM4OA1Bsdkq5wdmMv3yjweubkaUjxLFwbx38XbOLbjP\n" +
            "jXscgSIjI7KmW5yP0Uab3QPk56+MnpEP3qQHr9T5xYhoktAagn2gpjBzqMiCeeys\n" +
            "uAeDAoGBAOc5iiX/+kt1e0Q2254yiFVzn+ytoTQT26Vhz9zbUukocqE0+gaNuVVq\n" +
            "VkUDX1E5euxR7FP/QAGUj7xmHIMl6KCpJinvnJDo7O1zVJ0bzJIthaevSFqiTEcj\n" +
            "k0bJhhvbIY86TLyDKBgeWe11CjCn373K5N5PK2AyWbZzvWGeajAPAoGBANB9ByPS\n" +
            "WW1Rdexpgy5UuBfjmPUPxdV+KxishMKzEBWzj6u0ase4p+SFwVi99mKg3AjKWMcd\n" +
            "o3PeHpzcHgImUOP/a/p/AdDbbv2qvseE6YJO8gDVTWB5TYYlXxtE5bq8vMc3P8rg\n" +
            "7xcH/AIBkTSmzuLVf9Ho7x7XsUE4BBucpkSdAoGBAJfynJyg5k7YLG6ntORNF8Mg\n" +
            "GKLYf+Bk0irZ4F3vNnv2Ai9r9MJ6Y9kLXUNLW+TrQiZEdrra74wCilc7yZgC9/SM\n" +
            "aYlFsAd0fnAnN5pxWovyB1+QcWAhgpUmAbIsqJX2ZoKxSF6fVNymOxhi2s+EQpKp\n" +
            "5ts7VwSzX4aGkmS4juxhAoGAF9PGTTycgYWnE7RJgaNIPT6VI1JCfsyXNgUWfKbA\n" +
            "Anrr2Rvu8kD9PrAzWpld/KSrbrgKJWJ5FI5p5gqHFjBDwkkTp5l8jOXgzIiK1Pk/\n" +
            "QhemoQJvPjm/t48+Eb67K0jFHhTxWQPDjZqDM23ktY9oGeyDovYMsxFWFhUHyKQw\n" +
            "QlsCgYBN3pQzCwBGhXeLOJDEjZxlPaVsQg60IPqQVFAWr60RN2u16b9QwSdDu2ZV\n" +
            "E/Cr7vr05tTBdwLn8cCNlwbKtK6LsxgAkZ+1qz5a21ImXt31xiC+tsYTDt21Vbs7\n" +
            "u9+v9lPloQRKVTC53xFFfVHWrqslesQxd8jIQpGugnWEC2Jqpw==\n" +
            "-----END RSA PRIVATE KEY-----";
    private static final String openSshPrivateRsaKeyPem = "-----BEGIN RSA PRIVATE KEY-----\n" +
            "Proc-Type: 4,ENCRYPTED\n" +
            "DEK-Info: DES-EDE3-CBC,0F770FF6FE8576B7\n" +
            "\n" +
            "s6c6pniuAR+pg4li8baRuXHgnHSLiDqq93/mdZBcdbk7GFNrQ+5/5jtbEiKUzXk2\n" +
            "lBy7mVKL3cqPIrRsh/pflxsn/Ub46WLoYMn75mvT7LjKr4joamSOxUjCgPjkA6zK\n" +
            "+epPsa2N7Weeq1Us909l2HUKjdpHvClA7j1zmZVJFKiFRfVFDpbkkdaSu/GCUcBY\n" +
            "jEUclikU+QhoUFrrRB+WAZUWUOYygY/bM73Is+Kx7xnVe0iN19Syk/6AK5MD7zBS\n" +
            "wsOVvBO4T9SBsx5wToFaPLAv+ucOGzidMihS+mtISRCdiOzYcIgLlfdeKek/t/QS\n" +
            "aeg/Ikq1qxLc9rUAFiX6sVqIGlFD43e61KJDzoaH7BDRRcQ9vqv7mtL7xGp/Gt4O\n" +
            "5k75rNYUDr9DIkq0ipBz+P7xJtFglmKzwu2yRWHWau1KpjXhTiD7u4SnB66teXKS\n" +
            "68PCR0hIDRkry5Pwm67n8Zw2JSbr0W4yifX381ZJK8td+dFNIewUaIS2fg5DGJRf\n" +
            "s1eXxSGiaXI4uwTPtT+lMu44BixLVVcMZUT8mip+KCcBhz8MaxRYH0edczkxXg19\n" +
            "00lPxawI/GGEy+jS7tCoVNa6DJa9gYlzCCKw9bF31ayROh5yTrMEANPTISS/P6d/\n" +
            "poOeOSvqiknJUnR+53HUmqfCppUvnSuyV1T562Z/g9At1HuG2Ayh61OOwhwDqYO6\n" +
            "l2pX1M43T/XQK3ncUtZr2NQMq21P1THdDSLtHqeLMLIqryrJamu8/D2AD9xDgnRB                                                                                                                              \n" +
            "5hIGTT9/VOE+iHvMTtVozz5rla9wmwm4aPqouo7eIBoHirTIZmWdHJSI21LQOZmK                                                                                                                              \n" +
            "2UroZZoC5P8bOBjKgiKgrXzXOwF1b2+7/muyLCLs4ZstPhnzxxWxSJxVkTO5aQ1v                                                                                                                              \n" +
            "RBBCczgeBMgMfHhwSE3IaCk1cXFSUvZxKODRUf3tyE5IPSW8m0Q4/zJgZz0x2NLW                                                                                                                              \n" +
            "IJHrg5cdpUvb6LOzLCBZtNho+DbNiacwafAERqRMcaKMCUByKkmcnXkF5g2roj14                                                                                                                              \n" +
            "B9XWhky1ugQ+P6qo+4fmPqHZ3vpXEIeQ1WNHDgKg7oegfdmGbFRvtFm2T7zkrWW+                                                                                                                              \n" +
            "/JlIXudJCkERdD90qYGokJZTwQQQI1qLspMzIz3wx8uLRf1GZ7KhZhTvg0A55Pvn                                                                                                                              \n" +
            "kum/5PtE19GW/uISVHgDc0HE0+rRSmxj4Y+GB6Y8wQeXxulRdFUYk8UkxvHHSij+                                                                                                                              \n" +
            "OekYfQdnGowCWYbeEEWMGMOQl/C58kZdYeWycI1WRRfXgJXYKOYmUaCuqUBJM+pa\n" +
            "ADfaT0B5c2rgSsM0x1Dg0QccBmZg9T88wMPODGsBobN9r6SIjVAVqpxDiFuSdoO5\n" +
            "4AF4Gk/0STI0PbyJUJ09dHZbrugLgE2a04TD/ArGpn9yoR/AWa+QxEcZjSR4C4d3\n" +
            "LPp+GibWBfbV94LLA4MtSED/djSXDX0eps4JbhICBvIkSH5lOyZkGcgqaWSt6YGR\n" +
            "uMIGNgSfxhiVXywbs8BrcZUlrUoZpzWIbW96S3vqoYiPvQRuUrRcQsZ6vnvWh7VO\n" +
            "95qHax395RFsdz42Ynmw4RuDSNDbkkEJXS8Gdj0TEngjvQiC3WfSiw==\n" +
            "-----END RSA PRIVATE KEY-----";
    private static final String openSshPrivateRsaKeyPassword = "debug";
    private static final String openSshPublicRsaKeyPem =
            "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvE+tykIsQMlqiCy569sG0EeKKz" +
                    "WwF4sm8TAIpoQctr4/a7SWAcoTw24UiQPSA+VK71XvVcovPfbn3YWavag8YWl81VUvWWmM+IOwZwMIacC9P55pLdipvAQ06wQNDFeFySW7Qa" +
                    "q07/hWxukDf5FrE89eSJuFE6/DsyKPOsZ1BTBRMJ4E4Ltg7wfqAXQ/bl+bIj7aedb0JcL9TJbS54RHFuhDelUu0596Xm1rN5N2XgGO9IZjy3j" +
                    "YI18E9qfov2JqEScINEWEkSEXSSwHbQubBEl6lGv+jLfVQk0z2XAcJ4kvE4Y1U71e7EMFeYfUj5xawGGMSxUBfIKdWc6rqZ11Mw== debug@test";


    /*
     * keypair generated with
     *       openssl genrsa -des3 -out debug_openssl_private_rsa_key 2048
     *       openssl rsa -in debug_openssl_private_rsa_key -pubout > debug_openssl_public_rsa_key
     *
     *       openssl rsa < debug_openssl_private_rsa_key > debug_NOPASS_openssl_private_rsa_key
     */
    private static final String openSslPrivateRsaKeyPemNoPassword = "-----BEGIN RSA PRIVATE KEY-----\n" +
            "MIIEpAIBAAKCAQEA3OU+ZUf6KrnKitek+TRF6jky0zVlmKkAzH4+bd40D1M8fliO\n" +
            "dMc/h5KTl0xnoCgZ4p1hHm3Q17AKJ8GZiuk4pwKdEc2F1jd8MBlv3Q1WxWdLzwqM\n" +
            "kO5MMi4LqsNDUSjqHk1CqOILWEN25UXoqF40i5oUCcq0P8M4xIZZeAXCi+OwQmiU\n" +
            "+5LZxiW02xWHpeTo20eJKjBsUoz/+7Ea9MIoWB87voQEmhbl+252G0T1/jtEPPeo\n" +
            "+gkfDysX0OxzCUsDl/Q70sSts6Ef4kR6xNS9QGWb7DCg0gygugbXez6Nmyq23FAM\n" +
            "JL8wDfKLCEwawINo0wx/S+IFP3TLmB174UBvvwIDAQABAoIBAQCJ8yBkX+77f8vd\n" +
            "qY59kweWnuH+xPoNvH2jN7QFKR+Z8oF05hkRFN237PH/KtgMTP7dZyuftTUXffjZ\n" +
            "my4ocj3PDvLIi3Fptnz4DOqvQgVOgpP1WMEwQaGUNO1UV11S8hpDkjxu+7vaA0fd\n" +
            "JyuE+lAWXsLk2pJ2v5RUJxL4waAde4qdn3zcRjVMmu9RDzI7FVh8q16w7Zyeh7su\n" +
            "fJ78H88EeJ10GS9TSr9eI/39P7xlH2tQsB3Lv31D2+W7l+2X82UyTY99rPfV6IqQ\n" +
            "KaGsTahCUgjus0RuhCURHplAOuugOe2KlE9TJhTuyK3cvufulfTfNX0wuyeLq/EW\n" +
            "0mtx5AoBAoGBAP0v5F5K4ahrCC4bDwgDMHHHKHSHb9shHAEk50Efz5b6qBwWi+i6\n" +
            "XCIWf2c1kDUwStHsGXQh3iN7TyuM2GQoQImhce27A/cGDTsUPdmZ32uUbHRDSJox\n" +
            "i7LTtyS6Nn8g/dh5Yn8OiZ2tlZpUZekloeJTLer3uzfOGkZQeZUaUPRJAoGBAN9Z\n" +
            "gj8fj0GmrENsK06Ib+OmnJuQdgY1atR3kLjZ9YAf+DZk+bBP2qxrnjgfKkjhYW6c\n" +
            "wX5T4atLPr17iUrTn8+YHjc0ZbVCSqIyx0TCLjwntKGM6IG2RFwNhN//J2gtewsx\n" +
            "ekyW+d/oFYFhwVXy9oUqibxSMqj4vNFSbT6eaDPHAoGBAJu8ccRuWw+1hnqVulE7\n" +
            "ZPkXgBLtnCg13Xv2ryin4JEF7ZIZbEXjG/j7zbI2iFWvNtaZW67LhlBc8P3gzNoO\n" +
            "yGPgIqwQdQfleQ32DXVj6MHLskpxeJ8gCsYc5HJ6+DqKmJonUCbHUm7i7zrW3zji\n" +
            "JQmKEJyPdWGGLTNDHQZSAanBAoGAfqzTlF2f8IpJlYvaHBaB70nl9M1AQ1E0oACY\n" +
            "Ul88QEjhjGhEvVztF3GKMSZr4x4BFq1NiQqmKXLpyKoyOgBA2YrbSFAth1pr3gaS\n" +
            "wkqn0nJqnl2+2SK5LsR0Il8iyJFTAgwz4xCV9Ao7eEArWUYNz4VKzUaJeRBqdwYa\n" +
            "87MAQq0CgYAapNcmz2ytdsFLOHt7nYLB2ITIKFKNb/AajaVqU0soDQNHhfwOL8Mo\n" +
            "0NATc5AybDrn7NAGao/Je30Dm7k2wTJeKRUtoaF9u6NG+1K6LGeV+nvgAqjIJkNk\n" +
            "mGkDVhxwLM93s48e8wWAKgyusMV3V8sYKCZBSElWOEXW8n7qVKIGEA==\n" +
            "-----END RSA PRIVATE KEY-----";
    private static final String openSslPrivateRsaKeyPem = "-----BEGIN RSA PRIVATE KEY-----\n" +
            "Proc-Type: 4,ENCRYPTED\n" +
            "DEK-Info: DES-EDE3-CBC,7B8D82583EFFE7F0\n" +
            "\n" +
            "bsJetcGI3CkBYrAQszOZfsZdrz/7C5NCtIxu8vOCieeC3s/OGMplpnLNH0W/1oIY\n" +
            "Y/Y4X3iHO3Jbdj4t9++F0R0yoGQWdRe7EYuW5MQcBPnHGKG2Kh278NiuWD/eCCmk\n" +
            "VdSe9nZloTNaVHrBk1g4N2MauI91O7jxLVULK8Q7CiOaw90zwIurJusAL8Io9xNZ\n" +
            "RBQsmhSmFQCKXWW9mT26i4cCI/rxUC/XI8zkahBZTWVZn+TQJ4HPFyXLB1MT44x5\n" +
            "1ZVI1EBNhCrAllgDVOIuShb1rRcE911mJNNSJ83Ywpt2s+ou0WQbXeqACaPNpO0g\n" +
            "MJZXEh/lcb9u1IllCtsIQPX22gRFcn332cd5p3M8qdrTbDV9FMQFwdCpQ3puppg5\n" +
            "g4OOlg2G31UnBSGpsy7X8eApApnViUMz8Hor8uPsEtTNJIeRBvzOyu6YWGgYWkAf\n" +
            "LOsxpncD5leeFfRqY7najU/25dcwht9lhYw5nm/DhKIUQFXODDWtXZnhNvrFn84T\n" +
            "LNRTnsLMg2dEQXxNX8fYVpvWWyfLC8G/XvFy0OwslWah3r9276YmB7cSBU2S4xCm\n" +
            "yMWM5PJJCxIiQqzEer4ejbuYpvRFJteGIS62k9MpxsIZpm/uXhQMnA/J2fQI75/j\n" +
            "9GsXCHTeIAhbWGWISGvB9JqkmyMVq7pqV7A84YWQ2txcy6bzzZ6/YT2DLquXaVi+\n" +
            "tPLHrM/TdhVWmHpGfdYh3cIPfU90jLK8nix743VOKUK0S6l84WSwseJYt49b+z75\n" +
            "NrCP/oMrpywxPrKMkelvwCtF6uL7Mo7FEbpFFmxmSJvyI25r59dwyjYg1aMnsh/t\n" +
            "kj8YS9rdyfdEfeM2FYwuRigSsElR54p0DAZzbHTSGXKEeliJLKlks12iDEDIfNpq\n" +
            "/MesPAF5tNIaLBIAyAa1J43TcyYSa4l7+CtSnOPCC7X9JP0jQPrQiXM17VoSlBe4\n" +
            "/DhbAcr9yYU14zWJzFtODqW3RIpAbr2JyDLhnG2dWc0ASUL/C4rp/HakX9+6XmgI\n" +
            "XDZSdM6kNm5+HS7knundPsjeIodpdMRB3vqdjsveD/ESejiMkIefS1zSs8eRCVNj\n" +
            "fj//h8VBjq9rcH5yII566dlaHtSZxmDEdI75lYDkFw7xnCJWjxfU2I4CdtevlZ8y\n" +
            "MC3+Jt61etfVAkn2v/PhcDx64aZ56yRxh/SHGLpn4Opk11zEDFoEiAYbDoiVt+m+\n" +
            "UlrQU7XrzFKOhRNLQpW3Xx44366Bjb/MjfXzMayf5OkYLLwktYdx0KKARolsxNBK\n" +
            "DVi7ZbC+rHSKeEZYAUyixca0P1HjL7RSWCD97FV1HFVeaNC3kGHhJys3Tc3XBhwq\n" +
            "F0f0LQBU5r3J0qX0fUfc5RAW7Px0cx+9aj/R5ctYC0l6VBxyu+MsXdJe2YUhEYbh\n" +
            "NGyJPhnUyHiSgzSy+uKKu+hloO6fYYlTyCLOO6ChIUy6f4Wwr4Ewp5FcBtInNjmj\n" +
            "iYBeFuc6UtdQJc4GTLazJvSi5fql6tgLeXM27mirlS7niy3U27RASAYjNp1BJeMG\n" +
            "9Ba/ysutbdCP1qX5WLwnMArR8PcVRcGnldwGl8iCzXDzCFps0F51JacOA4oCkXU+\n" +
            "-----END RSA PRIVATE KEY-----";
    private static final String openSslPrivateRsaKeyPassword = "debug";
    private static final String openSslPublicRsaKeyPem = "-----BEGIN PUBLIC KEY-----\n" +
            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3OU+ZUf6KrnKitek+TRF\n" +
            "6jky0zVlmKkAzH4+bd40D1M8fliOdMc/h5KTl0xnoCgZ4p1hHm3Q17AKJ8GZiuk4\n" +
            "pwKdEc2F1jd8MBlv3Q1WxWdLzwqMkO5MMi4LqsNDUSjqHk1CqOILWEN25UXoqF40\n" +
            "i5oUCcq0P8M4xIZZeAXCi+OwQmiU+5LZxiW02xWHpeTo20eJKjBsUoz/+7Ea9MIo\n" +
            "WB87voQEmhbl+252G0T1/jtEPPeo+gkfDysX0OxzCUsDl/Q70sSts6Ef4kR6xNS9\n" +
            "QGWb7DCg0gygugbXez6Nmyq23FAMJL8wDfKLCEwawINo0wx/S+IFP3TLmB174UBv\n" +
            "vwIDAQAB\n" +
            "-----END PUBLIC KEY-----";


    /*
      keypair generated in same way with openSSL, but salt starts with 1 (binary)
    * */

    private static final String openSslPrivateRsaKeyPemNoPassword2 =
            "-----BEGIN RSA PRIVATE KEY-----                                                                                                                                                               \n" +
                    "MIIEpAIBAAKCAQEAmvguzaVQMz0MZT/QHxwY8RCAjEMIjaxzjf/soUNP90+0iPuR                                                                                                                              \n" +
                    "6jBeIhiQXmZaU6H86hKFG8AzKMvN5273saL212dYrYLXGNKCfH4/9KZu1FJzXwSu                                                                                                                              \n" +
                    "Uma/wb1X+GUwL5xp3rbcHwgcMv9AhdpJKLToVrupYKLMxBfWYCw02w5nJBiiSLlI                                                                                                                              \n" +
                    "lsN0XD0pskLlmrPw/w2da8DexTWqYIIuBCGHuNdzBI1ajgagxKpvKzDz3Te5GMnu                                                                                                                              \n" +
                    "rA3KvvfALVzl+gOGtOSut1ol3dCgoBh6f1IGZqoo3cQHOYHdhaAa7+lX0oLn/cSN\n" +
                    "3AeH9CqNgj2cpcdKPLRX78y8Ju5+q06wWYGv4wIDAQABAoIBAGgYSagNYV/ppAfm\n" +
                    "42/iOcbD5PVSmc5AhqZdwJ9aTb68JXLWOV9r+e9BPMiMTCRdbTv2EL9hTXwb2kWZ\n" +
                    "PnxuEQ0D+IckmkOsM8ZYL7GwkkXA1IqA5G+pYSlMfGj333Q7xsm5XwbhNb/zwW2o\n" +
                    "APh8/Iw2JkIpWQ5nTLLxPtfeRt3xOoRQzgO54j2XeET33MVSN8NMb9Bwdotvg94A\n" +
                    "WJvSVQNXmXGlHC/WGu81SybK6NRlaAz/WAxQ/+2s6eVL22u4+qT5UHq42isSAEW5\n" +
                    "vWaQbIrPBBUgFVx43knVy5DM+50woFWW+Wo5NWNPw3Pww9yYLWMnp3aPdK5RlzGE\n" +
                    "qwCOJLECgYEAyg4gZRiYhreuRSrOlWZAJXZTFI5BebBGsvc+VsfQhrOQpfforO5W\n" +
                    "4e4m2R/bZulmRxIqXj/y7dsrZ5Fec1eO+BtRgaJE15LZD0Y32aeuxBpUmiPyQ9+X\n" +
                    "8r7OZaFEi0xemAnvMPAQEagFl7IEoJCeEDSe8KlI/PM+ZAVerBH1l98CgYEAxFfj\n" +
                    "CwibUIFpjzdsfMoevwW+h3Dyt7en90w17VUqWc9jgCcQjXK7lLRXle1ugw8RMJoI\n" +
                    "SolKoMp2RVwM9WM9rpWNDMu1wXV/vferRb0NIxYUjJi9u4JOKAfYV1QzMHbbn8iG\n" +
                    "eo+gyyOm2IGQXbyJOa/BUpVdSgCO9bn0XQ9aeH0CgYBtMwNI/+j27fBOS1tInPFQ\n" +
                    "DcnK0zMJrD4ZXMwhJG5LTmJ/gCMMyubDxezS7Yeq77sp7+Rb+Z219PxZRdRQ6+JF\n" +
                    "rqX3NJaWFzQeMCnhBOHL9BsDDyhQjFfXhk2P2X9s9UIuUzglL6jPkgoruLcNe/sg\n" +
                    "8P9xO1xJ8MAoWEqZHj+n6wKBgQCJZtO9efVu/lGH5wplvfCMT5HJKNLCnKTP3CZ1\n" +
                    "Az+TAB4qpavgwOTiqN4OTs0irF2kPHcG6lMueOERotxysVOOJJxD0x9L1lVh9LuI\n" +
                    "H0fdQOt6hL1qRkM5olvUqVj1VohVpjft9ytYXYe6Rdlor7L8irFogJx7WC6zacHH\n" +
                    "iiIO5QKBgQCR4dfAoljiGNxR7OVUWYb4992ImIWyvEQRF+0+ZX1+lFiBG+mMzyPd\n" +
                    "6Jjmi2EMhCy0tBmLg4ruqMi6Bk519N2FHQDVcJ57VwIO8u+/CodORaYwpqFP6J9H\n" +
                    "oj7RVYucNHQZ9YYmwuQ1FTtdw1CFvOBGUE3Mh8GL6C4eOS6H4oqXNQ==\n" +
                    "-----END RSA PRIVATE KEY-----";
    private static final String openSslPrivateRsaKeyPem2 = "-----BEGIN RSA PRIVATE KEY-----\n" +
            "Proc-Type: 4,ENCRYPTED\n" +
            "DEK-Info: DES-EDE3-CBC,9848D06D94A23648\n" +
            "\n" +
            "TSNE6MaGdDtwzCAlV5DkdYGTenTdhlEpTWa8la3D1Y3tLWCFo1+riPE0HT71ctXy\n" +
            "rHOcOIVxNvufySYjB+ZhflwCvwmyAhhg6WL7jwa+BP2WSWBuuAaY5uMRX+Psl0Lv\n" +
            "rkgPumc48sEWxe8jOsEJ/GMcqYXpTRuhFT4A02B90sGP8Nt4xBde2NXFzv2NJhJV\n" +
            "uN4+wL9S5Ysc9DhyHokNC6RPjfpqciyDM+EIB5qDocScLqmTJJWrKw+7rh7uZJ5B\n" +
            "KMUentksY+adP6EUC75GsT4PkDsjatoHkhZeJcUMIi8YQuhrgxc0mpu/UsV695Ey\n" +
            "QkVrE8v1xN+Sq5YV96R+/qV92ykvhfMOokb/lWXUFgNgsHaz68oStrBEK9PYJdNT\n" +
            "gXsDUlM0fTdiDARBA0w7y72s3Jb00bJMzTH0RMKO4iKnzqEFv5srbjGESWXIhsIP\n" +
            "MLlHeiFTJHQFZcrrwyGI7II4ZHl+inLyRiB8gYM02Sf6y+Otg6gJ6g/oePIDlrOI\n" +
            "ZyJTgK2GKJ7/gMuttNXmajDnzV2ST4iQWfCtVqZTEC5wuAlUuEP1Kn6tozaBrSOy\n" +
            "R019j2SClyDUQEzwMpWnsXhch7/kzibkfO37vsTSg3VLfKjBMps5OL4Mto3HD1TW\n" +
            "TPiTyOdFiCSg9M0a5VoFXzg26RMDfDjIqhk9TxNHqjwiIhKQWDmCn0w1Wvz072xX\n" +
            "8iYU1262CIGRuqdYvnwRJ5emy5tlmJuFHOZKFyzGJVdH4SZZ8/SpuXJsKOMryC67\n" +
            "/CghiKgmj03YSEi1UbxMAgeceRr4Fp5mEpQMtlU+SfOsnxe4rlBDjsk6peXNUgcu\n" +
            "++vHxyfu3LkcwtT5xWJcHSnUk2/htyD5FKXJ6U920Hp46shdLoLzz92GGC5ni+S8\n" +
            "gImvILeVBlhnPVCDlwcusqkL/JyYnNIJkargk7Cnu0rhLWWnGOgiFh1Yc2greqsQ\n" +
            "lFlFA5rUmU5RdSxsCXvXLNQvL2sjqyfNf1X+IkAhc8I+ylNLVPxgef25pasP0+46\n" +
            "28Ch+ZRblh0g0K6ppoD7W/+J/EbT1XEMCTKrQilCXvMAf1nbDj1tmg/aQoJIJ9wO\n" +
            "Vw5pg7RiVNCDwbjuZuJ/8iC4+4mgw6z5uhYlYwvsDZlZvij44BTnB/WkF/BhzJ+t\n" +
            "IA3g9DL232t8AoX5aYvJ3/mPXypGcGabPz5POkUYl7onHp4j+dFl/Kxj3wzZ02JX\n" +
            "k/HXUfwkN8Trbng9yONs8qosFaxZsE2dmsTkkbcbKRcgjYT2FAIx2dXE+m6nF4UE\n" +
            "zskPSTpbuDfevLQJOLxoJZTDJjAEbaGybUQJmMINbTVM+llt20ES/ZNxHHtUs2GM\n" +
            "7ZY1nroZY4BVn5RAOrU7E3nlodmQtVRmjdK31+RIDJUg7psMd4gIfpTv+vjvHr1z\n" +
            "GZIG+g3QG9/NAzjStJ/piQFoCd8Fm+tfhAMHpUHkq3YO0VfVR0D40+82oIoTFvcY\n" +
            "/eDFQpdcQju3HPkm5KfWqv0PZ9gUe77jOhmuylHeIBI+SMPqbtTHOPqIzE6B9QOT\n" +
            "t0vHG53B9qwzwN3S9kRSvITHh4FCMkp62gtnjTOmpSQa5aTAP2miI9i8wnALvrg4\n" +
            "-----END RSA PRIVATE KEY-----";
    private static final String openSslPrivateRsaKeyPassword2 = "debug";
    private static final String openSslPublicRsaKeyPem2 = "-----BEGIN PUBLIC KEY-----\n" +
            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmvguzaVQMz0MZT/QHxwY\n" +
            "8RCAjEMIjaxzjf/soUNP90+0iPuR6jBeIhiQXmZaU6H86hKFG8AzKMvN5273saL2\n" +
            "12dYrYLXGNKCfH4/9KZu1FJzXwSuUma/wb1X+GUwL5xp3rbcHwgcMv9AhdpJKLTo\n" +
            "VrupYKLMxBfWYCw02w5nJBiiSLlIlsN0XD0pskLlmrPw/w2da8DexTWqYIIuBCGH\n" +
            "uNdzBI1ajgagxKpvKzDz3Te5GMnurA3KvvfALVzl+gOGtOSut1ol3dCgoBh6f1IG\n" +
            "Zqoo3cQHOYHdhaAa7+lX0oLn/cSN3AeH9CqNgj2cpcdKPLRX78y8Ju5+q06wWYGv\n" +
            "4wIDAQAB\n" +
            "-----END PUBLIC KEY-----";


    /*
    * generated "BEGIN PRIVATE KEY" using:
    *    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048
    *
    *    openssl rsa -in tmp.removeme.nopass.pem -pubout
    * */
    private static final String openSslPrivateKeyPemNoPass = "-----BEGIN PRIVATE KEY-----\n" +
            "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDvPLXbKQnR50qf\n" +
            "VI+JVlDA57NHHTJnUwpYJShpMFdACA4zCVMIdllDXxkMep1//VHrCLPx9jAEVsxJ\n" +
            "AQzenBwwGmzSIgXMpY7hLgkd4PlPRNUZqTgOz00nxFmHfwTGPzCgvtND76Jfc5kD\n" +
            "Kr9ym1NmTniRL224gd+sDJP7VABnnsTyqS8At6hc6ncdLAxJ6FQRr0hfNPCzvD2a\n" +
            "DRC/tDpcxxjquoCfxf5tMLXRkD56c1v+4oaRR1YUTNO1imTNeS7ePwUgX2QHIn7Q\n" +
            "lKmSChuou3WNxbtgLfA22Q45CiESDFfwb5mJ9cUruHNDcjk7jBUjU9SNl1EXjK91\n" +
            "4/Mzpc9FAgMBAAECggEARQeBebFHshdIwtyFZh1Pw7mXUyeriYC+dVyTYnaeVk18\n" +
            "u2EvYjuz2eqwsZcXpvyTDHxAX8qnZDkfTNlOu1TUFVUqnR9QCRKkPXkpDEQD68ly\n" +
            "q6rWD//kxVq0cpJF8GX/RAKLtwiIE36pYe6NuyXyVIzD4TCMOjbPMTeX42cDjuIE\n" +
            "IIXFddrtDJphPuqhQ2O5BBJjxCokeAW1H9UPff01a0co5bZDzyCBXaHe2hgJ94cY\n" +
            "6Opxj7MSEX3agmbq6w25XNYexuc/g4yFpwQOzV1bt1icD+nFqxrIbKsBIvIVqoGR\n" +
            "qc9mLNSYkJWEBPBXiqIhJjyQ6iF4GlLUU47qbZH+6QKBgQD7ct6Hzgvoewu7IqUq\n" +
            "wcUIOkg9DVrMU5q3aOq5VEZM3i9Xdpx9nxgU0tYFA8QX+vQvkCblEaf4lrO4Q2Mp\n" +
            "FnLFFz2w0XMdliU7fnBBr+BMgG+eByHdwNIBzToEVqAMZegzhXckLF5iO/82S6IP\n" +
            "V866JNjReJdK+MEyu0GEiFapawKBgQDzkUG7X9Pq4oAiVYCtoKewyDicmZqPWVwS\n" +
            "v2n+IxnWvpCNGsduLRsu3EsyY2fAztBeD95jtcPksttcemRaJfjllirzJajMDHvu\n" +
            "/I9iUE4FkeMDWrLYHUEv3J5/71AbYRIiehB5iDmazfWN8e7OhfREix16LaI7FUBr\n" +
            "BC6hS0QmDwKBgQCOEiAjsUrPJz7AlFmoJ+WQuYV5YWNNEWvYd2IwJqq14c/z5iOT\n" +
            "YuGzWlDscm1Ic1Wmzhb71JcIgPW4hfKwE2vzaidEEYOuUthknhMFOj9MWkE2k6cR\n" +
            "6VF/DRrbuqohdy7UdXOUr7EAZg/T+LXvX1iBmjIbYLxy8swOQvlIzdPRUwKBgQDN\n" +
            "RsUBaHgwZAjd5vX2X4o1AepEgWi0G/nviweHuomSZTVq1wDxqG5ahiuSIhlVdHhE\n" +
            "bldd7dlVrDAYtsZQ++PTi0ZTeo/SuUrSVmV51HiNVTDgqNZGMhG4htXGuSjoil1A\n" +
            "VWQBKYBzKdYkdZxwzpDaG+0SBdfOt9B84R9zrP2YnQKBgQCVIixAuMEId7YOr29/\n" +
            "/57IrgPUR9WdLYF6L+30+TmnzBRFjz4VuD5vOpwFqIR1LUhJ4C7DZhItayTTDVtG\n" +
            "2B+62ZZXTBQi8jQUq/Kpy3UjIEbcw0BEwO/ggeLw0as4hXyiLla20x2r2uPf+0FH\n" +
            "NwjAyUJrBXpY9AN3cV/yYVcUgA==\n" +
            "-----END PRIVATE KEY-----";
      public static final String openSslPrivateKeyPemNoPassPubKey = "-----BEGIN PUBLIC KEY-----\n" +
              "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7zy12ykJ0edKn1SPiVZQ\n" +
              "wOezRx0yZ1MKWCUoaTBXQAgOMwlTCHZZQ18ZDHqdf/1R6wiz8fYwBFbMSQEM3pwc\n" +
              "MBps0iIFzKWO4S4JHeD5T0TVGak4Ds9NJ8RZh38Exj8woL7TQ++iX3OZAyq/cptT\n" +
              "Zk54kS9tuIHfrAyT+1QAZ57E8qkvALeoXOp3HSwMSehUEa9IXzTws7w9mg0Qv7Q6\n" +
              "XMcY6rqAn8X+bTC10ZA+enNb/uKGkUdWFEzTtYpkzXku3j8FIF9kByJ+0JSpkgob\n" +
              "qLt1jcW7YC3wNtkOOQohEgxX8G+ZifXFK7hzQ3I5O4wVI1PUjZdRF4yvdePzM6XP\n" +
              "RQIDAQAB\n" +
              "-----END PUBLIC KEY-----";

//    /*
//     * generated BEGIN ENCRYPTED PRIVATE KEY using:
//     *   openssl genpkey -algorithm RSA -des3 -pass pass:debug -pkeyopt rsa_keygen_bits:2048
//     *   openssl rsa -in tmp.removeme.pem -pubout > tmp.removeme.public.pem
//     *   openssl rsa -in tmp.removeme.pem > tmp.removeme.public.nopass.pem
//     *
//     */
//    private static final String openSslPrivateKeyPemNoPassword = "todo";
//    private static final String openSslPrivateKeyPem = "todo";
//    private static final String openSslPrivateKeyPassword = "debug";
//    private static final String openSslPrivateKeyPublicKeyPem = "";
}
