Azure-sdk-for-java: [BUG] Unable to import symmetric key into AKV using the Java SDK

Created on 8 Jul 2020  路  6Comments  路  Source: Azure/azure-sdk-for-java

Describe the bug
Unexpected error while importing symmetric key.
I added the code provided below in the samples/java for the Azure-security-keyvault-keys project and executed it. The symmetric key import failed.

Exception or Stack Trace

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" com.azure.core.exception.HttpResponseException: Status code 400, "{"error":{"code":"BadParameter","message":"Invalid kty value: oct","innererror":{"code":"KeyTypeNotSupported"}}}"
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at com.azure.core.http.rest.RestProxy.instantiateUnexpectedException(RestProxy.java:320)
    at com.azure.core.http.rest.RestProxy.lambda$ensureExpectedStatus$3(RestProxy.java:361)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1755)
    at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.signalCached(MonoCacheTime.java:320)
    at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.onNext(MonoCacheTime.java:337)
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2317)
    at reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.onSubscribe(MonoCacheTime.java:276)
    at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:191)
    at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53)
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.MonoCacheTime.subscribeOrReturn(MonoCacheTime.java:132)
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150)
    at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:114)
    at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:123)
    at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:112)
    at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:213)
    at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:123)
    at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(FluxHandleFuseable.java:178)
    at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:96)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1755)
    at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121)
    at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252)
    at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136)
    at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:366)
    at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:367)
    at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:423)
    at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:607)
    at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:96)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1518)
    at io.netty.handler.ssl.SslHandler.decodeNonJdkCompatible(SslHandler.java:1279)
    at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1316)
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:440)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:834)
    Suppressed: java.lang.Exception: #block terminated with an error
        at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99)
        at reactor.core.publisher.Mono.block(Mono.java:1678)
        at com.azure.security.keyvault.keys.KeyClient.importKeyWithResponse(KeyClient.java:317)
        at com.azure.security.keyvault.keys.KeyClient.importKey(KeyClient.java:264)
        at com.saurabh500.samples.ImportKey.main(ImportKey.java:28)

To Reproduce


public class ImportKey {

    public static void main(String[] args) throws InterruptedException, IllegalArgumentException {

        // Instantiate a key client that will be used to call the service. Notice that the client is using default Azure
        // credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
        // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.

        String keyVaultName = System.getenv("KEY_VAULT_NAME");
        String kvUri = "https://" + keyVaultName + ".vault.azure.net";

        KeyClient client = new KeyClientBuilder().vaultUrl(kvUri)
                .credential(new DefaultAzureCredentialBuilder().build()).buildClient();

        byte[] symmetrickeyContent = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };

        String keyName = "importedSymmetricKey";
        KeyVaultKey importResult = client.importKey(keyName, JsonWebKey.fromAes(new SecretKeySpec(symmetrickeyContent, "AES")));
        System.out.printf("Imported Key Id: %s Name : %s Version = %s\n", importResult.getId(), 
                importResult.getName());

        KeyVaultKey keyvaultKey = client.getKey(keyName);
        System.out.printf("Key Retrieved by name with version %s ", keyvaultKey.getProperties().getVersion());

    }
}

Code Snippet
See above

Expected behavior
The call above should succeed.

Screenshots
If applicable, add screenshots to help explain your problem.
NA

Setup (please complete the following information):

  • OS: [e.g. iOS]: Windows Server 2019
  • IDE : [e.g. IntelliJ] Eclipse
  • Version of the Library used: Tested on the lastest master branch.

Additional context
Add any other context about the problem here.

Information Checklist
Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

  • [x] Bug Description Added
  • [x] Repro Steps Added
  • [x] Setup information Added
Client KeyVault customer-reported question

All 6 comments

Hi @saurabh500 馃槃 - @vcolin7 will take a look and get back to you shortly.

Hey @joshfree Good to see you here :smiley:

I am not sure if this is a service issue or client issue.

I couldn't find any references to AKV not supporting symmetric keys with kty=oct, although the error is coming from the service.
I did see another reference to similar problem at https://feedback.azure.com/forums/906355-azure-key-vault/suggestions/37894861-does-azure-support-aes-symmetric-keys-we-have-t

@vcolin7 In case you need more information like the Key Vault name or a repro environment / service details, please ping me on my Microsoft Alias: sausing

Hi @saurabh500, I am actively looking into this and will reach the Key Vault service team about it as well. I was able to reproduce the issue with the code you provided, thank you for that :)

For the time being, only EC and RSA keys are supported by KeyVault as specified here. However, I do agree documentation such as this could be clearer about whether the types mentioned are supported or not, instead of saying "these are the possible JWK types as per the specification", otherwise it feels somewhat ambiguous.

I will be closing this for the time being as it is not a bug in the SDK. Thank you for taking time to file this issue :)

Thank you. I needed a clear answer which you provided 馃榾

Was this page helpful?
0 / 5 - 0 ratings