如何在C#中解密JWE源(用RSA1_5 A256CBC-HS512加密)?

时间:2018-03-16 19:37:17

标签: java c# encryption rsa jwe

我正在实现一个客户端,通过密码方式与某些服务器进行通信。客户端将带有公共RSA密钥的get请求发送到服务器。文档“如何与服务器通信”的示例包含java代码。以下代码生成公钥:

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

我需要在C#中实现我的客户端。我在C#中找到了如何做同样的方式:

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

客户端使用来自How to adapt public/private RSA keys of C# for using them as in Java?的参数和解决方案。没关系。客户端可以生成可以在服务器上通过验证的密钥。 结果,我有加密的响应并试图解密它。

responseContent = rsa.Decrypt(responseContent)

但是此代码抛出以下异常:

  

System.Security.Cryptography.CryptographicException:'数据是   解密超过了这个256字节模数的最大值。'

responseContent 是字节数组,长度为250996.正如我所见,无法通过上面的方式解密响应内容。

从文档中我知道

enter image description here

另外,我有一个例子如何在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();

我认为rsa.Decrypt类似于上面的代码。但是当我播种时 - 不是。 经过一番研究,我发现我的回答是JWE来源。 基于https://tools.ietf.org/html/rfc7516我将我的回复拆分为由'。'分隔的部分。并从base64url解码它们中的每一个。结果我有:

  • 标题(JSON:{“enc”:“A256CBC-HS512”,“alg”:“RSA1_5”})
  • 加密密钥(大小为256字节)
  • 初始化向量(大小为16字节)
  • Cipertext(大小1844688字节)
  • Auntification Tag(大小为32字节)

我认为主要内容是在 Cipertext 中,我需要解密它。但我不知道因为 Cipertext 大小超过256字节而且我不能使用rsa.Decrypt。

如果源的大小超过RSA密钥,如何解密源?

1 个答案:

答案 0 :(得分:1)

我发现这个库js-jose可以完全满足我的需要。我把它添加为NuGet包,代码如下:

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

并将结果解密。