Шифрование с открытым ключом в Jose-JWT - PullRequest
0 голосов
/ 07 мая 2018

Я думаю, что этот вопрос не дурак, поэтому я попытаюсь объяснить мою ситуацию.

Я тестирую 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 # используются закрытые ключи на стороне клиента, это нелогично, может кто-нибудь объяснить, почему и как я могу решить эти проблемы?

1 Ответ

0 голосов
/ 10 мая 2018

Я нашел ответ на одну из двух проблем, с которыми я столкнулся, и заключается в том, что я не полностью перечитал репозиторий 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 для управления открытыми и закрытыми ключами, JOSE-JWT выполняет работу по расшифровке и шифрованию.Итак, мой вопрос решен.

...