You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2019/08/31 16:28:43 UTC

[karaf] branch master updated: KARAF-6384 - Add support for encrypted key password for SSH

This is an automated email from the ASF dual-hosted git repository.

jbonofre pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/karaf.git


The following commit(s) were added to refs/heads/master by this push:
     new e330b79  KARAF-6384 - Add support for encrypted key password for SSH
     new 1d3403a  Merge pull request #911 from coheigea/ssh_enc_password
e330b79 is described below

commit e330b79a6db9480b9b47174b6d7c4442685c7fd0
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Wed Jul 10 10:34:17 2019 +0100

    KARAF-6384 - Add support for encrypted key password for SSH
---
 .../features/standard/src/main/feature/feature.xml |  7 ++++
 manual/src/main/asciidoc/user-guide/remote.adoc    | 13 +++++++
 .../java/org/apache/karaf/shell/ssh/Activator.java |  9 ++---
 .../shell/ssh/keygenerator/KeyPairLoader.java      | 34 ++++++++++++++++++
 .../ssh/keygenerator/OpenSSHKeyPairProvider.java   |  5 +--
 .../karaf/shell/ssh/keygenerator/PemWriter.java    |  5 +--
 .../OSGI-INF/metatype/metatype.properties          |  3 ++
 .../main/resources/OSGI-INF/metatype/metatype.xml  |  3 +-
 .../OpenSSHGeneratorKeyFileProviderTest.java       | 41 ++++++++++++++++++++--
 .../resources/org/apache/karaf/shell/ssh/rsa.pem   | 30 ++++++++++++++++
 10 files changed, 138 insertions(+), 12 deletions(-)

diff --git a/assemblies/features/standard/src/main/feature/feature.xml b/assemblies/features/standard/src/main/feature/feature.xml
index 0dd524d..63b2e6d 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -293,6 +293,13 @@ sftpEnabled=true
 hostKey = ${karaf.etc}/host.key
 
 #
+# The password required to decrypt the private key of the server stored in
+# 'hostKey'. This is not required if the private key stored in 'hostKey' is
+# not encrypted
+#
+#hostKeyPassword =
+
+#
 # The location of the hostKeyPub file defines where the public key of the server
 # is located. If no file is at the defined location it will be ignored.
 #
diff --git a/manual/src/main/asciidoc/user-guide/remote.adoc b/manual/src/main/asciidoc/user-guide/remote.adoc
index 4deed60..7d8c846 100644
--- a/manual/src/main/asciidoc/user-guide/remote.adoc
+++ b/manual/src/main/asciidoc/user-guide/remote.adoc
@@ -82,6 +82,12 @@ sshRealm = karaf
 hostKey = ${karaf.etc}/host.key
 
 #
+# The password required to decrypt the private key of the server stored in
+# 'hostKey'. This is not required if the private key stored in 'hostKey' is
+# not encrypted
+#hostKeyPassword =
+
+#
 # The location of the hostKeyPub file defines where the public key of the server
 # is located. If no file is at the defined location it will be ignored.
 #
@@ -130,6 +136,13 @@ The `etc/org.apache.karaf.shell.cfg` configuration file contains different prope
  address of the network interface.
 * `hostKey` is the location of the `host.key` file. By defaut, it uses `etc/host.key`. This file stores the 
  private key of the SSHd server.
+* `hostKeyPassword` is the password required to decrypt the private key of the server stored in `hostKey`, if the key
+is stored in an encrypted form. Note that Karaf does not use this property to
+encrypt the private key when generating it, only for reading external keys
+that are already encrypted. Also note that specifying a `hostKeyPassword`
+might require installing the BouncyCastle provider to support the desired
+encryption algorithm.
+* `hostKeyPub` is the location of the public key of the server.
 * `sshRole` is the default role used for SSH access. See the [Security section|security] of this user guide for details.
 * `sftpEnabled` controls if the SSH server start the SFTP system or not. When enabled, Karaf SSHd supports SFTP, meaning
  that you can remotely access to the Karaf filesystem with any sftp clients.
diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/Activator.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/Activator.java
index ea7a6a4..000af3c 100644
--- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/Activator.java
+++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/Activator.java
@@ -150,7 +150,8 @@ public class Activator extends BaseActivator implements ManagedService {
         Class<?>[] roleClasses      = getClassesArray("sshRoleTypes", "org.apache.karaf.jaas.boot.principal.RolePrincipal");
         String sshRole              = getString("sshRole", null);
         String privateHostKey       = getString("hostKey", System.getProperty("karaf.etc") + "/host.key");
-        String publicHostKey        = getString("hostKeyPublic", System.getProperty("karaf.etc") + "/host.key.pub");
+        String privateKeyPassword   = getString("hostKeyPassword", null);
+        String publicHostKey        = getString("hostKeyPub", System.getProperty("karaf.etc") + "/host.key.pub");
         String[] authMethods        = getStringArray("authMethods", "keyboard-interactive,password,publickey");
         int keySize                 = getInt("keySize", 2048);
         String algorithm            = getString("algorithm", "RSA");
@@ -160,10 +161,10 @@ public class Activator extends BaseActivator implements ManagedService {
         String welcomeBanner        = getString("welcomeBanner", null);
         String moduliUrl            = getString("moduli-url", null);
         boolean sftpEnabled         = getBoolean("sftpEnabled", true);
-        
+
         Path serverPrivateKeyPath = Paths.get(privateHostKey);
         Path serverPublicKeyPath = Paths.get(publicHostKey);
-        KeyPairProvider keyPairProvider = new OpenSSHKeyPairProvider(serverPrivateKeyPath, serverPublicKeyPath, algorithm, keySize);
+        KeyPairProvider keyPairProvider = new OpenSSHKeyPairProvider(serverPrivateKeyPath, serverPublicKeyPath, algorithm, keySize, privateKeyPassword);
         KarafJaasAuthenticator authenticator = new KarafJaasAuthenticator(sshRealm, sshRole, roleClasses);
         UserAuthFactoriesFactory authFactoriesFactory = new UserAuthFactoriesFactory();
         authFactoriesFactory.setAuthMethods(authMethods);
@@ -199,7 +200,7 @@ public class Activator extends BaseActivator implements ManagedService {
         }
         if (welcomeBanner != null) {
             server.getProperties().put(SshServer.WELCOME_BANNER, welcomeBanner);
-        } 
+        }
         return server;
     }
 
diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/KeyPairLoader.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/KeyPairLoader.java
index d0ac5a5..a576c6e 100644
--- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/KeyPairLoader.java
+++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/KeyPairLoader.java
@@ -41,9 +41,17 @@ import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
 import org.bouncycastle.jce.spec.ECParameterSpec;
 import org.bouncycastle.jce.spec.ECPublicKeySpec;
 import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.openssl.PEMDecryptorProvider;
+import org.bouncycastle.openssl.PEMEncryptedKeyPair;
 import org.bouncycastle.openssl.PEMKeyPair;
 import org.bouncycastle.openssl.PEMParser;
 import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
