在 Jose-JWT 中使用 public 密钥加密
Encryption with public key in Jose-JWT
我认为这个问题不是骗人的,所以我会尽量解释我的情况。
我正在测试 JWT,更具体地说 JOSE-JWT lib 来自 Github,嗯,我遇到了麻烦。
我正在生成私有-public 密钥对并使用 PHP 和 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.
向客户端发送 public 密钥
我正在使用 BouncyCastle and an answer from Whosebug 并稍加修改以直接从字符串而不是文件中读取。
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);
}
他们都给我问题,答案和使用 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));
异常:
对应的英文: http://unlocalize.com/es/74799_Keyset-does-not-exist.html
还有充气城堡:
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));
异常:
CreateToken 方法从这里提取:
我对这个方法做了一点修改:
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);
}
}
在这两种情况下,加密方法都在寻找私钥(在客户端????)...所以,我的问题是为什么这个例子在客户端使用私钥,如果维基百科是这样说的:
来源: https://en.wikipedia.org/wiki/Public-key_cryptography
并且在一些情况下我发现我认为是正确的:
https://connect2id.com/products/nimbus-jose-jwt/examples/jwt-with-rsa-encryption
在此 Java 示例中,这使用 public 密钥来加密数据,而不是私有密钥。
我不知道为什么 C# 示例在客户端使用私钥,这是不合逻辑的,有人能解释一下为什么吗,我该如何解决这个问题?
我找到了我遇到的两个问题之一的答案,而且我还没有完全阅读 JOSE-JWT 存储库,它说:
var payload = new Dictionary<string, object>()
{
{ "sub", "mr.x@contoso.com" },
{ "exp", 1300819380 }
};
var publicKey=... //Load it from there you need
string token = Jose.JWT.Encode(payload, publicKey, JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM);
我发现Bouncy Castle只是一个API来操作public私钥,加解密工作由JOSE-JWT完成。那么,我的问题就解决了。
我认为这个问题不是骗人的,所以我会尽量解释我的情况。
我正在测试 JWT,更具体地说 JOSE-JWT lib 来自 Github,嗯,我遇到了麻烦。
我正在生成私有-public 密钥对并使用 PHP 和 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.
向客户端发送 public 密钥我正在使用 BouncyCastle and an answer from Whosebug 并稍加修改以直接从字符串而不是文件中读取。
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);
}
他们都给我问题,答案和使用 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));
异常:
对应的英文: http://unlocalize.com/es/74799_Keyset-does-not-exist.html
还有充气城堡:
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));
异常:
CreateToken 方法从这里提取:
我对这个方法做了一点修改:
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);
}
}
在这两种情况下,加密方法都在寻找私钥(在客户端????)...所以,我的问题是为什么这个例子在客户端使用私钥,如果维基百科是这样说的:
来源: https://en.wikipedia.org/wiki/Public-key_cryptography
并且在一些情况下我发现我认为是正确的:
https://connect2id.com/products/nimbus-jose-jwt/examples/jwt-with-rsa-encryption
在此 Java 示例中,这使用 public 密钥来加密数据,而不是私有密钥。
我不知道为什么 C# 示例在客户端使用私钥,这是不合逻辑的,有人能解释一下为什么吗,我该如何解决这个问题?
我找到了我遇到的两个问题之一的答案,而且我还没有完全阅读 JOSE-JWT 存储库,它说:
var payload = new Dictionary<string, object>()
{
{ "sub", "mr.x@contoso.com" },
{ "exp", 1300819380 }
};
var publicKey=... //Load it from there you need
string token = Jose.JWT.Encode(payload, publicKey, JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM);
我发现Bouncy Castle只是一个API来操作public私钥,加解密工作由JOSE-JWT完成。那么,我的问题就解决了。