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
944 stars 184 forks source link

Sign with Public key (pem) #251

Closed huyoumo closed 1 month ago

huyoumo commented 1 month ago

Hi,

I'm new to JWT and please pardon me if asking layman's question.

The goal I try to achieve is:

With .NET (C#) 4.7.2, I installed jose-jwt 5.0.0 and BouncyCastle 1.8.9

I want to sign the JWT token with public key (with RS256), how can I achieve this?

I've seen examples that sign the token with private key, but not much example for signing with public key.

Please help.

Update: after doing more google, it seems the question is not applicable, as it oppose the JWT specification, refer to link below: https://stackoverflow.com/questions/44214400/can-json-web-token-sign-with-public-key

Please take a look and reply if the above link has the right answer?

Thanks and regards, Youmo

dvsekhvalnov commented 1 month ago

Hi @huyoumo ,

well, typical use case with digital signature is:

  1. sign with something only you own (private key)
  2. let other verify integrity & authenticity with something that everybody knows (public part of you private key)

but technically nothing prevents you to sign with public key. I can't recall if library have any restrictions around it, i guess just try it may be?

var payload = new Dictionary<string, object>()
{
    { "sub", "mr.x@contoso.com" },
    { "exp", 1300819380 }
};

Jwk publicKey = new Jwk("AQAB", "qFZv0pea_jn5Mo4qEUmStuhlulso8n1inXbEotd_zTrQp9K0RK0hf7t0K4BjKVhaiqIam4tVVQvkmYeBeYr1MmnO_0N97dMBz_7fmvyv0hgHaBdQ5mR5u3LTlHo8tjRE7-GzZmGs6jMcyj7HbXobDPQJZpqNy6JjliDVXxW8nWJDetxGBlqmTj1E1fr2RCsZLreDOPSDIedG1upz9RraShsIDzeefOcKibcAaKeeVI3rkAU8_mOauLSXv37hlk0h6sStJb3qZQXyOUkVkjXIkhvNu_ve0v7LiLT4G_OxYGzpOQcCnimKdojzNP6GtVDaMPh-QkSJE32UCos9R3wI2Q");

string token=Jose.JWT.Encode(payload, publicKey, JwsAlgorithm.RS256);
huyoumo commented 1 month ago

Hi @dvsekhvalnov,

Thank you so much for the prompt reply.

I've tried the above code you posted, however, I've got the following exception: System.Security.Cryptography.CryptographicException: 'Key does not exist. ' Here's the stack trace: " at System.Security.Cryptography.NCryptNative.SignHash[T](SafeNCryptKeyHandle key, Byte[] hash, T& paddingInfo, AsymmetricPaddingMode paddingMode, NCryptHashSigner1 signer)\r\n at System.Security.Cryptography.NCryptNative.SignHashPkcs1(SafeNCryptKeyHandle key, Byte[] hash, String hashAlgorithm)\r\n at System.Security.Cryptography.RSACng.SignHash(Byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)\r\n at System.Security.Cryptography.RSA.SignData(Byte[] data, Int32 offset, Int32 count, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)\r\n at System.Security.Cryptography.RSA.SignData(Byte[] data, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)\r\n at Jose.RsaUsingSha.Sign(Byte[] securedInput, Object key)\r\n at Jose.JWT.EncodeBytes(Byte[] payload, Object key, JwsAlgorithm algorithm, IDictionary2 extraHeaders, JwtSettings settings, JwtOptions options)\r\n at Jose.JWT.Encode(Object payload, Object key, JwsAlgorithm algorithm, IDictionary`2 extraHeaders, JwtSettings settings, JwtOptions options)\r\n at JWTTokenGen.Program.TryFromAdvise() in C:\Users\Administrator\source\repos\JWTTokenLab\JWTTokenGen\Program.cs:line 74\r\n at JWTTokenGen.Program.Main(String[] args) in C:\Users\Administrator\source\repos\JWTTokenLab\JWTTokenGen\Program.cs:line 55"

Any advice?

Thanks and regards, Youmo

dvsekhvalnov commented 1 month ago

Guess, System.Security.Cryptography expects to have private key, so most likely idea of signing with public part only will not work.

huyoumo commented 1 month ago

Hi @dvsekhvalnov,

Thanks for sharing the thoughts, I think based on the investigation, we can conclude that to sign with public key is:

We can close the issue.

Regards, Youmo

dvsekhvalnov commented 1 month ago

you welcome.

it may be possible in other language though.