javac#encryptionrsajwe

How to decrypt JWE source (encrypted with RSA1_5 A256CBC-HS512) in C#?


I am implementing a client for communicate with some server by the cryptological way. The client sends get request with public RSA key to the server. Documentation "how to communicate with server" has the sample with java code. The following code generates the public key:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keypair = keyGen.genKeyPair();
byte[] pubKeyBytes = keypair.getPublic().getEncoded();

I need to implement my client in C#. I found the way how to do the same in C#:

var rsa = new RSACryptoServiceProvider(2048);
var parameters = _rsa.ExportParameters(includePrivateParameters: false);

The client uses parameters and solution from How to adapt public/private RSA keys of C# for using them as in Java? That's ok. The client can generate the key which can pass verification on the server. As result, I have the encrypted response and trying to decrypt it.

responseContent = rsa.Decrypt(responseContent)

But this code throws following exception:

System.Security.Cryptography.CryptographicException: 'The data to be decrypted exceeds the maximum for this modulus of 256 bytes.'

responseContent is byte array with length 250996. And as I see there is impossible to decrypt response content by way above.

From the documentation, I know that

enter image description here

Also, I have an example how to decrypt response in java:

JWEObject jweObject = JWEObject.parse(encryptedPayload); 
RSAPrivateKey rsaPrivatteKey = (RSAPrivateKey)KeyFactory
    .getInstance("RSA")
    .generatePrivate(new PKCS8EncodedKeySpec(keybytes));
RSADecrypter RSADecrypter rsaDecrypter= new RSADecrypter(rsaPrivateKey);
JWEObject jweObject.decrypt(rsaDecrypter); 
String decryptedResponse = jweObject.getPayload().toString();

I thought that rsa.Decrypt is analog of code above. But as I sow - not. After some research, I found that my response is JWE source. Based on https://www.rfc-editor.org/rfc/rfc7516 I split my response to parts which was separated by '.' and decode each of them from base64url. As result I have:

I think the main content is in Cipertext and I need to decrypt it. But I don't know how because of the Cipertext size is more than 256 bytes and I can't use rsa.Decrypt.

How to decrypt source when size of it is more than RSA key?


Solution

  • I found this library js-jose that can do exactly what I need. I added it as NuGet package, written following code:

     JWT.Decode(responseContent, // content as String read from Response
                rsa, // RSACryptoServiceProvider
                JweAlgorithm.RSA1_5, 
                JweEncryption.A256CBC_HS512); 
    

    and has decrypted content as result.