Pour cacher du texte dans du texte(rtf). stéganographie. [borland 5, bcb]

Soyez le premier à donner votre avis sur cette source.

Vue 6 108 fois - Téléchargée 610 fois

Description

Vous souhaitez cacher un message sans que personne ne puisse soupçonner son existence : c'est possible !
Il y a plusieurs façons de faire. Ce programme montre comment cacher un texte non formaté dans un document au format RTF (Rich Text Format);

Désoler pour les puristes, comme je ne voulais me casser le tête pour les allocations de mémoire, je me suis servi de l'AnsiString de Borland pour mes chaînes de caractères. (Il faut faire le passage en char).

Le principe de basse est assez simple. On ce sert des lettres du document RTF pour cacher notre message. La taille est toujours fixée à 16 sauf quand on veut utilisé une lettre : cette dernière passe alors à 16,5.
C'est ce morceau de code que vous pouvez lire ci-dessous.
Pour le reste, l'interface graphique et les améliorations consulter le zip.

Dans quelques jours un autre type de stéganographie(Cacher des données dans des données) devrait voir le jour : Comment cacher un fichier quelconque dans une image BMP.

Source / Exemple :


AnsiString TexteO, TexteM; // Texte Original et Texte Modifié
long CaractereReste; // nombre de caratère restant à intègrer
long first; // fin de la config debut hypotètique du texte voir le zip ou l'initialiser à 0

void __fastcall TTexteChild::Integrer(void)
{
AnsiString t, tmp = " ", MessageO, CaractO;
long length, len, pass;
int ind, i, NCR;
bool caract;

    Compter();
    for (length=1;length<=TexteO.Length();length++) { // mise a la bonne taille des caractère
        if ((TexteO[length] == '\\') && (TexteO[length+1] == 'f') && (TexteO[length+2] == 's') && (TexteO[length+3] >= '0') && (TexteO[length+3] <= '9')) {
            t = t + "\\fs32";
            length+=2;
            while ((TexteO[length+1] != '\\') && (TexteO[length+1] != ' '))
                length++;
        } else {
            tmp[1] = TexteO[length];
            t = t + tmp;
        }
    }
    TexteM = t;
    t = "";

bool parant = false;

    for (length=1;length<=TexteM.Length();length++) { // supression des "{\fs09" "}"
        if ((TexteM[length] == '{') && (TexteM[length+1] == '\\') && (TexteM[length+2] == 'f') && (TexteM[length+3] == 's') && (TexteM[length+4] >= '0') && (TexteM[length+4] <= '9')) {
            length+=3;
            parant = true;
            while ((TexteM[length] != ' '))
                length++;
        } else if ((TexteM[length] == '}') && (TexteM[length-1] != '\\')){
            if (parant == false) {
                tmp[1] = TexteM[length];
                t = t + tmp;
            }
            parant = false;
        } else {
            tmp[1] = TexteM[length];
            t = t + tmp;
        }
    }
    TexteM = t;
    t = "";

    for (length=1;length<=Memo1->Text.Length();length++) { // enleve '\n'
        if (Memo1->Text[length] != '\n') {
            tmp[1] = Memo1->Text[length];
            MessageO = MessageO + tmp;
        }
    }

    len = MessageO.Length();

    if (len == 0) {
        CaractereReste = 0;
        goto fin;
    }

    tmp[1] = MessageO[1];
    CaractO = CharStrToRtf(tmp);
    MessageO = MessageO + " ";

    ind = 1;
    pass = 0;

    for (length=1;length<first;length++) {
        tmp[1] = TexteM[length];
        t = t + tmp;
    }
    for (length=first;length<=TexteM.Length();length++) {// integration
        if ((TexteM[length] == '\\') &&  // configuration du texte : ne pas toucher
            (!((TexteM[length+1] == '\'') || (TexteM[length+1] == '{') || (TexteM[length+1] == '}')))) {

             tmp[1] = TexteM[length];
             t = t + tmp;
             while ((TexteM[length+1] != '\\') && (TexteM[length+1] != ' ')) {
                length++;
                tmp[1] = TexteM[length];
                t = t + tmp;
             }
        } else { // c'est du texte visible

            if ( ((CaractO == " ") || (CaractO == "\r")) && (ind <= len)) { // 2 ou 3 caract visuel  ( 2 = ' ', 3 = "\r\n" = "\par"
                t = t + CaractereRtf(TexteM,length);

                if (CaractO == " ")
                    i = 2;
                else
                    i = 3;

                t = t + "\\fs33 ";
                while (i > 0) {
                    length++;
                    t = t + CaractereRtf(TexteM,length);
                    i--;
                }
                t = t + "\\fs32 ";

                ind++;
                tmp[1] = MessageO[ind];
                if ((tmp == "\r") || (tmp == " "))
                    CaractO = tmp;
                else
                    CaractO = CharStrToRtf(tmp);
                CaractereReste--;
                pass = 0;

            } else  {
                if ((TexteM[length] == CaractO[1]) && (ind <= len) && (pass > 3)) {
                    if (CaractO.Length() == 1) { // 1 caract visuel
                        t = t + "\\fs33 " + CaractO + "\\fs32 ";

                    } else {                    // plusieur caract formant 1 visuel
                        caract = true;
                        if (length+i < TexteM.Length()) {
                            i = CaractO.Length();
                            while (i > 2) {
                                if (CaractO[i] != TexteM[length+i-1]) {
                                    caract = false;
                                    break;
                                }
                                i--;
                            }
                        } else
                            caract = false;

                        if (caract == true) {
                            t = t + "\\fs33 " + CaractO + "\\fs32 ";
                        }
                    }

                    if ((CaractO.Length() == 1) || ((CaractO.Length() > 1) && (caract == true)) ) {
                        ind++;
                        tmp[1] = MessageO[ind];
                        if ((tmp == "\r") || (tmp == " "))
                            CaractO = tmp;
                        else
                            CaractO = CharStrToRtf(tmp);
                        CaractereReste--;
                        pass = 0;
                    }
                } else {
                    tmp[1] = TexteM[length];
                    t = t + tmp;
                    pass++;
                }
            }
        }
    }
    TexteM = t;
}
//---------------------------------------------------------------------------

