2016-08-05 200 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);