1

この質問はだまされていないと思うので、私の状況を説明しようと思います。

私はJWT、より具体的にはGithubのJOSE-JWT libをテストしていますが、問題があります。

PHP とphpseclibを使用して、秘密鍵と公開鍵のペアを生成し、クライアントに公開鍵を送信しています。ご覧のとおり、すべてが正しいです。私のクライアントは JSON を受け取り、それをオブジェクトに変換し、JSON.NETを使用して文字列に抽出しています。

私はBouncyCastleStackoverflowからの回答を使用しており、ファイルからではなく文字列から直接読み取るように少し変更しています。

        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# の例がクライアント側で秘密鍵を使用している理由がわかりません。これは論理的ではありません。誰かが理由を説明してくれませんか。また、この問題をどのように解決できますか?

4

1 に答える 1

1

私が抱えている2つの問題のうちの1つに対する答えを見つけました.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 によって行われます。それで、私の質問は解決されました。

于 2018-05-10T00:14:23.073 に答える