void __fastcall TTexteChild::Extraire(void)
{
AnsiString t, tmp = " ";
long length;
bool Codee;

    Codee = true;
    for (length=1;length<=TexteO.Length();length++) { // le texte est-il bien codé
        if ((TexteO[length] == '\\') && (TexteO[length+1] == 'f') && (TexteO[length+2] == 's')) {
            if (!((TexteO[length+3] == '3') && (TexteO[length+4] >= '1') && (TexteO[length+4] <= '3'))) {
                Codee = false;
                break;
            }
        }
    }

    if (Codee == false) {
        Memo1->Text = ""; // il n'y a pas de message
        return;
    }

    for (length=1;length<=TexteO.Length();length++) {// extraction
         if ((TexteO[length] == '\\') &&  // mise en forme : ne pas toucher
             (!((TexteO[length+1] == '\'') || (TexteO[length+1] == '{') || (TexteO[length+1] == '}') ||
              ((TexteO[length+1] == 'f') && (TexteO[length+2] == 's') && (TexteO[length+3] >= '0') && (TexteO[length+3] <= '9'))
              ))) {
             while ((TexteO[length+1] != '\\') && (TexteO[length+1] != ' ')) {
                length++;
             }
         } else { // c'est du texte
             if ((TexteO[length] == '\\') && (TexteO[length+1] == 'f')  && (TexteO[length+2] == 's') && (TexteO[length+3] == '3') && (TexteO[length+4] == '3') && (TexteO[length+5] == ' ')) {
                switch (NbCaractRtf(TexteO,length,tmp))
                {
                  case 1 : t = t + tmp;
                  break;
                  case 2 : t = t + " ";
                  break;
                  case 3 : t = t + "\r\n";
                  break;
                }

             }
         }
    }

    TexteM = t;
}
//---------------------------------------------------------------------------

