web-dev-qa-db-fra.com

comment utiliser RSA pour crypter des fichiers (énormes données) en C #

Je suis nouveau dans le cryptage. J'ai besoin d'implémenter un algorithme de chiffrement asymétrique, qui je pense qu'il utilise une clé privée/publique. J'ai commencé à utiliser un échantillon de RSACryptoServiceProvider. c'était correct avec de petites données à crypter. Mais en l'utilisant sur des données relativement plus importantes "2 lignes", j'obtiens l'exception CryptographicException "Bad Length"!

//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{

    //Import the RSA Key information. This only needs
    //toinclude the public key information.
    //RSA.ImportParameters(RSAKeyInfo);
    byte[] keyValue = Convert.FromBase64String(publicKey);
    RSA.ImportCspBlob(keyValue);

    //Encrypt the passed byte array and specify OAEP padding.  
    //OAEP padding is only available on Microsoft Windows XP or
    //later.  
    encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
}

Ensuite, j'ai trouvé quelques exemples de chiffrement de grandes données (ou fichiers) en utilisant CryptoStream, et n'utilise que des algorithmes symétriques comme DES ou 3DES, qui ont la fonction CreateEncryptor pour renvoyer ICryptoTransform comme l'une des entrées de le constructeur de CryptoStream !!!

CryptoStream cStream = new CryptoStream(fStream,
                new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV),
                CryptoStreamMode.Write);

Quelle est la façon de crypter des fichiers à l'aide de RSA?

41
ala

Comme mentionné dans d'autres réponses, le chiffrement asymétrique est uniquement conçu pour chiffrer des données plus petites que sa taille de clé.

Une option que j'ai mise en œuvre lorsque j'ai besoin de transférer de grandes quantités de données cryptées entre deux systèmes est d'avoir une paire de clés RSA dont la clé publique est connue à la fois de l'expéditeur et du récepteur, puis lorsque les données doivent être envoyées, le récepteur génère une nouvelle paire de clés RSA , chiffre la clé publique de cette paire de clés avec la clé publique commune et envoie la clé publique chiffrée à l'expéditeur. L'expéditeur déchiffre la clé publique du récepteur à l'aide de sa clé privée (que le récepteur n'a pas besoin de connaître, tout comme l'expéditeur n'a pas besoin de connaître la clé privée générée par le récepteur), génère une clé de chiffrement symétrique, chiffre les données avec la clé symétrique puis crypte la clé symétrique à l'aide de la clé publique reçue du récepteur. La clé symétrique chiffrée et les données chiffrées sont ensuite envoyées au récepteur qui utilise sa clé privée générée pour déchiffrer la clé symétrique puis déchiffre les données.

Vous pouvez utiliser les méthodes RSACryptoServiceProvider.ToXMLString() et RSACryptoServiceProvider.FromXMLString() pour stocker la clé publique commune en tant que littéral de chaîne XML dans l'application réceptrice.

N'oubliez pas, lorsque vous générez la clé de chiffrement symétrique pour utiliser RNGCryptoServiceProvider() pour générer la clé car il s'agit d'une méthode beaucoup plus sécurisée de génération de (pseudo) nombres aléatoires.

De plus, je déconseille fortement d'utiliser 3DES comme algorithme de chiffrement symétrique, il est ancien et commence à montrer son âge. Utilisez le chiffrement symétrique AES avec les classes AesCryptoServiceProvicer ou RijndaelManaged.

35
Joe Kuemerle

RSA ne peut chiffrer que les blocs de données qui sont plus courts que la longueur de clé, donc ce que vous faites normalement est

  1. Générez une clé aléatoire de la bonne longueur requise pour AES (ou similaire).
  2. Chiffrez vos données en utilisant AES ou similaire en utilisant cette clé
  3. Chiffrez la clé aléatoire à l'aide de votre clé RSA

Ensuite, vous publiez les deux sorties de 2 et 3

Pour décrypter

  1. Déchiffrez la clé AES à l'aide de votre clé RSA.
  2. Déchiffrez les données à l'aide de cette clé AES
59
jcoder

Habituellement, RSA n'est utilisé que pour transférer une clé symétrique (au début du flux par exemple), puis les données en masse sont chiffrées avec cette clé.

Le chiffrement asymétrique n'est pas assez efficace pour transférer beaucoup de données.

20
Henk Holterman

Pour les recherches futures concernant les exceptions de mauvaise longueur RSA ...

Vous pouvez calculer le nombre maximal d'octets pouvant être chiffrés avec une taille de clé particulière avec les éléments suivants:

((KeySize - 384)/8) + 37

Cependant, si le paramètre optimal de remplissage de chiffrement asymétrique (OAEP) est vrai, les éléments suivants peuvent être utilisés pour calculer le nombre maximal d'octets:

((KeySize - 384)/8) + 7

Les tailles de clé légales sont de 384 à 16384 avec une taille de saut de 8.

18
ObjectType

Les implémentations .NET de RSA (et tous les algorithmes de clé publique/privée) ne prennent pas en charge de gros blocs de données, car ce n'est pas le but de la clé publique/privée.

Au lieu de cela, vous devez générer une nouvelle clé symétrique et l'utiliser pour crypter les données. Ensuite, vous utilisez une clé publique/privée pour crypter la clé symétrique et l'échanger en toute sécurité avec l'autre partie. Ils décryptent ensuite la clé symétrique et l'utilisent pour décrypter vos données.

6
blowdart

on a:

MaxBlockSize=((KeySize - 384) / 8) + 37

OR

MaxBlockSize=((KeySize - 384) / 8) + 7

donc, nous pouvons diviser les données en certains blocs, puis chiffrer chacun et les fusionner

1
kazem