5

I need to create custom tokens that need to be signed using a key provided by Google. The key is provided as text, like -----BEGIN PRIVATE KEY-----\nMIIE....

I had this working by using BouncyCastle to read the PEM key and get the RSA keys, but now I need this project to run under Linux so I can't use BouncyCastle as it only works under Windows (it makes uses of RSACryptoServiceProvider).

So, is there a way I can achieve the same result but using only .NET Standard code?

I already tried to convert the PEM file to a PFX file, but I don't have any certificates. Tried to get the certificates from here or here didn't work (OpenSSL says that the certificates don't belong to the key provided).

Matheus Lacerda
  • 5,983
  • 11
  • 29
  • 45
CheloXL
  • 167
  • 2
  • 9
  • i am not a c# developer but this library https://github.com/dvsekhvalnov/jose-jwt may help you to generate JWT – rkj Jun 11 '18 at 14:06
  • I don't need a way to generate the JWT. I can do that. I need a way to provide to the JWT generator the key to sign/encrypt it. – CheloXL Jun 11 '18 at 15:13

3 Answers3

5

You can convert your PEM file to p12 file and signed your JWT with that p12

var payload = new Dictionary<string, object>()
{
    { "sub", "mr.x@contoso.com" },
    { "exp", 1300819380 }
};

var privateKey=new X509Certificate2("my-key.p12", "password").GetRSAPrivateKey();

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

Here is the details link https://github.com/dvsekhvalnov/jose-jwt#rs--and-ps--family

rkj
  • 8,067
  • 2
  • 27
  • 33
  • How to decode it? I'm trying to decode it. Can you please help? I posted the question here: https://stackoverflow.com/questions/71281539/c-jwt-bearer-token-authentication-failure-unauthorized – TheDeveloper Feb 28 '22 at 23:06
2

The PemUtils library will do exactly what you need, it decodes the PEM and DER data without the use of RSACryptoServiceProvider. It's available as a NuGet package and in case you have any additional needs, I'm the author of that library, so feel free to open an issue on github.

Something like this should work:

using (var stream = File.OpenRead(path))
using (var reader = new PemReader(stream))
{
    var rsaParameters = reader.ReadRsaKey();
    var key = new RsaSecurityKey(RSA.Create(rsaParameters));
    var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.RsaSha256);
}
huysentruitw
  • 27,376
  • 9
  • 90
  • 133
0

Just to expand on the solution, this is the full code, working (this is for firebase auth tokens):

var privateKey = new X509Certificate2("cert.p12", "password");
var credentials = new SigningCredentials(new X509SecurityKey(privateKey), SecurityAlgorithms.RsaSha256);
var claims = new List<Claim>(8)
{
    new Claim(JwtRegisteredClaimNames.Sub, "firebase-adminsdk-vifbe@your-service.iam.gserviceaccount.com"),
};

var tokenHandler = new JwtSecurityTokenHandler();
return tokenHandler.CreateEncodedJwt(
    "firebase-adminsdk-vifbe@your-service.iam.gserviceaccount.com",
    "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
    new ClaimsIdentity(claims),
    DateTime.UtcNow.AddSeconds(-60),
    DateTime.UtcNow.AddSeconds(10 * 60),
    DateTime.UtcNow,
    _credentials
);
CheloXL
  • 167
  • 2
  • 9