AnsiString __fastcall TTexteChild::CharStrToRtf(AnsiString Valeur)
{
AnsiString t;

    switch (Valeur[1])
    {
      case '{' : t = "\\{";
      break;
      case '}' : t = "\\}";
      break;
      case '\\' : t = "\\\\";
      break;
      case 'œ' : t = "\\'9c";
      break;
      case '¡' : t = "\\'a1";
      break;
      case '¢' : t = "\\'a2";
      break;
      case '£' : t = "\\'a3";
      break;
      case '?' : t = "\\'a4";
      break;
      case '¥' : t = "\\'a5";
      break;
      case 'S' : t = "\\'a6";
      break;
      case '§' : t = "\\'a7";
      break;
      case 's' : t = "\\'a8";
      break;
      case '©' : t = "\\'a9";
      break;
      case 'ª' : t = "\\'aa";
      break;
      case '®' : t = "\\'ae";
      break;
      case '¯' : t = "\\'af";
      break;
      case '°' : t = "\\'b0";
      break;
      case '±' : t = "\\'b1";
      break;
      case '²' : t = "\\'b2";
      break;
      case '³' : t = "\\'b3";
      break;
      case 'µ' : t = "\\'b5";
      break;
      case '·' : t = "\\'b7";
      break;
      case '¹' : t = "\\'b9";
      break;
      case 'º' : t = "\\'ba";
      break;
      case 'O' : t = "\\'bc";
      break;
      case 'o' : t = "\\'bd";
      break;
      case 'Y' : t = "\\'be";
      break;
      case '¿' : t = "\\'bf";
      break;
      case 'À' : t = "\\'c0";
      break;
      case 'Á' : t = "\\'c1";
      break;
      case 'Â' : t = "\\'c2";
      break;
      case 'Ã' : t = "\\'c3";
      break;
      case 'Ä' : t = "\\'c4";
      break;
      case 'Å' : t = "\\'c5";
      break;
      case 'Æ' : t = "\\'c6";
      break;
      case 'Ç' : t = "\\'c7";
      break;
      case 'È' : t = "\\'c8";
      break;
      case 'É' : t = "\\'c9";
      break;
      case 'Ê' : t = "\\'ca";
      break;
      case 'Ë' : t = "\\'cb";
      break;
      case 'Ì' : t = "\\'cc";
      break;
      case 'Í' : t = "\\'cd";
      break;
      case 'Î' : t = "\\'ce";
      break;
      case 'Ï' : t = "\\'cf";
      break;
      case 'Ð' : t = "\\'d0";
      break;
      case 'Ñ' : t = "\\'d1";
      break;
      case 'Ò' : t = "\\'d2";
      break;
      case 'Ó' : t = "\\'d3";
      break;
      case 'Ô' : t = "\\'d4";
      break;
      case 'Õ' : t = "\\'d5";
      break;
      case 'Ö' : t = "\\'d6";
      break;
      case '×' : t = "\\'d7";
      break;
      case 'Ø' : t = "\\'d8";
      break;
      case 'Ù' : t = "\\'d9";
      break;
      case 'Ú' : t = "\\'da";
      break;
      case 'Û' : t = "\\'db";
      break;
      case 'Ü' : t = "\\'dc";
      break;
      case 'Ý' : t = "\\'dd";
      break;
      case 'Þ' : t = "\\'de";
      break;
      case 'ß' : t = "\\'df";
      break;
      case 'à' : t = "\\'e0";
      break;
      case 'á' : t = "\\'e1";
      break;
      case 'â' : t = "\\'e2";
      break;
      case 'ã' : t = "\\'e3";
      break;
      case 'ä' : t = "\\'e4";
      break;
      case 'å' : t = "\\'e5";
      break;
      case 'æ' : t = "\\'e6";
      break;
      case 'ç' : t = "\\'e7";
      break;
      case 'è' : t = "\\'e8";
      break;
      case 'é' : t = "\\'e9";
      break;
      case 'ê' : t = "\\'ea";
      break;
      case 'ë' : t = "\\'eb";
      break;
      case 'ì' : t = "\\'ec";
      break;
      case 'í' : t = "\\'ed";
      break;
      case 'î' : t = "\\'ee";
      break;
      case 'ï' : t = "\\'ef";
      break;
      case 'ð' : t = "\\'f0";
      break;
      case 'ñ' : t = "\\'f1";
      break;
      case 'ò' : t = "\\'f2";
      break;
      case 'ó' : t = "\\'f3";
      break;
      case 'ô' : t = "\\'f4";
      break;
      case 'õ' : t = "\\'f5";
      break;
      case 'ö' : t = "\\'f6";
      break;
      case '÷' : t = "\\'f7";
      break;
      case 'ø' : t = "\\'f8";
      break;
      case 'ù' : t = "\\'f9";
      break;
      case 'ú' : t = "\\'fa";
      break;
      case 'û' : t = "\\'fb";
      break;
      case 'ü' : t = "\\'fc";
      break;
      case 'ý' : t = "\\'fd";
      break;
      case 'þ' : t = "\\'fe";
      break;
      case 'ÿ' : t = "\\'ff";
      break;
      case '\r' : t = "\\par\r";
      break;
      default: t = Valeur;
    }

    return t;
}
//---------------------------------------------------------------------------

