JWT шифрует полезную информацию

Я новичок в технологии JWT, и я много читаю об этом.

Я знаю, что JWT имеет 3 части:

  • HEADER: ALGORITHM и TOKEN TYPE
  • Полезная нагрузка: DATA
  • ПОДПИСЬ, ПРОВОДЯЕМАЯ С СЕКРЕТНЫМ КЛЮЧОМ.

Можно ли зашифровать информацию полезной нагрузки? Я имею в виду, скажем, например, у меня есть эта полезная информация в моем токене:

{
"iss": "joe",
"exp": "1300819380",
"data": {
    "id": "12",
    "userName": "PH",
    "qntRed": "7",
    "qntGrad": {
        "1": "800",
        "2": "858",
        "3": "950",
        "4": "745",
        "5": "981"
    }
}

И пусть "qntGrad" - это конфиденциальная информация. Можно ли зашифровать это также секретным ключом? Это все еще токен JWT?

Ответ 1

Фактически существует не только подписанный JWT, но несколько технологий, описанных RFC:

В вашем случае прочитайте RFC7516 (JWE). Эти JWE имеют 5 частей:

  • Защищенный заголовок
  • Зашифрованный ключ
  • Инициализационный вектор
  • гипертекст
  • Тег аутентификации

В зависимости от вашей платформы вы можете найти библиотеку, которая поможет вам создать такой зашифрованный JWT. Что касается PHP, я пишу библиотеку, которая уже может загружать и создавать эти jose.

Ответ 2

Не шифрование токена означает, что другие внешние службы могут читать и проверять, что токен фактически аутентичен, не имея доступа к вашему закрытому ключу. (Им нужен только открытый ключ)

Ответ 3

Ниже приведен очень простой и эффективный метод шифрования с использованием AES. Обратите внимание, что вам нужно будет получить свой собственный ключ (ссылка включена в комментарии).

Обратите внимание, что при шифровании он будет устанавливать IV для каждого вызова шифрования. Вам понадобится это для дешифрования.

public class CustomEncryption
{
    public static string Encrypt256(string text, byte[] AesKey256, out byte[] iv)
    {
        // AesCryptoServiceProvider
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 256;
        aes.Key = aesKey256();
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;
        iv = aes.IV;

        byte[] src = Encoding.Unicode.GetBytes(text);

        using (ICryptoTransform encrypt = aes.CreateEncryptor())
        {
            byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);

            return Convert.ToBase64String(dest);
        }
    }

    public static string Decrypt256(string text, byte[] AesKey256, byte[] iv)
    {
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 256;
        aes.IV = iv;
        aes.Key = aesKey256();
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        byte[] src = System.Convert.FromBase64String(text);

        using (ICryptoTransform decrypt = aes.CreateDecryptor())
        {
            byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
            return Encoding.Unicode.GetString(dest);
        }
    }

    private static byte[] aesKey256()
    {
        //you will need to get your own aesKey
        //for testing you can generate one from
        //https://asecuritysite.com/encryption/keygen

        return new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5 };
    }
}

}