Reading the SSH private key from the application.yaml file in spring-boot?

advertisements

I have a camel application which connects to SFTP server using SSH Private key. If i read the id_rsa file from a file, i was able to connect to the server. As given in this example, it is working with loading from a file.

registry.put("privateKey", getBytesFromFile("./src/main/resources/id_rsa"));

private byte[] getBytesFromFile(String filename) throws IOException {
    InputStream input;
    input = new FileInputStream(new File(filename));
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    IOHelper.copyAndCloseInput(input, output);
    return output.toByteArray();
}

I want to provide the private key dynamically at runtime. That means in application.yaml in spring-boot application, which will be replaced by docker container environment variables.

@Value("${sftp_private_key}")
private String privateKey;

registry.put("privateKey", privateKey.getBytes());

I am getting this exception

org.apache.camel.component.file.GenericFileOperationFailedException: Cannot connect to sftp://<user>@<sftp_server>:22
    at org.apache.camel.component.file.remote.SftpOperations.connect(SftpOperations.java:146) ~[camel-ftp-2.19.1.jar:2.19.1]
    at org.apache.camel.component.file.remote.RemoteFileConsumer.connectIfNecessary(RemoteFileConsumer.java:203) [camel-ftp-2.19.1.jar:2.19.1]
    at org.apache.camel.component.file.remote.RemoteFileConsumer.recoverableConnectIfNecessary(RemoteFileConsumer.java:171) [camel-ftp-2.19.1.jar:2.19.1]
    at org.apache.camel.component.file.remote.RemoteFileConsumer.prePollCheck(RemoteFileConsumer.java:59) [camel-ftp-2.19.1.jar:2.19.1]
    at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:110) [camel-core-2.19.1.jar:2.19.1]
    at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174) [camel-core-2.19.1.jar:2.19.1]
    at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101) [camel-core-2.19.1.jar:2.19.1]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_121]
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_121]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_121]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
Caused by: com.jcraft.jsch.JSchException: invalid privatekey: [[email protected]
    at com.jcraft.jsch.KeyPair.load(KeyPair.java:757) ~[jsch-0.1.54.jar:na]
    at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:46) ~[jsch-0.1.54.jar:na]
    at com.jcraft.jsch.JSch.addIdentity(JSch.java:442) ~[jsch-0.1.54.jar:na]
    at org.apache.camel.component.file.remote.SftpOperations.createSession(SftpOperations.java:220) ~[camel-ftp-2.19.1.jar:2.19.1]
    at org.apache.camel.component.file.remote.SftpOperations.connect(SftpOperations.java:115) ~[camel-ftp-2.19.1.jar:2.19.1]
    ... 13 common frames omitted

After some debugging, i understand that its an issue with \n characters. If i read from a file the private key contains \n characters. But if i read from .yaml file, it does not have \n characters. I replaced all new lines into \n characters and converted it into single line. Still it's not working.

How can i provide this value in application.yaml which is equivalent to reading from that file?


As explained here, it is working after i put |

Example application.yaml:

sftp_private_key: |
                  ----BEGIN RSA PRIVATE KEY-----
                     Remaining part of key
                  -----END RSA PRIVATE KEY-----