0

I have a Azure Function In Java. Using Managed Identity and Key Vault reference, I have added a configuration in function app to access the key vault secret and certificate. The secret is referenced correctly and I am able to access its value in Azure Function.

When accessing the certificate from Azure Key Vault, using System.getenv(, I get a string which is encoded. How can I convert that string into a valid certificate in pfx or pem format.

Is there any other way to securely access certificate from Azure Key Vault in the Azure function using Java as runtime language.

6
  • Hello @the_eagle, may I know if you have referred this SO thread : stackoverflow.com/questions/55599001/… Commented Sep 6, 2021 at 7:33
  • Hi @RamaraoAdapa-MT, I have referred this thread. The ans is for .NET. I tried a similar approach using Java (my runtime stack.) But I get an error. java.security.cert.CertificateParsingException: signed fields invalid at java.base/sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1822) at java.base/sun.security.x509.X509CertImpl.<init>(X509CertImpl.java:184) at java.base/sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:105) at java.base/java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:355) Commented Sep 6, 2021 at 13:41
  • byte[] encodedCert = Base64.getDecoder().decode(certB64); ByteArrayInputStream inputStream = new ByteArrayInputStream(encodedCert); X509Certificate cert = null; try { CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); cert = (X509Certificate)certFactory.generateCertificate(inputStream); } catch (CertificateException e) { e.printStackTrace(); } Above is my time code in Java. The value in certB64 is the string returned as config variable from Key vault Commented Sep 6, 2021 at 13:43
  • Please try with below code : byte[] encodedCert = Base64.getDecoder().decode(certB64.replaceAll(X509Factory.BEGIN_CERT, "").replaceAll(X509Factory.END_CERT, "")); ByteArrayInputStream inputStream = new ByteArrayInputStream(encodedCert); X509Certificate cert = null; try { CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); cert = (X509Certificate) certFactory.generateCertificate(inputStream); } catch (CertificateException e) { e.printStackTrace(); } Let me know if it works Commented Sep 7, 2021 at 6:08
  • Update: the code I have put decodes the string and generates a x509 cert correctly. The issue is when we have a managed identity activated and a proper access policy to Get Certificates, the base64 string that is returned is actually not valid. Online tools like cert decoder confirmed that. I am not sure what is returned through the configuration variable when we assign a managed identity and access policy as in this link stackoverflow.com/questions/55599001/…. String certString = System.getenv("getCert"); Commented Sep 8, 2021 at 8:50

1 Answer 1

0

As per our discussion in the comment section, to convert the base 64 string into a valid certificate in pfx or pem format, please use below code :

byte[] encodedCert = Base64.getDecoder().decode(certB64.replaceAll(X509Factory.BEGIN_CERT, "").replaceAll(X509Factory.END_CERT, "")); 
ByteArrayInputStream inputStream = new ByteArrayInputStream(encodedCert); 
X509Certificate cert = null; 
try { 
CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 
cert = (X509Certificate) certFactory.generateCertificate(inputStream);
} 
catch (CertificateException e) { 
e.printStackTrace(); 
}

You can refer this to retrieve a certificate from keyvault : https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/keyvault/azure-security-keyvault-certificates#retrieve-a-certificate

Sign up to request clarification or add additional context in comments.

3 Comments

This code shows error on X509Factory. However, the code works. But a better way that i have figured is that each certificate has a secret if. Using client libraries we can get the secret id and fetch the certString using getSecret(<cert name>).
Currently, one issue I am facing is that while deploying azure function the build fails if some variables are specified in configuration settings in Azure Function App portal. There are service principal credentials which I am taking as env variables. However while deploying locally, it does not picks up those values and hence non-null exception is there
this is the error message. The build fails java.lang.IllegalArgumentException: Must provide non-null values for clientId, tenantId, clientSecret properties in ClientSecretCredentialBuilder

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.