时间:2019-05-06 标签:c#Jose-Jwt : Signed and Encrpyt from KeyPair string

标签 c# .net encryption sign jose

我是 jwt 的新手,在阅读了很多网页后,我还没有找到如何使用从本网站生成的 key 对生成 token ( 签名和加密 )的示例https://mkjwk.org/ .我认为这不会很困难。我认为这是生成签名 token 的方式(不知道是否正确):

        RSACryptoServiceProvider rsaCrypto = new RSACryptoServiceProvider();

        var payload = new Dictionary<string, object>()
        {
            {"jti", "ORIGEN_" + Guid.NewGuid().ToString()},
            {"iat", DateTime.UtcNow},
            {"exp", DateTime.UtcNow.AddYears(1)},
            {"login", "USER" },
            {"password", "PASSWORD" },
            {"origen", "ORIGEN" }
        };

        // Contains both public and private keys to sign
        var headers = new Dictionary<string, object>()
        {
            { "kty", "RSA" },
            { "d", "A7Q8cttv_CSG4CJkX_xlU5lUoeRrCPZpyZx9eVaD7zi-tE7wDPKNmJPRP6uR_LA2YVXMmfY9w8q1_v_MiYxkYnFgZqNZlKdwucSQUlnfX5Tt806qh_323h5NnHrKweL-98_d8R4RuZXCWEQ3X0QDCVfccaLVVqLJy8S5zlx0aAVuBJxLxBHFRO700qdUN-RaMjHULoOnE1KbwmfKPfGlLL0YWPHQ9t-qIBh6OSZsDZh30K4VLF8sRXkGgn81_Byp4hK9tCfG98R6fWUM2_FCQrC9R1hO-KTsLffRzMboWe-2ymZGQfZKO-gtFaQH7_AjdVnQYMyKhSSCGYAAroSZAQ"},
            { "e", "AQAB" },
            { "use", "enc"},
            { "kid", "RPA" },
            { "alg", "RS256" },
            { "n", "qJPwMcHtb7xFGGczn20IiEtrPVehquyT6lxIJa_e4vcZE33uM6myVZWocTZWzTDmrNT3bJghEpLOhrgYatT3QnJIiTM9KAD01kYPc5cP5yo6Wmu0YjivqL3Rj7dUvi2pvl7juwYxt1_8zfdnBN5GpBIYcaY3ulVo_OSL7TOxJrua5IMhilQz6kqta3-Rgz3GSglOs94RHRvorYxMyHPQ6KhwSlh_zLzJQZ-0-AZ4yaMPdVwEaaEJpL-odYmRudX4E0t42dExLf_q1rpRfvTcdFSwfsJ7FmQcOtlc340WUgr4BHJfwrNIE4i-TFqrB4zSQJVKHlBfLeGKiYZQPD7igw" }
        };

        string tokenSigned = JWT.Encode(payload, rsaCrypto, JwsAlgorithm.RS256, headers);

我得到一个 token (我认为是签名的)但是如果我把这个 token 放在这个网站 https://jwt.io/ ,我收到错误“无效签名”。
另外我想用公钥加密这个 token 。所以我这样做:
// Another public key to encrypt
headers = new Dictionary<string, object>()
        {
            { "kty", "RSA" },
            { "e", "AQAB" },
            { "use", "enc"},                
            { "alg", "RS256" },
            { "n", "ldMvqNDlz8-ABqEhqjtT0qvjKKbJMQ4J6GEi-7QrY-EUtyjCE7cOriHrYmbjt3o3zXwUTyOp0-twnF5j1HXFwVk7_XNsZz7LUmGNtmnqgB2iw2xhS7LAicN0RRgIbxWRDLOaaZ-49QumX6_r_jLNtIspKiFiuUNf2s0ipeAjWBFquiiqTMBd98z3pS-vC5y0CfzPbTSLSinikrHkIW2uO4FNHWZpoo8npn7vwWtAJjknWhaFi2s9P5kzUk4Mpbdx4DxUJ9ZvUi9SmdvH2vUzwGe0lxyvlw0DAMMWAT9TmsiKzBeXTY6rQ1-2Edn4F9S5kkPNOh1NqJoebz50-Bpl6w" }
        };