+import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
+import org.bouncycastle.operator.InputDecryptorProvider;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
+import org.bouncycastle.pkcs.PKCSException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -59,11 +67,37 @@ public final class KeyPairLoader {
     }
 
     public static KeyPair getKeyPair(InputStream is) throws GeneralSecurityException, IOException {
+        return getKeyPair(is, null);
+    }
+
+    public static KeyPair getKeyPair(InputStream is, String password) throws GeneralSecurityException, IOException {
         try (PEMParser parser = new PEMParser(new InputStreamReader(is))) {
             Object o = parser.readObject();
 
             JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter();
 
+            if (o instanceof PEMEncryptedKeyPair) {
+                if (password == null) {
+                    throw new GeneralSecurityException("A password must be supplied to read an encrypted key pair");
+                }
+                JcePEMDecryptorProviderBuilder decryptorBuilder = new JcePEMDecryptorProviderBuilder();
+                PEMDecryptorProvider pemDecryptor = decryptorBuilder.build(password.toCharArray());
+                o = pemConverter.getKeyPair(((PEMEncryptedKeyPair) o).decryptKeyPair(pemDecryptor));
+            } else if (o instanceof PKCS8EncryptedPrivateKeyInfo) {
+                if (password == null) {
+                    throw new GeneralSecurityException("A password must be supplied to read an encrypted key pair");
+                }
+
+                JceOpenSSLPKCS8DecryptorProviderBuilder jce = new JceOpenSSLPKCS8DecryptorProviderBuilder();
+                try {
+                    InputDecryptorProvider decProv = jce.build(password.toCharArray());
+                    o = ((PKCS8EncryptedPrivateKeyInfo)o).decryptPrivateKeyInfo(decProv);
+                } catch (OperatorCreationException | PKCSException ex) {
+                    LOGGER.debug("Error decrypting key pair", ex);
+                    throw new GeneralSecurityException("Error decrypting key pair", ex);
+                }
+            }
+
             if (o instanceof PEMKeyPair) {
                 return pemConverter.getKeyPair((PEMKeyPair)o);
             } else if (o instanceof KeyPair) {
diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/OpenSSHKeyPairProvider.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/OpenSSHKeyPairProvider.java
index 8f527d0..b4b1885 100644
--- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/OpenSSHKeyPairProvider.java
+++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/OpenSSHKeyPairProvider.java
@@ -50,11 +50,12 @@ public class OpenSSHKeyPairProvider extends AbstractKeyPairProvider {
     private String algorithm;
     private int keySize;
 
-    public OpenSSHKeyPairProvider(Path privateKeyPath, Path publicKeyPath, String algorithm, int keySize) {
+    public OpenSSHKeyPairProvider(Path privateKeyPath, Path publicKeyPath, String algorithm, int keySize, String password) {
         this.privateKeyPath = privateKeyPath;
         this.publicKeyPath = publicKeyPath;
         this.algorithm = algorithm;
         this.keySize = keySize;
+        this.password = password;
     }
 
     @Override
@@ -69,7 +70,7 @@ public class OpenSSHKeyPairProvider extends AbstractKeyPairProvider {
         // 1. Try to read the PKCS8 private key. If it is RSA or DSA we can infer the public key directly from the
         // private key, so there is no need to load the public key.
         try (InputStream is = Files.newInputStream(privateKeyPath)) {
-            KeyPair kp = KeyPairLoader.getKeyPair(is);
+            KeyPair kp = KeyPairLoader.getKeyPair(is, password);
             cachedKey = kp;
             return singleton(kp);
         } catch (Exception e) {
diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/PemWriter.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/PemWriter.java
index 9eb763e..e9d2257 100644
--- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/PemWriter.java
+++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/keygenerator/PemWriter.java
@@ -24,6 +24,7 @@ import java.io.IOException;
 import java.nio.file.Path;
 import java.security.KeyPair;
 
+import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
 import org.bouncycastle.util.io.pem.PemObject;
 
 public class PemWriter {
@@ -36,11 +37,11 @@ public class PemWriter {
     }
 
     public void writeKeyPair(String resource, KeyPair kp) throws IOException, FileNotFoundException {
-        try (org.bouncycastle.util.io.pem.PemWriter writer = new org.bouncycastle.util.io.pem.PemWriter(new FileWriter(privateKeyPath.toFile()))) {
+        try (JcaPEMWriter writer = new JcaPEMWriter(new FileWriter(privateKeyPath.toFile()))) {
             writer.writeObject(new PemObject("PRIVATE KEY", kp.getPrivate().getEncoded()));
         }
 
-        try (org.bouncycastle.util.io.pem.PemWriter writer = new org.bouncycastle.util.io.pem.PemWriter(new FileWriter(publicKeyPath.toFile()))) {
+        try (JcaPEMWriter writer = new JcaPEMWriter(new FileWriter(publicKeyPath.toFile()))) {
             writer.writeObject(new PemObject("PUBLIC KEY", kp.getPublic().getEncoded()));
         }
     }
diff --git a/shell/ssh/src/main/resources/OSGI-INF/metatype/metatype.properties b/shell/ssh/src/main/resources/OSGI-INF/metatype/metatype.properties
index 235513f..b5d7b5a 100644
--- a/shell/ssh/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/shell/ssh/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -39,6 +39,9 @@ hostKey.description = location of the private host key for SSH
 hostKeyPub.name = Public host key
 hostKeyPub.description = location of the public host key for SSH
 
+hostKeyPassword.name = Private host key password
+hostKeyPassword.description = the password to use to decrypt the private key stored in hostKey, if it is encrypted
+
 keySize.name = Key size
 keySize.description = Secret key size in 1024, 2048, 3072, or 4096
 
diff --git a/shell/ssh/src/main/resources/OSGI-INF/metatype/metatype.xml b/shell/ssh/src/main/resources/OSGI-INF/metatype/metatype.xml
index e52eeb1..fa2b6ed 100644
--- a/shell/ssh/src/main/resources/OSGI-INF/metatype/metatype.xml
+++ b/shell/ssh/src/main/resources/OSGI-INF/metatype/metatype.xml
@@ -23,7 +23,8 @@
         <AD id="sshHost" type="String" default="0.0.0.0" name="%sshHost.name" description="%sshHost.description"/>
         <AD id="sshRealm" type="String" default="karaf" name="%sshRealm.name" description="%sshRealm.description"/>
         <AD id="hostKey" type="String" default="${karaf.etc}/host.key" name="%hostKey.name" description="%hostKey.description"/>
-        <AD id="hostKeyPublic" type="String" default="${karaf.etc}/host.key.pub" name="%hostKeyPublic.name" description="%hostKeyPublic.description"/>
+        <AD id="hostKeyPub" type="String" default="${karaf.etc}/host.key.pub" name="%hostKeyPub.name" description="%hostKeyPub.description"/>
+        <AD id="hostKeyPassword" type="String" name="%hostKeyPassword.name" description="%hostKeyPassword.description"/>
         <AD id="keySize" type="Integer" default="2048" name="%keySize.name" description="%keySize.description"/>
         <AD id="algorithm" type="String" default="RSA" name="%algorithm.name" description="%algorithm.description"/>
     </OCD>
diff --git a/shell/ssh/src/test/java/org/apache/karaf/shell/ssh/keygenerator/OpenSSHGeneratorKeyFileProviderTest.java b/shell/ssh/src/test/java/org/apache/karaf/shell/ssh/keygenerator/OpenSSHGeneratorKeyFileProviderTest.java
index bf106b0..bd2200f 100644
--- a/shell/ssh/src/test/java/org/apache/karaf/shell/ssh/keygenerator/OpenSSHGeneratorKeyFileProviderTest.java
+++ b/shell/ssh/src/test/java/org/apache/karaf/shell/ssh/keygenerator/OpenSSHGeneratorKeyFileProviderTest.java
@@ -18,8 +18,12 @@
  */
 package org.apache.karaf.shell.ssh.keygenerator;
 
+import static org.junit.Assert.fail;
+
 import java.io.File;
 import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.security.KeyPair;
 import java.security.interfaces.ECPrivateKey;
 import java.security.interfaces.ECPublicKey;
@@ -46,7 +50,7 @@ public class OpenSSHGeneratorKeyFileProviderTest {
 
         //File path = new File("/home/cschneider/.ssh/id_rsa");
         OpenSSHKeyPairProvider prov =
-            new OpenSSHKeyPairProvider(privateKeyTemp.toPath(), publicKeyTemp.toPath(), KeyUtils.RSA_ALGORITHM, 1024);
+            new OpenSSHKeyPairProvider(privateKeyTemp.toPath(), publicKeyTemp.toPath(), KeyUtils.RSA_ALGORITHM, 1024, null);
         KeyPair keys = prov.loadKeys().iterator().next();
         Assert.assertNotNull(keys);
         Assert.assertTrue("Loaded key is not RSA Key", keys.getPrivate() instanceof RSAPrivateCrtKey);
@@ -69,7 +73,7 @@ public class OpenSSHGeneratorKeyFileProviderTest {
         Assert.assertEquals("DSA", simpleKeyPair.getPrivate().getAlgorithm());
 
         OpenSSHKeyPairProvider provider =
-            new OpenSSHKeyPairProvider(privateKeyTemp.toPath(), publicKeyTemp.toPath(), "DSA", 2048);
+            new OpenSSHKeyPairProvider(privateKeyTemp.toPath(), publicKeyTemp.toPath(), "DSA", 2048, null);
         KeyPair convertedKeyPair = provider.loadKeys().iterator().next();
         Assert.assertEquals("DSA", convertedKeyPair.getPrivate().getAlgorithm());
 
@@ -92,11 +96,42 @@ public class OpenSSHGeneratorKeyFileProviderTest {
         new PemWriter(privateKeyTemp.toPath(), publicKeyTemp.toPath()).writeKeyPair(KeyUtils.EC_ALGORITHM, kp);
 
         OpenSSHKeyPairProvider prov =
-            new OpenSSHKeyPairProvider(privateKeyTemp.toPath(), publicKeyTemp.toPath(), KeyUtils.EC_ALGORITHM, 256);
+            new OpenSSHKeyPairProvider(privateKeyTemp.toPath(), publicKeyTemp.toPath(), KeyUtils.EC_ALGORITHM, 256, null);
         KeyPair keys = prov.loadKeys().iterator().next();
         Assert.assertNotNull(keys);
         Assert.assertTrue("Loaded key is not EC Key", keys.getPrivate() instanceof ECPrivateKey);
         Assert.assertTrue("Loaded key is not EC Key", keys.getPublic() instanceof ECPublicKey);
     }
 
+    @Test
+    public void loadEncryptedPrivateKey() throws Exception {
+        Path privateKeyPath = Paths.get(this.getClass().getResource("../rsa.pem").toURI());
+
+        // First we try to load without specifying a password...
+        OpenSSHKeyPairProvider prov =
+            new OpenSSHKeyPairProvider(privateKeyPath, null, KeyUtils.RSA_ALGORITHM, 1024, null);
+        try {
+            prov.loadKeys();
+            fail("Failure expected on a decryption failure");
+        } catch (Exception ex) {
+            // expected
+        }
+
+        // Now we provide the wrong password
+        prov = new OpenSSHKeyPairProvider(privateKeyPath, null, KeyUtils.RSA_ALGORITHM, 1024, "password");
+        try {
+            prov.loadKeys();
+            fail("Failure expected on a decryption failure");
+        } catch (Exception ex) {
+            // expected
+        }
+
+        // Now it should work
+        prov = new OpenSSHKeyPairProvider(privateKeyPath, null, KeyUtils.RSA_ALGORITHM, 1024, "security");
+        KeyPair keys = prov.loadKeys().iterator().next();
+        Assert.assertNotNull(keys);
+        Assert.assertTrue("Loaded key is not RSA Key", keys.getPrivate() instanceof RSAPrivateCrtKey);
+        Assert.assertTrue("Loaded key is not RSA Key", keys.getPublic() instanceof RSAPublicKey);
+    }
+
 }
diff --git a/shell/ssh/src/test/resources/org/apache/karaf/shell/ssh/rsa.pem b/shell/ssh/src/test/resources/org/apache/karaf/shell/ssh/rsa.pem
new file mode 100644
index 0000000..a1e34c5
--- /dev/null
+++ b/shell/ssh/src/test/resources/org/apache/karaf/shell/ssh/rsa.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQINAubvRUVyWMCAggA
+MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBDMc/hPGDrndOLgH70FkALsBIIE
+0EyOCSJByCun3cEPbgA6UaunVBsmRTPRL8BBua840YnNi3ncPtZYnkQmGb1Uh+91
+vJy0ZwdwUJUANd10S+bHaBmDrahsnH2T5aOk+EKLPVyJgB2et4VL5N7xjJACqROG
++naB4/EFb0FnioUTPRBAvSltSQNAg27c2K0nJYrWnpqdG/3eBOSmVD6BIXbNl767
+c2rWcNDZRSEs+KMYK9NUPkW+z9n4FEldZI6CvFB/0rOzOjgyhY9FjsrItZr94zMv
+y4hGtOFfq6ZsIf0IRQ39sbF4d96V8LyV0LBPv13CokikAVS7po9gGeKHFiwzNgwX
+OQOWt/qArMq4cckihBchPCLhIKve5BJXLSV1bvrytvuKSbN99r9HagNRQ8lyj5fO
+L+73cecVOt6yDjKX49iVhWUxgbe7tUgK+/VasyXHa0oR4xJ4ZXrKFsEKlysetC4m
+WeEkOOG87cDroyOU1N5McjBMYfDGKiujsUie0QahGwjJbFgh4o/UQw+HkxsqZR3r
+RMQemEKMYXLMM0BvUnJFWIcPl20wf9HJ80WRMIVSsBIPpCXyg+BHE82osorbW5zH
+1O0sXqBnifU/O8dnTqX/cUvZ/9x2jcNlxlGHGdIvxLFlv1t/HhNBD43xsMm013fW
+UHsJMumYoksqKkBlYpwR4oQgOpnJqA2jzlZzbV5q1NFyc0fzJf9wYck1Ur81Tct9
+B+eKh32VIvFP9ZieZN87Ez1GhkQWxFGdLpXTlC9j+MlubARMJhtbxtDoObIBYVB2
+Ki7zhDdfy5qdDPIQ1rPecjzIRqWahwbzLyHGHjFqI1Rqfwz0DLMWxlO8lDPd7OjG
+rf3U8MRlur3CIi5mEIWGta3nVFoGBq6fliqjY+NgQ7j3rcPHn/or4HVaNDXpQnA6
+i/7v2xzVTCrKygxuxEG1/o0xZyxHkKstBxf+WkV5vwtdf8b3iOROmHtqHg6BlscN
+yrrIwY+9bISdISkcGJv5OlJC8vzJyu6eCI0CO5aXUF5UDhREPDrolqWvqrcYjCC5
+1SMtqSunIl0xW4QruHSa7CQvCr+oJ8kCKQsBM9RVv+5gu61bBzbADc2cAOkun9BC
+JVQkIbIM4bChvhHoFXq6IWss3DBnxtykQ2zSgNOBaFEI6u3CdVhKtewBB2mleo93
+E8s5BmyHnDPPccQOv8n+eO6NeQ0tmaHqa9gYqdr1vziUbSuamZ8QHB3NcMJbkiS0
+LMeg+N3Nz/2MztgFN9iS+hNeLCU5F59vWJRiUXVplZ5EsCh0ih58TgfA+6eBUQBN
+MtblH+qTmMTnMvJS5emBt+vGmHTqal7ubUmhGUjojvR3dtFCBI41BWqp2xMpDFfr
+v5UuKwFZEU4oBa/F5HjbtoayH4HQrc6izTH/cbYhqwYMGlJQPcNiN8Lr/j95puF+
+6+S3ymUAa9YDEeGHLuqCwfihex7lk8ku7GMtY83Y2O8TrKmm1pAgt2/y3aGGMugd
+Yej3OEJ7RLKAmD0l2X5Yr4crB8vCEO+58XWVwA7Eu3GxNEH+Z5LDh+sXRLopjt6V
+eQ6R36KExT8AwnKtwIyVve2a5n7Stff9TN1AncN+6lMOZZWOWwdFyJCvp8hxhIX9
+ivPCZx+BHyYyn9GPnC5fvkX5YxEs60dH17CeciMFrN4f
+-----END ENCRYPTED PRIVATE KEY-----