web-dev-qa-db-fra.com

Comment utiliser le cryptage Rijndael avec une bibliothèque de classes .Net Core? (Pas .Net Framework)

Comment utilisons-nous le cryptage Rijndael dans une bibliothèque de classes .Net Core? (Il ne s'agit pas d'une bibliothèque de classes .Net Framework) Nous devons créer une bibliothèque partagée .Net Core à utiliser dans plusieurs projets et implémenter des méthodes Encrypt et Decrypt qui utilisent le même cryptage Rijndael dans tous les projets.

Nous utilisons actuellement:

  • VS Enterprise 2015
  • c #
  • Bibliothèque de classes .Net Core
  • .NETStandard, Version = référence v1.6

Il semble que l'implémentation de Rijndael et d'AES ne figure pas dans la version .Net Core 1.0 ... elle semble inclure uniquement les classes de base. Comment obtenir une implémentation .Net Core du cryptage Rijndael ou AES ajoutée comme référence à un nouveau projet de bibliothèque de classes .Net Core?

Voici la méthode Encrypt qui fonctionne dans .Net Framework 4.5.2:

    public static string Encrypt(string valueToEncrypt, string symmetricKey, string initializationVector)
    {
        string returnValue = valueToEncrypt;

        var aes = new System.Security.Cryptography.RijndaelManaged();
        try
        {
            aes.Key = ASCIIEncoding.ASCII.GetBytes(symmetricKey);
            aes.IV = ASCIIEncoding.ASCII.GetBytes(initializationVector);
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.ISO10126;

            var desEncrypter = aes.CreateEncryptor();
            var buffer = ASCIIEncoding.ASCII.GetBytes(valueToEncrypt);

            returnValue = Convert.ToBase64String(desEncrypter.TransformFinalBlock(buffer, 0, buffer.Length));
        }
        catch (Exception)
        {
            returnValue = string.Empty;
        }

        return returnValue;
    }
12
Ensunder

La différence (en .NET) entre Rijndael et AES est que Rijndael permet à la taille du bloc de changer, mais pas à AES. Étant donné que la taille de bloc par défaut de RijndaelManaged est identique à la taille de bloc AES (128 bits/16 octets), vous utilisez en fait AES.

Au lieu d'instancier le type d'implémentation par nom, utilisez simplement la fabrique (Aes.Create()). Cela fonctionne dans .NET Core et .NET Framework.

Autres choses à noter:

  • Toutes les instances SymmetricAlgorithm sont identifiables, vous devez les utiliser dans une instruction using.
  • Toutes les instances ICryptoTransform (telles que votre nom incorrect desEncryptor) sont identifiables, vous devez les utiliser dans une instruction using.
  • Le remplissage ISO10126 n'est pas disponible dans .NET Core 1.0. Si vous devez être compatible avec les flux existants, vous pouvez appliquer le remplissage vous-même et spécifier PaddingMode.None. Sinon, PKCS7 est plus standard.
  • Votre clé AES n’est pas très aléatoire, car elle provient d’une chaîne ASCII (de nombreuses valeurs ne seront pas valides) .
    • Base64 au moins a la plage de valeurs complète
    • PBKDF2 (fonction de dérivation de clé basée sur un mot de passe 2) via la classe Rfc2898DeriveBytes permet une entrée de bruit de chaîne partagée secrète et prévisible.
    • En règle générale, KeyAgreement est préférable, mais ni ECDH ni DH classique ne sont disponibles dans .NET Core 1.0.
  • Généralement, le chiffreur devrait laisser un IV aléatoire être calculé (appelez aes.GenerateIV() si vous utilisez le même objet pour plusieurs opérations) et présentez-le avec le texte chiffré. Donc, chiffrer prend une clé et un texte en clair et produit un texte chiffré et IV. Le déchiffrement prend (clé, IV, texte chiffré) et produit un texte en clair.
21
bartonjs

Si vous souhaitez simplement chiffrer/déchiffrer des éléments, évitez d’utiliser Rijndael directement car asp.net core contient des wrappers beaucoup plus agréables, beaucoup plus faciles à utiliser et plus susceptibles d’être sécurisés par défaut. C'est ce qu'on appelle DataProtection.

using Microsoft.AspNetCore.DataProtection;

// During startup add DP
serviceCollection.AddDataProtection();

...

// the 'provider' parameter is provided by DI
public MyClass(IDataProtectionProvider provider)
{
    _protector = provider.CreateProtector("Contoso.MyClass.v1");
}

...

// protect the payload
string protectedPayload = _protector.Protect(input);
Console.WriteLine($"Protect returned: {protectedPayload}");

...

// unprotect the payload
string unprotectedPayload = _protector.Unprotect(protectedPayload);
Console.WriteLine($"Unprotect returned: {unprotectedPayload}");

Voir la documentation sur la protection des données pour plus d'informations

0
alastairtree