我正在使用jose-jwt库,并希望使用RS256算法在C#中创建加密的JWT进行加密.我没有密码学的经验,所以请原谅我的无知.我在文档中看到以下示例:
var payload = new Dictionary() { { "sub", "mr.x@contoso.com" }, { "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-----
最后,文档中列出的两个选项有什么区别,我如何在两者之间做出选择?
- - - - - - - - - - - - - 选项1 - - - - - - - - - - - ----
RS-*和PS-*系列
CLR:
RS256,RS384,RS512和PS256,PS384,PS512签名需要相应长度的RSACryptoServiceProvider(通常是私有)密钥.需要强制CSP使用Microsoft增强RSA和AES加密提供程序.通常可以重新导入RSAParameters.有关 详细信息,请参见http://clrsecurity.codeplex.com/discussions/243156.
-------------------------- OPTION 2 ---------------------- ----
CORECLR:RS256,RS384,RS512签名需要相应长度的RSA(通常是私有)密钥.
小智.. 21
我知道这篇文章很老了,但我花了很长时间才想到这一点,所以我想我会分享.
要测试我使用OpenSSL创建了RSA密钥:
openssl genrsa -out privateKey.pem 512 openssl rsa -in privateKey.pem -pubout -out publicKey.pem
您将需要以下2个nuget包:
https://github.com/dvsekhvalnov/jose-jwt
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(); 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(Listclaims, 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 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/是一个很好的资源来测试你的令牌
我知道这篇文章很老了,但我花了很长时间才想到这一点,所以我想我会分享.
要测试我使用OpenSSL创建了RSA密钥:
openssl genrsa -out privateKey.pem 512 openssl rsa -in privateKey.pem -pubout -out publicKey.pem
您将需要以下2个nuget包:
https://github.com/dvsekhvalnov/jose-jwt
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(); 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(Listclaims, 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 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/是一个很好的资源来测试你的令牌