I think this question is not a dupe, so I will try to explain my situation.
I'm testing JWT, more specifically JOSE-JWT lib from Github, and well, I'm having troubles.
I'm generating a private-public key pair and sending to the client the public key, using PHP and phpseclib. Everything is correct as you can see there. My client is receiving the JSON and converting it to a object and extracting it to a string using JSON.NET.
I'm using BouncyCastle and an answer from Stackoverflow with a little modifications to read directly from a string instead from a File.
public static RSACryptoServiceProvider GetRSAProviderFromPemFile(string pemfile) { return GetRSAProviderFromPemString(File.ReadAllText(pemfile).Trim()); } public static RSACryptoServiceProvider GetRSAProviderFromPemString(string pemstr) { bool isPrivateKeyFile = true; if (pemstr.StartsWith(pempubheader) && pemstr.EndsWith(pempubfooter)) isPrivateKeyFile = false; byte[] pemkey; if (isPrivateKeyFile) pemkey = DecodeOpenSSLPrivateKey(pemstr); else pemkey = DecodeOpenSSLPublicKey(pemstr); if (pemkey == null) return null; if (isPrivateKeyFile) return DecodeRSAPrivateKey(pemkey); else return DecodeX509PublicKey(pemkey); }
And both of them are giving me problems, with the answer and using docs from Jose repo:
var payload1 = new Dictionary<string, object>() { { "sub", "mr.x@contoso.com" }, { "exp", 1300819380 } }; Console.WriteLine("Jose says: {0}", JWT.Encode(payload1, pubkey, JwsAlgorithm.RS256));
Exception:
Image may be NSFW.
Clik here to view.
English equivalent:http://unlocalize.com/es/74799_Keyset-does-not-exist.html
And with Bouncy Castle:
var claims = new List<Claim>(); claims.Add(new Claim("claim1", "value1")); claims.Add(new Claim("claim2", "value2")); claims.Add(new Claim("claim3", "value3")); Console.WriteLine("Bouncy Castle says: {0}", Helpers.CreateToken(claims, pubkeyStr));
Exception:
Image may be NSFW.
Clik here to view.
CreateToken method extracted from here: https://stackoverflow.com/a/44857593/3286975
I did a little modification to this method:
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(keyPair.Public as RsaKeyParameters); //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); } }
In both cases is like the encrypter methods are looking for the private key (in the client client????)... So, My question is why this examples are using private keys in the client-side, if the Wikipedia says this:
Image may be NSFW.
Clik here to view.
Source:https://en.wikipedia.org/wiki/Public-key_cryptography
And in several cases I found what I think is right:
https://connect2id.com/products/nimbus-jose-jwt/examples/jwt-with-rsa-encryption
In this Java example, this uses public key to encrypt data, not private one.
I don't know why C# examples are using private keys in the client-side, this is ilogical, can somebody explain me why, and how can I solve this problems?