I have an AWS Lambda function that gets triggered by the Alexa command. On every Alexa command, I want to call an external API endpoint to do the desired operation.
I have a jar that calls the API and has the below externalService class with invokeCommand function. The jar has been added as a dependency under my Java project.
if(value.equals("something")) {
externalService.invokeCommand();
}
invokeCommand calls the external API which is protected by SSL certificate and throws an error
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
In Elastic Beanstalk I can create a zip folder with Jar, Keystore, and procfile and I can supply keystore as an argument in the procfile which will run the jar with the keystore and that'll allow access to SSL secured endpoint.
if(value.equals("something")) {
externalService.invokeCommand(); // error on AWS Lambda
}
However, I don't think I can do the same with Lambda which is not allowing me to call SSL secured endpoint.
I believe one option would be to package the certificates into the Jar/zip for your Lambda function itself which would put them on your classpath. Once they are on your classpath you can set them up programmatically using
System.setProperty("javax.net.ssl.keyStore", KEYSTORE_FILE);
System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE);
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
System.setProperty("javax.net.ssl.trustStore", TRUSTSTORE_FILE);
System.setProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE);
System.setProperty("javax.net.ssl.trustStoreType", "JKS");
Where you'd define KEYSTORE_FILE like
URL trustStoreResource = LdapConfig.class.getResource( "/keystore.jks" );
String KEYSTORE_FILE= trustStoreResource.toURI().getPath();
System.setProperty("javax.net.ssl.keyStore", KEYSTORE_FILE);
You have too create truststore programitically See below code for reference
// Declare path of trust store and create file
String trustStorePath = "/tmp/trust";
// try creating above directory and path if you get error no such file
// Create Truststore using Key store api
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
// locate the default truststore
String filename = System.getProperty("java.home")
+ "/lib/security/cacerts".replace('/', File.separatorChar);
try (FileInputStream fis = new FileInputStream(filename)) {
keyStore.load(fis, "changeit".toCharArray());
}
// Add Certificate to Key store
CertificateFactory certF = CertificateFactory.getInstance("X.509");
Certificate cert = certF.generateCertificate(new FileInputStream("your certificate path"));
keyStore.setCertificateEntry("any alias", cert);
// Write Key Store
try (FileOutputStream out = new FileOutputStream(trustStoreFile)) {
keyStore.store(out, "changeit".toCharArray());
}
// Set Certificates to System properties
System.setProperty("javax.net.ssl.trustStore", trustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
This you can test locally as well on aws lambda. Hope this will solve the issue
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.