2016-08-05 613 views
3

我正在使用jose-jwt library并希望在C#中使用RS256算法创建加密的JWT以进行加密。我没有密码学经验,所以请原谅我的无知。我看到在文档下面的例子:如何使用RS256和RSA私钥在C#中创建加密的JWT

var payload = new Dictionary<string, object>() 
{ 
    { "sub", "[email protected]" }, 
    { "exp", 1300819380 } 
}; 

var privateKey=new X509Certificate2("my-key.p12", "password", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet).PrivateKey as RSACryptoServiceProvider; 

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

这说明使用p12文件,但如何使用下面的表格的RSA密钥文件?我正在查看X509Certificate2的文档,但我没有看到RSA私钥的选项。它似乎只接受PKCS7,我知道这是公钥。

-----BEGIN RSA PRIVATE KEY----- 
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp 
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5 
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh 
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2 
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX 
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il 
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF 
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k 
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl 
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ 
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0= 
-----END RSA PRIVATE KEY----- 

最后,就是在docs列出的两个选项之间的差异,以及我如何在两者之间选择?

--------------------------选项1 ---------------- ----------

RS- *和* PS-家庭

CLR:

RS256,RS384,RS512和PS256,PS384,PS512签名要求 的RSACryptoServiceProvider(通常是私人)对应的长度为 的密钥。 CSP需要被迫使用Microsoft增强型RSA和AES密码提供程序。通常可以做的是重新导入 RSAParameters。有关详细信息,请参见http://clrsecurity.codeplex.com/discussions/243156

--------------------------选项2 ------------------ --------

CORECLR:RS256,RS384,RS512签名需要相应长度的RSA(通常为私钥)。

+0

只是为了检查...你的帖子中的关键......这是一个测试的关键,对吧? – vcsjones

+2

@vcsjones是的,我不想展示我真正的钥匙。 – FullStack

回答

1

我知道这个帖子是老了,但我花了永远摸不着头脑,所以我想我也有同感。

为了测试我使用创建RSA密钥的OpenSSL:

openssl genrsa -out privateKey.pem 512 
openssl rsa -in privateKey.pem -pubout -out publicKey.pem 

您将需要以下2个的NuGet包:

  1. https://github.com/dvsekhvalnov/jose-jwt
  2. http://www.bouncycastle.org/csharp/

测试代码

public static void Test() 
{ 
     string publicKey = File.ReadAllText(@"W:\Dev\Temp\rsa_keys\publicKey.pem"); 
     string privateKey = File.ReadAllText(@"W:\Dev\Temp\rsa_keys\privateKey.pem"); 

     var claims = new List<Claim>(); 
     claims.Add(new Claim("claim1", "value1")); 
     claims.Add(new Claim("claim2", "value2")); 
     claims.Add(new Claim("claim3", "value3")); 

     var token = CreateToken(claims, privateKey); 
     var payload = DecodeToken(token, publicKey); 
    } 

创建令牌

public static string CreateToken(List<Claim> claims, string privateRsaKey) 
    { 
     RSAParameters rsaParams; 
     using (var tr = new StringReader(privateRsaKey)) 
     { 
      var pemReader = new PemReader(tr); 
      var keyPair = pemReader.ReadObject() as AsymmetricCipherKeyPair; 
      if (keyPair == null) 
      { 
       throw new Exception("Could not read RSA private key"); 
      } 
      var privateRsaParams = keyPair.Private as RsaPrivateCrtKeyParameters; 
      rsaParams = DotNetUtilities.ToRSAParameters(privateRsaParams); 
     } 
     using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) 
     { 
      rsa.ImportParameters(rsaParams); 
      Dictionary<string, object> payload = claims.ToDictionary(k => k.Type, v => (object)v.Value); 
      return Jose.JWT.Encode(payload, rsa, Jose.JwsAlgorithm.RS256); 
     } 
    } 

解码令牌

public static string DecodeToken(string token, string publicRsaKey) 
    { 
     RSAParameters rsaParams; 

     using (var tr = new StringReader(publicRsaKey)) 
     { 
      var pemReader = new PemReader(tr); 
      var publicKeyParams = pemReader.ReadObject() as RsaKeyParameters; 
      if (publicKeyParams == null) 
      { 
       throw new Exception("Could not read RSA public key"); 
      } 
      rsaParams = DotNetUtilities.ToRSAParameters(publicKeyParams); 
     } 
     using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) 
     { 
      rsa.ImportParameters(rsaParams); 
      // This will throw if the signature is invalid 
      return Jose.JWT.Decode(token, rsa, Jose.JwsAlgorithm.RS256); 
     } 
    } 

我发现https://jwt.io/一个很好的资源如果您使用公共证书和.NET 4.6来测试您的令牌

0

,为您可以使用解码:

string token = "eyJhbGciOiJSUzI1NiIsInR...."; 
string certificate = "MIICnzCCAYcCBgFd2yEPx...."; 
var publicKey = new X509Certificate2(Convert.FromBase64String(certificate)).GetRSAPublicKey(); 
string decoded = JWT.Decode(token, publicKey, JwsAlgorithm.RS256); 
+0

签名是使用私钥生成的。因此这不起作用... –

0
  1. RS256是一个签名算法不是一种加密算法
  2. 加密与公共密钥
  3. 这里所做的是建立一个加密的智威汤逊代码:

    var cert = new X509Certificate2(".\\key.cer"); 
    var rsa = (RSACryptoServiceProvider) cert.PublicKey.Key; 
    
    var payload = new Dictionary<string, object>() 
    { 
        {"sub", "[email protected]"}, 
        {"exp", 1300819380} 
    }; 
    
    var encryptedToken = 
        JWT.Encode(
        payload, 
        rsa, 
        JweAlgorithm.RSA_OAEP, 
        JweEncryption.A256CBC_HS512, 
        null); 
    
相关问题