如何使用rs256算法使用我自己的rsa私钥来签名字节?

我有自己的私钥字符串,即

-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQCSAYYgzvGTww.... .... .... ..... 3yUMYj9oYzqdrRHP0XgD0cEEvyqPBwLaNsRdFwy5qTiHjj0f+ZWHQWmqcoLmmpzyZEbIvQm/VhbjRF6iKG4WZ9Hfa7ntYRNGdWgD/KMIeZI= -----END RSA PRIVATE KEY----- 

现在,我需要在C#中使用此私钥签署我的声明集以生成JWT有效负载。

我写了以下代码:

 var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); var issueTime = DateTime.Now; var iat = (int)issueTime.Subtract(utc0).TotalSeconds; var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds; var payload = new { iss = email, prn = prn, scope = "scope", aud = "https://example.com", exp = exp, iat = iat }; var segments = new List(); var header = new { typ = "JWT", alg = "RS256" }; byte[] headerBytes = Encoding.UTF8.GetBytes(jsonSerializer.Serialize(header)); byte[] payloadBytes = Encoding.UTF8.GetBytes(jsonSerializer.Serialize(payload)); segments.Add(Base64UrlEncode(headerBytes)); segments.Add(Base64UrlEncode(payloadBytes)); var stringToSign = string.Join(".", segments.ToArray()); var bytesToSign = Encoding.UTF8.GetBytes(stringToSign); 

现在我需要这些bytesToSign由我的私钥签名,正如我上面提到的使用rs256 alogorithm。 有人可以帮忙吗?

我按照以下内容更新了我的代码:

 var pemprivatekey = OpenSSLKey.DecodeOpenSSLPrivateKey(privateKey); RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(); if (pemprivatekey != null) { rsaProvider = OpenSSLKey.DecodeRSAPrivateKey(pemprivatekey); } byte[] signature = rsaProvider.SignData(bytesToSign, "SHA256"); segments.Add(Base64UrlEncode(signature)); return string.Join(".", segments.ToArray()); 

并生成JWT令牌。 请告诉我错误的地方,因为它不正确:当我将它传递给API时,它不起作用并抛出错误。

我最近不得不实现类似的东西,并在签署我的有效负载时遇到错误“无效的算法指定”,所以解决了我认为我将共享代码的具体问题。 我认为这也可能对你有用。

您可以在Karama.Jwt.Public找到完整的解释[ReadME] [2]和源代码。 我碰巧使用不同的库来生成我的JWT,即JOSE,但我认为这是偶然的,并且为了完整性,有一个项目使用没有第三方库实现相同的目的。

请告诉我你是怎么过的。

我会逐步列出我的答案

  1. 为此,您需要安装一个包来获取名为Jose-jwt的库。 这代表JavaScript Object Signing and Encrypting。 从NuGet包管理器Install-package Jose-jwt
  2. 使用OpenSSL,以PKCS12文件(* .p12)的forms打包您的私钥,您将在此过程中为该文件设置密码。

     openssl pkcs12 -export -nocerts -in ./myKey.key -out my-Key.p12 
  3. 如图书馆自述文件中所列,您需要从该文件生成RSACryptoServiceProvider ,如下所示:

     var privateKey=new X509Certificate2("my-key.p12", "password", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet).PrivateKey as RSACryptoServiceProvider; 
  4. 使用在PKCS12打包期间设置的密码创建的RSACryptoServiceProvider对您的有效负载进行编码,如下所示:

     string token=Jose.JWT.Encode(payload, privateKey, JwsAlgorithm.RS256); 

我找到了一些纯粹的基于Javascript的解决方案,如果它对任何人都有用。 你可以在这里找到JS库。

它解决了我的要求。