【问题标题】:Encryption with public key in Jose-JWTJose-JWT 中的公钥加密
【发布时间】:2018-10-17 11:37:24
【问题描述】:

我觉得这个问题不是骗人的,所以我会试着解释一下我的情况。

我正在测试 JWT,更具体地说是来自 Github 的 JOSE-JWT lib,但是我遇到了麻烦。

我正在使用 PHP 和 phpseclib 生成一个私钥-公钥对并将公钥发送给客户端。如您所见there,一切都是正确的。我的客户正在接收 JSON 并将其转换为对象并使用 JSON.NET 将其提取为字符串。

我使用BouncyCastleanswer from 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 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方法从这里提取: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# 示例在客户端使用私钥,这是不合逻辑的,谁能解释我为什么,我该如何解决这个问题?

【问题讨论】:

    标签: c# client jwt private-key jose


    【解决方案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 完成。所以,我的问题解决了。

    【讨论】:

      猜你喜欢
      • 2017-05-11
      • 2015-08-07
      • 2021-10-02
      • 2019-02-21
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 2013-04-06
      • 2019-08-07
      相关资源
      最近更新 更多