IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Décrypter un tableau de bytes en C++/CLI


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Avril 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Avril 2016
    Messages : 6
    Points : 3
    Points
    3
    Par défaut Décrypter un tableau de bytes en C++/CLI
    Bonjour à tous,

    J'ai un problème qui me fait tourner en rond depuis un moment.
    J'ai des programmes qui se communiquent des données via une base SQL.
    Par sécurité, une partie de ces données (de petits fichiers en fait) sont cryptées et stockés temporairement en varbinary dans la base.

    Ces données cryptées peuvent correspondre à des fichiers texte ou XML (UTF-8 sans BOM).

    Le programme C++ est en charge de décrypter les données.
    Quand je décrypte des fichiers texte, pas de problème, tout fonctionne bien.
    Pour les fichier XML, le déchiffrement échoue vers la fin du fichier avec l'erreur : 0x024e1e64 { "Longueur des données à déchiffrer non valide."}

    Le programme ressemble à cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
     
    array<Byte>^ Projet1::EncryptBytes_AES(array<Byte>^ cipheredData, int myLength, String myPassword)
    {
     
    	RijndaelManaged^ myRijndael = gcnew RijndaelManaged();
    	UTF8Encoding^ utf8 = gcnew UTF8Encoding;
    	array<Byte>^ encodedBytes = utf8->GetBytes(myPassword);
     
    	array<Byte>^ Key = encodedBytes;
    	array<Byte>^ IV = encodedBytes;
     
    	MemoryStream^ msDecrypt;
    	CryptoStream^ csDecrypt;
    	StreamReader^ srDecrypt;
     
    	MemoryStream^ msResult = gcnew MemoryStream(myLength);
    	array<Byte>^ resultat;
     
    	RijndaelManaged^ aesAlg;
     
    	String^ plaintext;
     
    	aesAlg = gcnew RijndaelManaged();
    	aesAlg->Padding = PaddingMode::None;
    	aesAlg->Key = Key;
    	aesAlg->IV = IV;
     
    	ICryptoTransform^ decryptor = aesAlg->CreateDecryptor(aesAlg->Key, aesAlg->IV);
     
    	msDecrypt = gcnew MemoryStream(cipheredData);
    	csDecrypt = gcnew CryptoStream(msDecrypt, decryptor, CryptoStreamMode::Read);
    	srDecrypt = gcnew StreamReader(csDecrypt);
     
    	csDecrypt->CopyTo(msResult);
            resultat = msResult->ToArray();
     
    	if (srDecrypt) srDecrypt->Close();
    	if (csDecrypt) csDecrypt->Close();
    	if (msResult) msResult->Close();
    	if (msDecrypt) msDecrypt->Close();
    	if (aesAlg) aesAlg->Clear();
     
    	return resultat;
     
    }

    Pour information, le programme d'origine qui crypte les données est un programme VB.NET qui ressemble à cela.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    Public Function MSecureB (ByVal Source() As Byte, ByVal MyPassword as String) As Byte()
     
            Using aesAlg As Aes = Aes.Create()
     
                aesAlg.Key = System.Text.UTF8Encoding.UTF8.GetBytes(MyPassword)
                aesAlg.IV = System.Text.UTF8Encoding.UTF8.GetBytes(MyPassword)
     
                Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)
     
                Using msEncrypt As New MemoryStream()
     
                    Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
     
                        csEncrypt.Write(Source, 0, Source.Length)
                        csEncrypt.FlushFinalBlock()
                        Return msEncrypt.ToArray()
     
                    End Using
     
                End Using
     
            End Using
     
        End Function
    Et curieusement, si j'utilise en VB.NET un programme équivalent au C++ pour décrypter mes fichiers XML, là, aucuns problèmes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    Public Function MSecureDecrypte_ByteArray(ByVal Source As Byte(), ByVal MyPassword as String) As Byte()
     
             Using aesAlg As Aes = Aes.Create()
     
                aesAlg.Key = System.Text.UTF8Encoding.UTF8.GetBytes(MyPassword)
                aesAlg.IV = System.Text.UTF8Encoding.UTF8.GetBytes(MyPassword)
     
                Dim decryptor As ICryptoTransform = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV)
     
                Using msDecrypt As New MemoryStream(Source)
     
                    Using csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)
     
                        Using srDecrypt As New StreamReader(csDecrypt)
     
                            Using ms2 As New MemoryStream()
                                csDecrypt.CopyTo(ms2)
                                MSecureDecrypte_ByteArray = ms2.ToArray()
                            End Using
     
                        End Using
     
                    End Using
     
                End Using
     
            End Using
     
        End Function
    PS : Si j'utilise un vecteur identique à ma clé c'est simplement pour simplifier le code exemple.


    Merci à ceux qui pourront m'apporter un éclairage sur ce problème

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Pour commencer, je ne suis pas certain d'où vient myLength. Mais normalement, tu ne devrais pas avoir à t'en servir, le CryptoStream est censé savoir où s'arrêter même si les données cryptées sont plus grandes que les données originales.

    Aussi, srDecrypt ne te sert à rien ici.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Avril 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Avril 2016
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    Merci Médinoc pour te pencher sur mon problème.

    Tu as tout à fait raison concernant le
    srDecrypt
    qui est l'héritage d'une précédente tentative que d'ailleurs je n'utilise plus.
    Pour ce qui est de la longueur des données lues, même quand je ne la précise pas
    MemoryStream^ msResult = gcnew MemoryStream();
    l'erreur reste malgré tout la même.

    J'ai l'impression qu'il plante sur le dernier block à décrypter.

    Précédemment j'avais utilisé un boucle While pour voir exactement où apparaissait le problème de "longueur de données".
    Le document d'origine est un xml finissant par
    <\document>
    , et le document était bien décrypté à 98% et l'erreur apparait toujours (quelque que soit la taille du document xml) à la fin au niveau du "o". (disons que je vois que les derniers caractères décryptés avant l'erreur sont
    <\D
    (le D de Document).

    Je ne sais pas si cela peut aider..

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    J'ai lu en diagonale (le C++/CLI m'intéresse peu), et je me pose la question... En C++/CLI, tu as (j'ai réduit pour montrer mon argument) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    array<Byte>^ encodedBytes = utf8->GetBytes(myPassword);
    array<Byte>^ Key = encodedBytes;
    array<Byte>^ IV = encodedBytes;
    ICryptoTransform^ decryptor = aesAlg->CreateDecryptor(aesAlg->Key, aesAlg->IV);
    En VB.NET :
    Code VB : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    aesAlg.Key = System.Text.UTF8Encoding.UTF8.GetBytes(MyPassword)
    aesAlg.IV = System.Text.UTF8Encoding.UTF8.GetBytes(MyPassword)
     
    Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)

    Donc, dans un cas, tu as un seul array que tu manipules par deux références différentes, alors que dans l'autre cas, tu as deux tableaux différents que tu manipules chacun par sa référence.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Candidat au Club
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Avril 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Avril 2016
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    Oui tu as raison JolyLoic, j'aurais pu réduire le volume du code C++ en utilisant une syntaxe identique au VB.
    Pour autant, en fin de compte, ma clé et mon vecteur sont identiques.
    Et d'ailleurs, pour la moitié de mes champs binaires à décrypter (les fichiers non XML), cela marche correctement.

Discussions similaires

  1. [Socket][File] Envoyer un tableau de byte
    Par itsmii dans le forum Entrée/Sortie
    Réponses: 14
    Dernier message: 30/01/2014, 09h10
  2. Réponses: 1
    Dernier message: 09/05/2005, 14h19
  3. probleme d allocation avec un tableau de BYTE
    Par e1lauren dans le forum C++
    Réponses: 5
    Dernier message: 06/05/2005, 13h42
  4. [VB.NET] Tableau de bytes Lecture/Ecriture
    Par BenoitM dans le forum Windows Forms
    Réponses: 3
    Dernier message: 05/04/2005, 09h51
  5. [C#] Convertir un tableau de byte en Image
    Par goulhasch dans le forum ASP.NET
    Réponses: 4
    Dernier message: 24/01/2005, 10h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo