0
votes

I am trying send message using provided sample "SendEventX509.java" but I am facing issue. Stacktrace mentioned below OS - Windows 10

Java runtime used: JDK 11.0.3

SDK version used: IoT Hub Java Device SDK 1.17.5

Sample provided in "https://github.com/Azure/azure-iot-sdk-java/blob/master/device/iot-device-samples/send-event-x509/src/main/java/samples/com/microsoft/azure/sdk/iot/SendEventX509.java"

The certificates have been generated from "ProvisioningX509CertGen.java" and device has been successfully enrolled and provisioned in IoTHub with X509 attestation.

Console log of the issue:

Exception in thread "main" java.io.IOException: Could not open the connection
at com.microsoft.azure.sdk.iot.device.DeviceIO.open(DeviceIO.java:164)
at com.microsoft.azure.sdk.iot.device.InternalClient.open(InternalClient.java:130)
at com.microsoft.azure.sdk.iot.device.DeviceClient.open(DeviceClient.java:317)
at samples.com.microsoft.azure.sdk.iot.SendEventX509.main(SendEventX509.java:136)
Caused by: com.microsoft.azure.sdk.iot.device.exceptions.TransportException: java.io.IOException: java.security.KeyStoreException: Key protection algorithm not found: java.security.UnrecoverableKeyException: Encrypt Private Key failed: password has been cleared
at com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttIotHubConnection.open(MqttIotHubConnection.java:204)
at com.microsoft.azure.sdk.iot.device.transport.IotHubTransport.openConnection(IotHubTransport.java:700)
at com.microsoft.azure.sdk.iot.device.transport.IotHubTransport.open(IotHubTransport.java:280)
at com.microsoft.azure.sdk.iot.device.DeviceIO.open(DeviceIO.java:160)
... 3 more
Caused by: java.io.IOException: java.security.KeyStoreException: Key protection algorithm not found: java.security.UnrecoverableKeyException: Encrypt Private Key failed: password has been cleared
at com.microsoft.azure.sdk.iot.device.auth.IotHubX509SoftwareAuthenticationProvider.getSSLContext(IotHubX509SoftwareAuthenticationProvider.java:66)
at com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttIotHubConnection.open(MqttIotHubConnection.java:125)
... 6 more
Caused by: java.security.KeyStoreException: Key protection algorithm not found: java.security.UnrecoverableKeyException: Encrypt Private Key failed: password has been cleared
at java.base/sun.security.pkcs12.PKCS12KeyStore.setKeyEntry(PKCS12KeyStore.java:704)
at java.base/sun.security.pkcs12.PKCS12KeyStore.engineSetKeyEntry(PKCS12KeyStore.java:601)
at java.base/sun.security.util.KeyStoreDelegator.engineSetKeyEntry(KeyStoreDelegator.java:111)
at java.base/java.security.KeyStore.setKeyEntry(KeyStore.java:1174)
at com.microsoft.azure.sdk.iot.deps.auth.IotHubSSLContext.generateSSLContextWithKeys(IotHubSSLContext.java:208)
at com.microsoft.azure.sdk.iot.deps.auth.IotHubSSLContext.(IotHubSSLContext.java:168)
at com.microsoft.azure.sdk.iot.device.auth.IotHubX509SoftwareAuthenticationProvider.generateSSLContext(IotHubX509SoftwareAuthenticationProvider.java:96)
at com.microsoft.azure.sdk.iot.device.auth.IotHubX509SoftwareAuthenticationProvider.getSSLContext(IotHubX509SoftwareAuthenticationProvider.java:56)
... 7 more
Caused by: java.security.UnrecoverableKeyException: Encrypt Private Key failed: password has been cleared
at java.base/sun.security.pkcs12.PKCS12KeyStore.encryptPrivateKey(PKCS12KeyStore.java:951)
at java.base/sun.security.pkcs12.PKCS12KeyStore.setKeyEntry(PKCS12KeyStore.java:641)
... 14 more
Caused by: java.lang.IllegalStateException: password has been cleared
at java.base/javax.crypto.spec.PBEKeySpec.getPassword(PBEKeySpec.java:196)
at org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey.getPassword(Unknown Source)
at java.base/com.sun.crypto.provider.PKCS12PBECipherCore.implInit(PKCS12PBECipherCore.java:268)
at java.base/com.sun.crypto.provider.PKCS12PBECipherCore.implInit(PKCS12PBECipherCore.java:379)
at java.base/com.sun.crypto.provider.PKCS12PBECipherCore.implInit(PKCS12PBECipherCore.java:364)
at java.base/com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndDESede.engineInit(PKCS12PBECipherCore.java:473)
at java.base/javax.crypto.Cipher.implInit(Cipher.java:847)
at java.base/javax.crypto.Cipher.chooseProvider(Cipher.java:901)
at java.base/javax.crypto.Cipher.init(Cipher.java:1576)
at java.base/javax.crypto.Cipher.init(Cipher.java:1507)
at java.base/sun.security.pkcs12.PKCS12KeyStore.encryptPrivateKey(PKCS12KeyStore.java:934)
... 15 more

Please help to resolve this issue

1
The code being executed is: private static String publicKeyCertificateString = -----BEGIN CERTIFICATE-----\r\n" + "XXXX\r\n" + "-----END CERTIFICATE-----"; private static String privateKeyString = "-----BEGIN PRIVATE KEY-----\r\n" + "XXXX\r\n" + "-----END PRIVATE KEY-----\r\n"; String connectionString = "HostName=<>;DeviceId=<>;x509=true"; IotHubClientProtocol protocol= IotHubClientProtocol.MQTT; DeviceClient client = new DeviceClient(connectionString, protocol, publicKeyCertificateString, false, privateKeyString, false); client.open();Jubin

1 Answers

0
votes

The default keystore type has changed from jks to pkcs12 since Java 9. It seems the above azure SDK code works properly with JKS keystore. You have two options:

  1. Change the keystore.type to jks in java.security file in your Java 11 jdk/jre installation. This will have wider impact on all applications. So be careful.

  2. If you have cloned the full repo of azure samples from github, change the com.microsoft.azure.sdk.iot.deps.auth.IotHubSSLContext.generateSSLContextWithKeys() and get instance of JKS keystore instead of default one. So change:

    KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());

to

KeyStore keystore = KeyStore.getInstance("jks");

that should hopefully do the trick for you.