I'm trying to get the Ciphertext out of a JWE response using C# and a PKCS 8 private key and cannot find a good example that works. I created the public and private keys using: openssl genrsa -out private.pem 2048 && openssl rsa -in private.pem -outform PEM -pubout -out public.pem && type public.pem
When I run this code it seems like it read the PEM key information fine, but there is zero bytes of output and I get "Cannot access a disposed object. Object name: 'RSACng'." when trying to use the RSA object.
Here is the code and the JWE + Private key data:
My goal is to get the Ciphertext out of the JWE string. Here is the code and the JWE + Private key data:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Pkcs;
using Microsoft.IdentityModel.Tokens;
namespace Transaction
{
public static class CallDecryptJwe
{
public static void DecryptJwe(string jweString, string decryptionKeyInput)
{
string jweToken = jweString;
string privateKeyPem = decryptionKeyInput;
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
//JWE Payload (string jswString)
/*
*
eyJraWQiOiIzM2MzZmNmYTI1YzkxMWUzMTBiNDBjZGYwZWMxMWFhOWQxY2Y2YzUzIiwiY3R5IjoianNvbiIsInR5cCI6IkpXVCIsImVuYyI6IkEyNTZHQ00iLCJhbGciOiJSU0EtT0FFUC0yNTYifQ.v0f_8g-OW86e81KBGACnR6jiqr8VC9HnFo8X3tyRYeulTFfh1rxHwtpq7RTTtsNs_bjhoexOG4i_MFuk1eCR4ex0VpCGmUssbpnEkttQ83EZEfPYalQf1oMhqHyHDVNjQ3vdQma8B7ucG6ru71HfnPF5iWAefMRNm6GQXFwqhRbD9XOXitw7KS8KWjucsHyGmhb2Ye3q0nHc6zEgAN2AfiX8xsfsbx73ajU0bl0cuaRbZVsFfadnjggFngRfp2eTu0MPVf8YriiLXqpe4g6uQo0ERECZpzO6QePZXlxA2GB04yURZLMqZiRpgfMvifYc9W07Y-vjJ6s8hq1T5MKA2A.d6wRkpDHrANCUIVS.uM6N3gWAfefOSQXQKHOqIntCrV1HmsJ8QSy2fGm2Z542PqXiJYyWYV6MiGWdqOgmkTYBMf5VIId319b75q9hOXn1f-idSyiDYlvW9uIF3eb-Nd9ZQ6OrEG6vXG833mE0uJ4hzxnzjKPspUYD95gLG21cuBLl4yeM52Gi3bqB9Sc8RcSQpl8gLcNce-h9VZmE_J4pCnS3eIDNwZT_UBP7tjuQ6ILpourxpn_f3YmUzKvOfROuLFfCPi4_TqMXHemEJvnzUUahtLtx8G8TlmUDAU9vQk7KjDiLtgbJAf7lLn9hoU01YnfAMEgLkkdtpwRAk6h12tbA7pD3eapjdwDuQAjGOj2_a1eVfAp5wjimCD_VYQJXTj8VHtiZ5-qD_F2Dd5PmnytK5o1zx3ceTQyEPGehYFeqzijqE7HjKleT2fmK-fcBWRswtL9Y5w8IJSDI4TLE0TtuCGwmaiSWwex2s3NJmLUJ7M2NuIu6m1TNfeyN7-l63HCpG4PXCO2CizzMQp1Yyb09EVq1cQ_VPweEXq1Xl9su2dOfbcX-_l_qib4KevCXIsL_aSJsO-hn1iWDTX8aHzbvx0wuPrDhrqrUYrYdVmdklBQEgLbhsVjvo8HwF___3sg_d9Vivs2XsxNG77JQdOYRvs7aHo5Gkl338rdhyQMkptz77KH6K71fMi8zGLRqgvTsiE-oUsveGcN7AxzxnNYv6FjQeWCxqo9eLjlC6A5ClNpEFOe32aITVrk44nDWx2M7s0KO2ZdmWQVVK4HeDqoFA5MOCRGJVOx0PrCLGK3EdmLKEauWs_kC9V9pyAGn27ScrbadKzv4HsPUOfG8kvwcpizXdC_EgeVlsFxOGGpuOl9nTmCh7DrNxNLkdwl2V1MCZfkLY6dKP33Hb5w4xrUzV5UrgLgkt6rXDmfiHDE28HYz-KHOmb16UUK67CEUnmYAt38XSyjwLA7Jt-aHAz1e6iSbPG2PexE.fPOiZh0ZOgXgPdtzUmV_vQ
*/
try
{
// Convert PEM private key to RSA object
RSA rsaPrivateKey = LoadPrivateKeyFromPem(privateKeyPem);
// Create RSA security key for decryption
var rsaSecurityKey = new RsaSecurityKey(rsaPrivateKey);
var validationParameters = new TokenValidationParameters
{
TokenDecryptionKey = rsaSecurityKey
};
// Decrypt the JWE token
var claimsPrincipal = handler.ValidateToken(jweToken, validationParameters, out var securityToken);
// You can now access the decrypted claims
Console.WriteLine("Decrypted claims:");
foreach (var claim in claimsPrincipal.Claims)
{
Console.WriteLine($"{claim.Type}: {claim.Value}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
//private.pem file (string decryptionKeyInput)
/*
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDKiKyfq8/SUQk0
o6Tc5rReV9HWA28YGP1TwWi7MolB6G7Bf4OoPEds1PFdUXAbbfLHwRF4v9ZBTY3d
cORNIfT8ZyY9RSxwoO6TVEXAUYsOafEp2mzmv93gpvh4ct9LZKkhSbSibkU11oEE
9vWcroHMVelUsJ59j9P7UtdJfjlOvm4x3sntjy0f3Lg8Lf6eltO1qxFVofxsOX2r
+/e1a7fJb6aZspBvK5WmoeJuiGR+F6OxvNp6LlvgQGz8aNK2F1E2yW6YUIwMkLhw
X1qXuvHEMtTctAISdQUHnSusJ/9vjEK7oZmGzt47GAFVcngbJchCRzmbu8Vh7Smv
in+xahR1AgMBAAECggEADVXzAd97A2btE3979USmlziymyQmPkC0+30Wc48IDSQs
GMcX6O2xKUgbLXEVj+TNMdxzVU9SYQHlh7FtguuruSvkj2+81ZyvINnRbvCflp8g
r0gP2CDFkAuGfE3aCJmT7lpvT6uxmHIrlCNbuEmgR89XWgl4Ih3kkB2cCd2LEfVn
iLqVY+zAkvCW9nQ8ap8xLSdJ1JIWxCLK3VWeO0OU1U/EabwtcDyGdJvtpWp8UQfK
VJuRNJedsFaplxWkM3fAhsIpEdKwQ1yHqc0+Buc5BtFdMj2dbq/ydo2VZ1BNvcO0
b23fnkw6l5Gh50xoT5vz6tuIkGcDxk+SB28wtdvAUQKBgQDl1HRiQQe6J9MrASjJ
zsNQAV/JPb5LeXutTYOnJsbgr9Wxjyt+kfJ8a2MHUdFt/nmeEtJoeDevhR2tR2ly
8TCVGSaYxTSWmbmmwCAa9vrlV4Ei7Qgyr+9BALagVcCx4GH8fmHQ598d0q91Ctqb
zAior/6jTeFyiW+f9lUQxnG7EQKBgQDhmIpUTdLsvGB3xG8ItmY0zApw31fX6Tsy
O2kFFq+hq3lvHa8eTDioNdbM6cbc5ic/bHdlhnXoWcAcfZ6GVqJ7eyo1h+Ztm31a
quYMrKUPX6JnQVt5dw5SYEUnkxwe6UwMPdqO9k0H80ndMwITGB6AREoiW7NOqKeF
AcOvT8tbJQKBgCi9RTgZcOY1ov/vf6xuIz7uT21brXyxdxPcNqcNf5lacdW8nCge
dM5LNs2YWjhWMHatvXBZRv2s6frKOs3uJP946tePtWewrjD5w3ckKos2vKRVQevC
NfXey4CWUsb1EElymaIvR+SAcSudFe0h+LL2J3wJFRp5dDj1sFR96LERAoGAKaiH
csXkOz8V+UfW0R8NhJZhHzK+/+nbuozp+byUth/6DqDGo6ujkrxObAyHYmdFvBqF
ecP4pe1c4mX4DgqVeoPl6Xis/nSGE2YXkSOYX1xjmvmgsK9hf6izXHl36eVe26vY
XinxU5SDgUtYCLqdd0YlAm84jz/pn1ASGJ99h9kCgYBbMjqWBJlowrpIn4ETFpDY
VOhgIgvg8blAi0d0xi+0D48k8iMg1cBU6/0RZsNuXR7Vf7Qls+Gqf2kRop6fR+1n
Qiysm/nzzpLKNRsU+7tZvJ3Ybp9Nw/DC8Hl/zMnQva9JEfnu+tH6iqcNOXrJRP4N
5dI4kF52AUbUSDd61VP7sQ==
-----END PRIVATE KEY-----
*/
static RSA LoadPrivateKeyFromPem(string privateKeyPem)
{
// Load RSA private key from PEM format
using var key = RSA.Create();
**key.ImportFromPem(privateKeyPem);** // this throws no exception but doens't seem to create an RSA object either.
return key;
}
}
}
Your use of using var key = RSA.Ceate()
is causing the return of your function to call RSA.Dispose()
before it can be used correctly by the calling code.
You could start by changing your code to:
static RSA LoadPrivateKeyFromPem(string privateKeyPem)
{
var key = RSA.Create();
key.ImportFromPem(privateKeyPem);
return key;
}