Я думаю, что этот вопрос не дурак, поэтому я попытаюсь объяснить мою ситуацию.
Я тестирую JWT, точнее JOSE-JWT lib от Github, и, ну, у меня проблемы.
Я генерирую пару секретный-открытый ключ и отправляю клиенту открытый ключ, используя PHP и phpseclib . Все правильно, как вы можете видеть там . Мой клиент получает JSON и преобразует его в объект и извлекает его в строку, используя JSON.NET .
Я использую BouncyCastle и ответ от Stackoverflow с небольшими изменениями для чтения непосредственно из строки вместо файла.
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:
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 метод извлечен отсюда: https://stackoverflow.com/a/44857593/3286975
Я сделал небольшую модификацию этого метода:
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 для шифрования данных используется открытый ключ, а не личный.
Я не знаю, почему в примерах C # используются закрытые ключи на стороне клиента, это нелогично, может кто-нибудь объяснить, почему и как я могу решить эти проблемы?