dvsekhvalnov / jose-jwt

Ultimate Javascript Object Signing and Encryption (JOSE), JSON Web Token (JWT) and Json Web Keys (JWK) Implementation for .NET and .NET Core
MIT License
921 stars 183 forks source link

EcdhKeyManagement alg expects key to be of CngKey or Jwk types with kty='EC #221

Closed MohamadRezaSafari closed 1 year ago

MohamadRezaSafari commented 1 year ago

Hi I pass an error when I even create a CngKey.

 var rsa = ReadKeyFromFile("test.pem");
  var pub = rsa.ExportParameters(false);
  RSACng rsaPub = new RSACng();
  rsaPub.ImportParameters(pub);
  var publicKey2 = rsaPub.Key.Export(CngKeyBlobFormat.GenericPublicBlob);
  string token = Jose.JWT.Encode(payload, publicKey2, JweAlgorithm.ECDH_ES_A256KW, JweEncryption.A256GCM);
dvsekhvalnov commented 1 year ago

Hi @MohamadRezaSafari , mind posting error details (hard to guess) ?

MohamadRezaSafari commented 1 year ago

image image image

MohamadRezaSafari commented 1 year ago

image

I've changed my code and understood something, there is a problem with JweAlgorithm.ECDH_ES_A256KW. JweEncryption.A256GCM can work with other algorithms but has a problem with JweAlgorithm.ECDH_ES_A256KW.

dvsekhvalnov commented 1 year ago

@MohamadRezaSafari on your first screenshot you need to pass rsaPub directly to library (it will be CngKey it expects).

MohamadRezaSafari commented 1 year ago

image image

You meant this ? The error occurred again.

dvsekhvalnov commented 1 year ago

Ah, my bad. RSACng doesn't seem to implement CngKey.

Try using Jwk instead, see here: https://github.com/dvsekhvalnov/jose-jwt#converting-between-jwk-and-net-key-types

Or you can try RsaKey helper directly: https://github.com/dvsekhvalnov/jose-jwt/blob/master/jose-jwt/keys/RsaKey.cs

MohamadRezaSafari commented 1 year ago

image image

Thank you man. The previous error passed but there is another error occurred.

MohamadRezaSafari commented 1 year ago

image

When I use the re-import code, there is an error.

dvsekhvalnov commented 1 year ago

what is CngKeyGenerator?

you actually can take a look at unit tests, which contains exactly same test: https://github.com/dvsekhvalnov/jose-jwt/blob/master/UnitTestsNet46/TestSuite.cs#L2602

MohamadRezaSafari commented 1 year ago

Thank you man, you helped me a lot. I really appreciate it.


string fileContent = File.ReadAllText("public-key.pem");

        using var reader = new StringReader(fileContent);
        var pemObjects = new PemReader(reader).ReadObject();
        var ecPublicKeyParameters = (ECPublicKeyParameters)pemObjects;
        var x = ecPublicKeyParameters.Parameters.G.AffineXCoord.GetEncoded();
        var y = ecPublicKeyParameters.Parameters.G.AffineYCoord.GetEncoded();

        var token = Jose.JWT.Encode(payload, Ecc256Public(x, y, CngKeyUsages.KeyAgreement),
                                        JweAlgorithm.ECDH_ES_A256KW, JweEncryption.A256GCM);

 private static CngKey Ecc256Public(byte[] x, byte[] y, 
        CngKeyUsages usage = CngKeyUsages.Signing)
    {
        return EccKey.New(x, y, usage: usage);
    }
dvsekhvalnov commented 1 year ago

So is it finally working as expected?

If so, feel free to close issue :)