AnsiString __fastcall TTexteChild::CaractereRtf(AnsiString TextRTF, long &Position)
{
long pos;
AnsiString CarRtf, tmp = " ";
bool fin;

    pos = Position;
    fin = false;
    do {
        tmp[1] = TextRTF[pos];
        CarRtf = CarRtf + tmp;
        switch (TextRTF[pos])
        {
          case '\\': pos++;
                tmp[1] = TextRTF[pos];
                switch (TextRTF[pos])
                {
                  case '{': ;
                  case '}': ;
                  case '\\': CarRtf = CarRtf + tmp;
                        fin = true;
                  break;
                  case '\'': tmp = "  ";
                        tmp[1] = TextRTF[pos+1];
                        tmp[2] = TextRTF[pos+2];
                        CarRtf = CarRtf + HexToInt(tmp);
                        tmp = " ";
                        pos+=2;
                        fin = true;
                  break;
                  case '~': pos++;
                  break;
                 default:
                        while((TextRTF[pos] != ' ') && (TextRTF[pos] != '\r') && (TextRTF[pos] != '\\')) {
                            tmp[1] = TextRTF[pos++];
                            CarRtf = CarRtf + tmp;
                        }
                }

          break;
          case ' ': ;
          case '\r': ;
          case '\n': pos++;
          break;
          default: fin = true;
        }

    } while(fin == false);

    Position = pos;
    return CarRtf;

}
//---------------------------------------------------------------------------

int __fastcall TTexteChild::NbCaractRtf(AnsiString TextRTF, long pos, AnsiString &Caract)
{
int nb;
AnsiString fs32, tmp = " ";
bool fin;

    nb = 0;
    Caract = " ";
    do {
        switch (TextRTF[pos])
        {
          case '\\': pos++;
                fs32 = "";
                switch (TextRTF[pos])
                {
                  case '{': ;
                  case '}': ;
                  case '\\': nb++;
                  case '~': pos++; // '°' => espace fait par word avant '!' et '?'
                  break;
                  case '\'': pos++;
                  break;
                  default:
                        while((TextRTF[pos] != ' ') && (TextRTF[pos] != '\r') && (TextRTF[pos] != '\\')) {
                            tmp[1] = TextRTF[pos++];
                            fs32 = fs32 + tmp;
                        }
                }

          break;
          case ' ': ;
          case '\r': ;
          case '\n': pos++;
          break;
          default: nb++;
                pos++;
        }
        if ((nb == 1) && (fs32 != "fs32"))
            Caract[1] = TextRTF[pos-1];

    } while(fs32 != "fs32");

    return nb;

}
//---------------------------------------------------------------------------

const AnsiString Hexa = "0123456789ABCDEF";

double __fastcall TTexteChild::HexToInt(AnsiString Valeur)
{
double exp, convert;
int i, curs;

    Valeur = Valeur.UpperCase();
    exp = 1;
    convert = 0;
    for( i=Valeur.Length(); i>0; i--) {
        curs = 1;
        while( Valeur[i] != Hexa[curs]) curs++;
        convert += (curs-1) * exp;
        exp *= 16;
    }
    return convert;
}
//---------------------------------------------------------------------------

Conclusion :


On pourrait ajouter des options de cryptographie, je le ferais peut-être.

Pendant les vacances scolaires je suis pas souvent sur le net, alors je repondrai quand même à vos questions mais avec du retard.
25/06/2004

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
14
Date d'inscription
lundi 5 août 2002
Statut
Membre
Dernière intervention
30 août 2004