string tokenEncrypted = JWT.Encode(payload, tokenSigned , JweAlgorithm.RSA_OAEP, JweEncryption.A256GCM, extraHeaders: headers);

但我总是收到错误“RsaKeyManagement alg 期望 key 为 RSACryptoServiceProvider 类型。”。我已经搜索过这个错误,但我没有什么清楚的。
拜托,有人可以帮我吗?我不确定我是否走对了路。

我将 jose-jwt 用于 .net,因为我读过库 System.IdentityModel.Tokens.Jwt 无法加密。

谢谢你。
问候。

最佳答案

在这种情况下,我有一个 jwk,我想用我的私钥对其进行签名,并使用带有 c# jose-jwt library 的客户公钥对其进行加密。 .这个jwk一直都一样,所以我只需要生成一次。为此,您需要创建一个 RSA 对象,然后使用库的 Encode 方法进行签名和加密。
jwk 有几个参数:

JSON Web Key (JWK): A JSON object that represents a cryptographic key. The members of the object represent properties of the key, including its value. These are some of the parameters:

p = 'RSA secret prime'; kty = 'Key Type'; q = 'RSA secret prime'; d = 'RSA secret exponent'; e = 'RSA public exponent'; kid = 'Key ID'; n = 'RSA public modulus'; use = 'Public Key Use'; alg = 'Algorithm'



但就我而言,我只有其中的一些:d、e、n、kty、use、kid、alg。问题是如果你有e和d参数,你还需要 p 和 q ,因为你不能构造 私钥 .NET 没有质数(P 和 Q)。

解决方案是将问题分为两部分:

JAVA部分:用Nimbus JOSE+JWT JAVA library创建一个完整的jwk :

C# 部分:
使用前面的jwk在C#中创建一个RSA对象c# jose-jwt library .像这样:
var js = new JavaScriptSerializer();    
// json is the result returned by java
var jwk = js.Deserialize<IDictionary<string, string>>(json);

byte[] p = Base64Url.Decode(jwk["p"]);
byte[] q = Base64Url.Decode(jwk["q"]);
byte[] d = Base64Url.Decode(jwk["d"]);
byte[] e = Base64Url.Decode(jwk["e"]);
byte[] qi = Base64Url.Decode(jwk["qi"]);
byte[] dq = Base64Url.Decode(jwk["dq"]);
byte[] dp = Base64Url.Decode(jwk["dp"]);
byte[] n = Base64Url.Decode(jwk["n"]);

RSA key = RSA.Create();
RSAParameters keyParams = new RSAParameters();
keyParams.P = p;
keyParams.Q = q;
keyParams.D = d;
keyParams.Exponent = e;
keyParams.InverseQ = qi;
keyParams.DP = dp;
keyParams.DQ = dq;
keyParams.Modulus = n;

key.ImportParameters(keyParams);

拥有 RSA 对象后,您可以对其进行签名:
var payload = new Dictionary<string, object>()
{       
    {"user", USER },
    {"password", PASSWORD }            
};

string tokenSigned = JWT.Encode(payload, key, JwsAlgorithm.RS256);

您可以在 library author web page 中找到原始解决方案.

问候。

关于时间:2019-05-06 标签:c#Jose-Jwt : Signed and Encrpyt from KeyPair string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50100186/

相关文章:

c# - 具有两个 Action 的一个循环 VS 具有一个 Action 的两个循环性能?

c# - 如何访问 DbContext 类中的配置?

.net - .NET 属性的历史前身是什么?

iphone - 类别头文件没有加密成二进制

Nodejs 中的 Java 密码

c# - 记录函数调用层次结构

c# - 在 C# 中构建字符串数组并检查空值?

.net - 是否可以使用没有 'installing' 版本的 .NET 版本进行构建?

c# - 在 Silverlight 5 中使用异步时堆栈跟踪不提供异常源方法

java - 使用 PHP OpenSSL 将 Java AES/ECB/PKCS7Padding/代码转换为 PHP