c # Jose-Jwt: подписано и зашифровано из строки KeyPair - PullRequest
0 голосов
/ 30 апреля 2018

Я новичок в jwt, и после прочтения множества веб-страниц я не нашел примеров того, как сгенерировать токен (, подписанный и зашифрованный ) с парами ключей, созданными с этого сайта https://mkjwk.org/. Я думаю, это не может быть очень сложно. Я думаю, что это способ генерирования подписанного токена (я не знаю, является ли он правильным):

        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);

Я получаю токен (я думаю, что он подписан), но если я размещу этот токен на этом веб-сайте https://jwt.io/,, я получаю сообщение об ошибке «Invalid Signature». Также я хотел бы зашифровать этот токен открытым ключом. Итак, я делаю это:

// 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 ожидает, что ключ будет иметь тип RSACryptoServiceProvider.». Я уже искал об этой ошибке, но у меня нет ничего ясного. Пожалуйста, кто-нибудь может мне помочь? Я не уверен, что я на правильном пути.

Я использую jose-jwt для .net, потому что я прочитал, что библиотека System.IdentityModel.Tokens.Jwt не может зашифровать.

Спасибо. Привет.

1 Ответ

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

В этом случае у меня был jwk, и я хотел подписать его своим закрытым ключом и зашифровать его открытым ключом клиента с помощью библиотеки c # jose-jwt . Этот jwk все время один и тот же, поэтому мне нужно сгенерировать его только один раз. Для этого вам нужно создать объект RSA, а затем использовать метод Encode библиотеки для подписи и шифрования. JWK имеет несколько параметров:

JSON Web Key (JWK): объект JSON, представляющий криптографический ключ. Члены объекта представляют свойства ключа, в том числе его ценность. Вот некоторые из параметров:

p = 'Секретное простое число RSA'; kty = 'Тип ключа'; q = 'Секретное простое число RSA'; d = «Секретный показатель RSA»; e = 'открытый представитель RSA'; kid = 'Ключ ID'; n = 'Публичный модуль RSA'; use = 'Использование открытого ключа'; alg = 'Алгоритм'

Но в моем случае у меня были только некоторые из них: d, e, n, kty, use, kid, alg. Проблема в том, что если у вас есть параметры e и d, вам также понадобятся p и q , потому что вы не можете создать закрытый ключ с .NET без простых чисел (P и Q).

Решение было разделить проблему на две части:

JAVA-часть: создание полного jwk с библиотекой Nimbus JOSE + JWT JAVA :

C # части: Используйте предыдущий jwk для создания объекта RSA в C # с 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);

Оригинальное решение можно найти на веб-странице автора библиотеки .

Привет.

...