如何在 C# 中解密 JWE 源代码(使用 RSA1_5 A256CBC-HS512 加密)?
How to decrypt JWE source (encrypted with RSA1_5 A256CBC-HS512) in C#?
我正在实现一个客户端,用于通过密码学方式与某些服务器进行通信。客户端向服务器发送带有 public RSA 密钥的获取请求。文档“如何与服务器通信”包含带有 java 代码的示例。以下代码生成 public 键:
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);
客户端使用来自的参数和解决方案,没关系。客户端可以生成可以在服务器上通过验证的密钥。
结果,我得到了加密的响应并尝试对其进行解密。
responseContent = rsa.Decrypt(responseContent)
但是此代码抛出以下异常:
System.Security.Cryptography.CryptographicException: 'The data to be
decrypted exceeds the maximum for this modulus of 256 bytes.'
responseContent是字节数组,长度为250996。而且我看到不可能通过上面的方式解密响应内容。
根据文档,我知道
此外,我有一个示例如何解密 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://www.rfc-editor.org/rfc/rfc7516,我将我的回复拆分为以“.”分隔的部分。并从 base64url 解码它们中的每一个。结果我有:
- Header(即 JSON: {"enc":"A256CBC-HS512", "alg":"RSA1_5"})
- 加密密钥(大小 256 字节)
- 初始化向量(大小 16 字节)
- 密文(大小 1844688 字节)
- 身份验证标记(大小 32 字节)
我认为主要内容在Cipertext中,我需要对其进行解密。但我不知道是怎么回事,因为 Cipertext 大小超过 256 字节,我不能使用 rsa.Decrypt.
当源文件的大小大于 RSA 密钥时,如何解密源文件?
我发现这个库 js-jose 可以完全满足我的需要。我将它添加为 NuGet 包,编写如下代码:
JWT.Decode(responseContent, // content as String read from Response
rsa, // RSACryptoServiceProvider
JweAlgorithm.RSA1_5,
JweEncryption.A256CBC_HS512);
并解密了内容。
我刚刚使用 .NET6 完成了一个实验性控制台应用程序,以熟悉 JWT、JWS 和 JWE 的概念。
也许这可以帮助某人...
我想让它在不使用任何第三方包的情况下工作。
这些都是 using 语句:
using Microsoft.IdentityModel.Tokens;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
您将需要一个 TokenValidationParameters object 来配置验证。
为此,您需要:
- 一个public验证签名的密钥
- 用于解密 header 和有效载荷的私钥
为了演示目的,这两个都存储在本地。
// Get public key to verify the signature
string publicKeySign = File.ReadAllText(@"C:\Docs\publicKeySign.pem");
var rsaPublicKey = RSA.Create();
rsaPublicKey.ImportFromPem(publicKeySign);
// Get private key to decrypt
string privateKeyEncrypt = File.ReadAllText(@"C:\Docs\privateKeyEncrypt.key");
rsaPrivateKey = RSA.Create();
rsaPrivateKey.ImportFromPem(privateKeyEncrypt);
// Pass those keys into the TokenValidationParameters object
var validationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = "http://mysite.example.com",
ValidAudience = "http://myaudience.example.com",
IssuerSigningKey = new RsaSecurityKey(rsaPublicKey),
TokenDecryptionKey = new RsaSecurityKey(rsaPrivateKey)
};
// Pass in the token (as a string) and your tokenValidationParameters
JwtSecurityTokenHandler jwtSecurityTokenHandler = new();
TokenValidationResult result = await jwtSecurityTokenHandler.ValidateTokenAsync(token, tokenValidationParameters);
结果是 TokenValidationResult、MS Docs here。它具有以下属性:
- 声明,这是一个字典
- ClaimsIdentity,它又具有 属性:
- 声明,这是一个 IEnumerable
这样,您就可以检查与 JWE 一起发送的声明。
希望这对您有所帮助,祝您玩得愉快!
我正在实现一个客户端,用于通过密码学方式与某些服务器进行通信。客户端向服务器发送带有 public RSA 密钥的获取请求。文档“如何与服务器通信”包含带有 java 代码的示例。以下代码生成 public 键:
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);
客户端使用来自
responseContent = rsa.Decrypt(responseContent)
但是此代码抛出以下异常:
System.Security.Cryptography.CryptographicException: 'The data to be decrypted exceeds the maximum for this modulus of 256 bytes.'
responseContent是字节数组,长度为250996。而且我看到不可能通过上面的方式解密响应内容。
根据文档,我知道
此外,我有一个示例如何解密 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://www.rfc-editor.org/rfc/rfc7516,我将我的回复拆分为以“.”分隔的部分。并从 base64url 解码它们中的每一个。结果我有:
- Header(即 JSON: {"enc":"A256CBC-HS512", "alg":"RSA1_5"})
- 加密密钥(大小 256 字节)
- 初始化向量(大小 16 字节)
- 密文(大小 1844688 字节)
- 身份验证标记(大小 32 字节)
我认为主要内容在Cipertext中,我需要对其进行解密。但我不知道是怎么回事,因为 Cipertext 大小超过 256 字节,我不能使用 rsa.Decrypt.
当源文件的大小大于 RSA 密钥时,如何解密源文件?
我发现这个库 js-jose 可以完全满足我的需要。我将它添加为 NuGet 包,编写如下代码:
JWT.Decode(responseContent, // content as String read from Response
rsa, // RSACryptoServiceProvider
JweAlgorithm.RSA1_5,
JweEncryption.A256CBC_HS512);
并解密了内容。
我刚刚使用 .NET6 完成了一个实验性控制台应用程序,以熟悉 JWT、JWS 和 JWE 的概念。
也许这可以帮助某人...
我想让它在不使用任何第三方包的情况下工作。 这些都是 using 语句:
using Microsoft.IdentityModel.Tokens;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
您将需要一个 TokenValidationParameters object 来配置验证。 为此,您需要:
- 一个public验证签名的密钥
- 用于解密 header 和有效载荷的私钥
为了演示目的,这两个都存储在本地。
// Get public key to verify the signature
string publicKeySign = File.ReadAllText(@"C:\Docs\publicKeySign.pem");
var rsaPublicKey = RSA.Create();
rsaPublicKey.ImportFromPem(publicKeySign);
// Get private key to decrypt
string privateKeyEncrypt = File.ReadAllText(@"C:\Docs\privateKeyEncrypt.key");
rsaPrivateKey = RSA.Create();
rsaPrivateKey.ImportFromPem(privateKeyEncrypt);
// Pass those keys into the TokenValidationParameters object
var validationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = "http://mysite.example.com",
ValidAudience = "http://myaudience.example.com",
IssuerSigningKey = new RsaSecurityKey(rsaPublicKey),
TokenDecryptionKey = new RsaSecurityKey(rsaPrivateKey)
};
// Pass in the token (as a string) and your tokenValidationParameters
JwtSecurityTokenHandler jwtSecurityTokenHandler = new();
TokenValidationResult result = await jwtSecurityTokenHandler.ValidateTokenAsync(token, tokenValidationParameters);
结果是 TokenValidationResult、MS Docs here。它具有以下属性:
- 声明,这是一个字典
- ClaimsIdentity,它又具有 属性:
- 声明,这是一个 IEnumerable
这样,您就可以检查与 JWE 一起发送的声明。 希望这对您有所帮助,祝您玩得愉快!