1

I'm using "BouncyCastle.NetCore" and "jose-jwt" libraries to sign and encrypt a web token. I'm able to sign with my private key by below code. but the requirements is to also perform OpenID JWT Encryption In order to encrypt the JWT payload, we need to do that using provided public key string (base64 decoded with X509 key spec). the encode needed to use RSA algorithm and JWE header should include header name “alg" with the value: RSA_OAEP_256. Below code is sign only with private key but not sure how to complete the encode??

 class Program
{
    string publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB";
    public static async Task Main(string[] args)
    {
        var payload = new System.Collections.Generic.Dictionary<string, object>()
            {
                { "sub", "Testmr.x@contoso.com" },
                { "iss", "https://www.YourBrand.com" },
                { "exp", 1300819380 },
                { "iat", 1446111752 },
                { "preferred_username", "JohnDoe2" },
                { "phone_number", "+2-10-344-3765333" }
            };
        var token = CreateToken(payload);
        Console.WriteLine($"token={token}");
    }
    public static string CreateToken(object payload)
    {
        string jwt = string.Empty;
        var fileStream = System.IO.File.OpenText("C:\\temp\\my_private_key.pem");
        var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(fileStream, new MyPasswordFinder());
        var keyPair = (Org.BouncyCastle.Crypto.AsymmetricKeyParameter)pemReader.ReadObject();
        RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)keyPair);
        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
        {
            rsa.ImportParameters(rsaParams);                
            jwt = JWT.Encode(payload, rsa, JwsAlgorithm.RS256);//,options: new JwtOptions { EncodePayload = true }
        }
        return jwt;
    }

}
Tarek El-Mallah
  • 4,015
  • 1
  • 31
  • 46
  • I think this article by "Scott Brady" may give you a good idea on how to do it, or at least point you to the right direction: https://www.scottbrady91.com/C-Sharp/JSON-Web-Encryption-JWE-in-dotnet-Core – Luis Apr 29 '20 at 20:21

1 Answers1

0

The only difference EncodePayload seems to make is how payload ends up being written out to JWT body. It is true by default and does not affect payload encryption (see source code):

return jwtOptions.EncodePayload
            ? Compact.Serialize(headerBytes, payloadBytes, signature)
            : Compact.Serialize(headerBytes, Encoding.UTF8.GetString(payloadBytes), signature);

What you probably want is to specify JweAlgorithm and correct JweEncryption (note, it's a different overload to the same function:

jwt = JWT.Encode(payload, rsa, JweAlgorithm.RSA_OAEP_256, JweEncryption.A256GCM);
timur
  • 14,239
  • 2
  • 11
  • 32
  • I don't think this answer my question, I have a private PEM/public PEM and also another RSA public key. I need to sign/encode/ and encrypt the token. the missing part in my code is the encrypt part (I summary we need JWE with JWS as payload). Also, your code above not working got error "Specified padding mode is not valid for this algorithm" – Tarek El-Mallah Apr 23 '20 at 02:23
  • Yes, I was testing it out on full framework before i realised there's a difference. Do you mind giving `JweAlgorithm.RSA_OAEP` a try? I understand this is not what you are after but it seems to work for me in .net core and I just want to at least understand if the result is somewhat similar to your expectation – timur Apr 23 '20 at 03:45
  • unfortunately your code not working with me, and even if it work it's not answer my question. – Tarek El-Mallah Apr 24 '20 at 19:51