2 votes

Clé, sel et IV lors de l'utilisation du cryptage Rijndael

Je travaille sur un site web où les utilisateurs peuvent télécharger des fichiers. Je souhaite crypter ces fichiers, au cas où il y aurait une faille de sécurité lors de l'accès à ces fichiers.

Lorsque l'utilisateur souhaite télécharger ses fichiers, je décrypte directement le flux de sortie HTTP(S).

Les fichiers sont placés sur un disque et un enregistrement pour chacun d'eux est inséré dans la base de données du site web avec quelques données supplémentaires (nom du fichier, taille, chemin d'accès, IV, etc.).

Je n'ai qu'une compréhension de base de l'utilisation du cryptage et j'ai donc quelques questions à poser.

J'utilise Rfc2898DeriveBytes pour générer les octets de la clé de cryptage. Est-il possible d'utiliser cette classe ? Pour autant que je sache, elle utilise SHA1, qui pourrait ne plus être sûr ?

Pour l'instant, j'utilise le même mot de passe et le même sel pour chaque cryptage, mais un IV aléatoire à chaque fois. Devrais-je également randomiser le sel et le conserver dans la base de données avec l'IV ? Cela apportera-t-il une sécurité supplémentaire ?

Dois-je utiliser un code d'authentification des messages (MAC) ? Les fichiers cryptés eux-mêmes sont uniquement stockés et ne sont jamais transférés, je ne sais donc pas si c'est nécessaire.

Je ne sais pas vraiment comment stocker au mieux le mot de passe de cryptage. Je ne veux pas l'inclure dans la DLL de mon site web, donc je le mettrai probablement dans un fichier sur le serveur, quelque part en dehors du dossier de mon site web. Comment pourrais-je faire autrement ?

Il s'agit de mon code de cryptage. Y a-t-il des failles de sécurité évidentes ?

const int bufferSize = 1024 * 128;

Guid guid = Guid.NewGuid();
string encryptedFilePath = Path.Combine(FILE_PATH, guid.ToString());
byte[] rgbIV;

using (Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes("PASSWORD HERE", Encoding.ASCII.GetBytes("SALT HERE")))
{
    byte[] rgbKey = deriveBytes.GetBytes(256 / 8);

    using (FileStream decryptedFileStream = File.OpenRead(decryptedFilePath))
    using (FileStream encryptedFileStream = File.OpenWrite(encryptedFilePath))
    using (RijndaelManaged algorithm = new RijndaelManaged() { KeySize = 256, BlockSize = 128, Mode = CipherMode.CBC, Padding = PaddingMode.ISO10126 })
    {
        algorithm.GenerateIV();
        rgbIV = algorithm.IV;

        using (ICryptoTransform encryptor = algorithm.CreateEncryptor(rgbKey, rgbIV))
        using (CryptoStream cryptoStream = new CryptoStream(encryptedFileStream, encryptor, CryptoStreamMode.Write))
        {
            int read;
            byte[] buffer = new byte[bufferSize];
            while ((read = decryptedFileStream.Read(buffer, 0, bufferSize)) > 0)
                cryptoStream.Write(buffer, 0, read);
            cryptoStream.FlushFinalBlock();
        }
    }
}

2voto

Artjom B. Points 52081

J'utilise Rfc2898DeriveBytes pour générer les octets de la clé de cryptage. Est-il possible d'utiliser cette classe ? Pour autant que je sache, elle utilise SHA1, qui pourrait ne plus être sûr ?

La récente rupture efficace de SHA-1 n'a en réalité qu'un impact sur la résistance aux collisions, qui n'est pas nécessaire pour PBKDF2 (l'algorithme à l'origine de l'algorithme Rfc2898DeriveBytes ). Voir : PBKDF2-HMAC-SHA1 est-il vraiment cassé ?

Pour l'instant, j'utilise le même mot de passe et le même sel pour chaque cryptage, mais un IV aléatoire à chaque fois. Devrais-je également randomiser le sel et le conserver dans la base de données avec l'IV ? Cela apportera-t-il une sécurité supplémentaire ?

Peut-être cela apportera-t-il une sécurité supplémentaire, mais cela ne fera certainement pas de mal, sauf si vous ajoutez un bogue. Source : Besoin de sel en cas de perfusion

Dois-je utiliser un code d'authentification des messages (MAC) ? Les fichiers cryptés eux-mêmes sont uniquement stockés et ne sont jamais transférés, je ne sais donc pas si c'est nécessaire.

En général, un système de stockage dispose de contrôles et de procédures pour prévenir et corriger la corruption des données. Si ce n'est pas le cas, un MAC est un bon moyen de vérifier si les données ont été corrompues, même si cela ne s'est pas produit de manière malveillante.

Si l'utilisateur final est censé recevoir les données, il peut vérifier lui-même le MAC et s'assurer que personne n'a modifié le texte chiffré.

Je ne sais pas vraiment comment stocker au mieux le mot de passe de cryptage. Je ne veux pas l'inclure dans la DLL de mon site web, donc je le mettrai probablement dans un fichier sur le serveur quelque part qui ne soit pas dans le dossier de mon site web. Comment pourrais-je faire autrement ?

Si j'ai bien compris, vous voulez en fait détenir la clé de cryptage/décryptage. Tout ce que vous pouvez faire n'est que de l'obscurcissement et n'apporte aucune sécurité réelle. Un attaquant pourrait simplement utiliser la même connexion au stockage de données que votre code habituel. Au mieux, l'attaquant sera légèrement ralenti. Au pire, il ne remarquera même pas que les données ont été cryptées, car le décryptage se fait de manière transparente.

Il est préférable de s'assurer qu'un attaquant ne peut pas entrer. Consultez le top 10 de l'OWASP et essayez de suivre les conseils. Ensuite, vous pouvez effectuer des analyses de sécurité avec Nikto ou faire appel à un testeur de pénétration professionnel.

C'est mon code de cryptage. Y a-t-il des failles de sécurité évidentes ?

Utilisation PaddingMode.ISO10126 ne semble pas être une bonne idée. Il est préférable d'opter pour le rembourrage PKCS#7. Source : Pourquoi la norme ISO 10126 sur le rembourrage a-t-elle été retirée ?

2voto

Zaph Points 40557
  1. Rfc2898DeriveBytes est essentiellement PBKDF2, qui est recommandé par le NIST.

  2. Si vous rendez le sel aléatoire (une bonne pratique de sécurité), vous devrez le fournir pour le décryptage. Une méthode courante consiste à préfixer les données cryptées avec le sel et l'IV.

  3. Oui, vous devez utiliser un Mac pour les données cryptées et toutes les informations qui y sont ajoutées, comme celles mentionnées ci-dessus.

  4. Afin de fournir des suggestions sur la sécurisation de la clé de chiffrement, plus d'informations sur la façon dont le chiffrement sera utilisé.

  5. Utiliser le rembourrage PKCS#7, parfois l'option est nommée PKCS#5 pour des raisons historiques.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X