je ne tiens pas ca d'une source sure mais il me semble que le wav a une entetes et que dans celle ci il y a l'echantillonnage et d'autre renseignement comme la longueur du fichier et donc les API windows en lisant cette entete connaisse le nombre de frame donc il serai peut etre possible en modifiant cette derniere créer un fichier qui au lieu de x frame par s en aurrai x+1 ou x+0.1 (pour alterer un peu moins le fichier) ce qui aurait comme resultat que seule de rares personnes veraient la difference (c'est le meme principe que pour les image subliminale). il me semble egalement que le wav est code sur un octet qui contient la hauteur de la sortie (c'est le plus simple car en faisant varier la hauteur de sortie plus ou moins vite on fait varier la freqence le vol etc) voila ce que je pus lire sur internet pour le MP3 je vais chercher
Messages postés
147
Date d'inscription
mercredi 18 septembre 2002
Statut
Membre
Dernière intervention
15 avril 2011

C'est vrai les formats non compressés permettent de cacher plus facilement des informations, ils sont aussi plus facile comprendre. Seulement ils sont bien moins utilisé et donc soumis à une attention plus grande.

Example :
Je suis un industriel et je ne souhaite pas que mon concurant (voir le réseau échelon lui même) soit avisé d'un marché potentiel que je suis sur le point de remporter. Je veux envoyer un mail à mon associé. Je choisis une de mes photos de vacances et j'écris un message bidon convenu avec ce dernier. Vais je envyer un BMP ou une JPG ? Si j'envoi un BMP et que mon message est intercepté, je serais tout de suite repéré alors qu'avec une JPEG, c'est moins sûr.

Les formats non compréssés c'est bien pour se faire la main, mais après ça sert à quoi de faire de la stéganogaphie si c'est pour ce faire repéré direct ?

PS : Une adresse internet est la bien venu aussi.
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
35
jpg, j'ai jamais essayé, mais je penses que les formats non compressés sont largement plus performants que les formats compressés pour las stégano.

Je n'ai jamais essayé le jpg, mais j'ai vu comment on compressait, voir login n ° je sais plsu combien, que je retrouve ce login, je vous donne le n°
Le jpg est très performant et très compliqué, donc, je ne m'y ataquerais vraiment pas...
Messages postés
147
Date d'inscription
mercredi 18 septembre 2002
Statut
Membre
Dernière intervention
15 avril 2011

Je te remercie coucou747, ce programme est le mien. L'idée de le créer à germer en classe avec gilouBZH et je l'ai fait. je te remercie gilou de répondre à ma place c'est sympa.

Quand à ton idée pour le .wav, elle me plait. gilouBZH t'en parlerai mieux que moi mais le wav est très semblable au bmp. Il ne compresse rien. Ce n'est pas le cas du mp3. Pour reprendre une expression de gilou, le mp3, c'est une oreille numérique. En fait le MP3 n'enregistre que les sons audibles par la plupart des gens. Donc mon idée est simple : si le MP3 ne s'en sert pas on peut les modifier dans un WAV. D'un point de vue technique je pense (ce n'est qu'une supposition) que le wav enregistre trois information pour un son unique : la fréquence, le volume et (ce qui n'est pas très probable) le nombre de fois que le son doit être répéter à la suite. Je t?invite avant de faire des recherches sur le WAV à en faire sur la nature même des sons (se sont des fréquences mécanique car elles ont besoins d'un support physique pour être émises (métal, bois, corde, membrane de HP) et pour être transporté (l'air)). Si ne trouve toujours rien oriente toi vers les explications sur le MP3 : tu pourrai cacher les infos dans l'octet qui code le volume. De plus, MP3 est bien plus répandu que le WAV, donc moins suspect.

Tiens moi au courant, je me passionne moi aussi de stégano. Mon prochain projet dans le domaine devrait être de cacher un fichier dans une JPEG. Bonne continuation.
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
35
oui évidement, je lançais seulement un défi
en fait, je t'expliques, je ne trouves pas la façon d'utiliser les .wav sur internet, ils n'expliquent pas grand chose sur ce format de musique peu compressé... J'adore toutes ces techniques stégano crypto etc... J'ai fait un programme de stégano pour cacher du texte dans les images bmp, je trouves mon programme plutot pas mal, les bmp sont des images parfaites pour cela, car elles laissetn pas mal de place.... Cependant, je me suis dit que les wav étaient un format de musique plutot peu compressé, donc ou l'on pouvait cacher bcp de choses, et en plus,n les wav ont un avantage par raport au bmp : une image bmp on l'a entièrement sous les yeux, un wav, on en écoute qu'une partie a un même moment, on écouyte pas tout le wav e nune seconde, donc on ne verra pas tout les défauts que la stégano y aura ajouté en même temps...

Donc, ne trouvant pas comment retoucher un wav en le laissant lisible et en le touchant le mons possible, j'ai posé ce comentaire en me disantque qqn pourrait essayer de m'indiquer comment faire ce programme ou le faire lui même...
(j'ai peut-être un peu manqué de tact excusez moi)

cependant ton programme n'ets pas mal du tout
Afficher les 13 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.