Cprb criptage par position aléatoire de clock

Contenu du snippet

Petite class d'extension de la la class String permettant de crypter une chaine par un algorythme de cryptage de ma conception.
l'algo decoupe la chaine par block , reverse les chars du block , intercale deux indice de decryptage dans chaque bloc puis,
Applique une opération binaire sur chaque eléments du bloc avec une variable prédefini dans les blocks
et place le blocks a une position aléatoire dans la chaine finale.
et enfin une compression Gzip de la chaine finale

j'ai ajouté l'expliquation de la procedure de cryptage étape par etape

la classe Crypte et Decrypte

Source / Exemple :


using System;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Collections.Generic;

/*

  • Algorhytme de cryptage par bloc
  • Cryptage :
  • Etape 1 : Concatenation de la clé de cryptage et du nom de l'appliquation (Salage)
  • Etape 2 : Hachage en MD5 de la chaine obtenu a l'etape 1
  • Etape 3 : Cryptage
  • Etape 3.1 : Découpage du texte a crypter en block de 4 caracteres Ajout de X '0' si neccessaire ( Text.longueur % 2 )
  • Etape 3.2 : Création d'une matrice int a deux dimension
  • Int[X Block , 4 + 2]
  • Etape 3.3 : Creation d'une liste de int remplie de chaque position possible de chaque block
  • Etape 3.4 : Remplissage de la matrice
  • Etape 3.4.1 : Piochage d'une position aléatoire dans la liste de int
  • retrait de cette position
  • Etape 3.4.2 : Matrice[position,0] = Block[0][3]
  • Matrice[position,1] = index du char aléatoire dans la clé MD5
  • Matrice[position,2] = Block[0][2]
  • Matrice[position,3] = Block[0][1]
  • Matrice[position,4] = index réel du bloc
  • Matrice[position,5] = Block[0][3]
  • Répetition de l'Etape 3.4.2 pour chaque blocs
  • Etape 4 : Création d'une chaine Hexadecimal
  • Etape 4.1 : Ajout de debut de chaine la valeur Hexadecimal du nombre '0' Ajouté a l'Etape 3.1
  • Etape 4.2 : Pour chaque élément de la matrice d'index i
  • chaineHexadecimal += " " + Matrice[i,0].ToString("X") = Matrice[i,0] ^ keyMD5[Matrice[i, 1]];
  • chaineHexadecimal += " " + Matrice[i,1].ToString("X") = Matrice[i,1] ^ keyMD5.Length;
  • chaineHexadecimal += " " + Matrice[i,2].ToString("X") = Matrice[i,2] ^ keyMD5[Matrice[i, 1]];
  • chaineHexadecimal += " " + Matrice[i,3].ToString("X") = Matrice[i,3] ^ keyMD5[Matrice[i, 1]];
  • chaineHexadecimal += " " + Matrice[i,4].ToString("X") = Matrice[i,4] ^ Matrice[i, 1];
  • chaineHexadecimal += " " + Matrice[i,5].ToString("X") = Matrice[i,5] ^ keyMD5[Matrice[i, 1]];
  • Etape 5 : Crompression GZip de la chaine Hexadecimal
  • /
namespace YohanFrameWork.Security { /// <summary> /// Algorhytme CPRB Crypting by positioning random of blocks /// </summary> public static class YFW_CPRB { #region ALGORHYTME CPRB CRYPTING BY POSITIONING RANDOM OF BLOCKS /// <summary> /// Crypte un text suivant la clé 'KeyCryptage' et le clé de salage 'SalageKey' /// </summary> /// <param name="data"></param> /// <param name="KeyCryptage">Clé de cryptage</param> /// <param name="SalageKey">Clé de salage http://fr.wikipedia.org/wiki/Salage_(cryptographie)</param> /// <exception cref="System.ArgumentException"></exception> /// <returns></returns> public static string CPRB_Crypte(this string data, String KeyCryptage, String SalageKey) { if (data == null || data == string.Empty) throw new System.ArgumentException("La chaine ne peut pas etre null ou vide", "this"); if (KeyCryptage == null || KeyCryptage == string.Empty) throw new System.ArgumentException("La chaine ne peut pas etre null ou vide", "Key"); /*
  • Generation d'une clé crypté en md5 salé a partir de la clé passé en parametre
  • /
String keyMD5 = KeyCryptage.CPRB_KeyToMD5(SalageKey); Random rand = new Random(); /*
  • La chaine a crypter doit etre de longueur paire
  • donc on va calculer le nombre de caracteres manuants et completer la data avec des 'X'
  • /
int excedent = (data.Length % 2); data += new string('X', 4 - excedent); /*
  • Calcule du nombre de blocs neccéssaire
  • /
int countblock = data.Length / 4; /*
  • Creation de la matrice a deux dimensions
  • [countblock,6] : pourquoi 6 ?
  • car 4 char pioché dans 'data'
  • + 1 emplacements identifiant la position du block néccessaire au decryptage
  • + 1 emplacement identifiant l'index du char opérateur binaire pioché dans 'key'
  • /
Int32[,] Matrice = new Int32[countblock, 6]; /*
  • Cration d'une liste de int qui servira a pioché une position aléatoire du block
  • et on la remplie avec des int de 0 ... countblock
  • /
List<int> arrayposition = new List<int>(); for (int i = 0; i < countblock; i++) { arrayposition.Add(i); } /*
  • Découpage de data par groupe de 4 char
  • et remplissage aléatoire de 'Blocks'
  • /
int pos_firth_char = 0; for (int i = 0; i < countblock; i++, pos_firth_char += 4) { //lecture de 4 char Char[] currentblock = data.ToCharArray(pos_firth_char, 4); // piochage aléatoire d'une position disponible dans la liste de positions int position = arrayposition[rand.Next(arrayposition.Count)]; // On retire la position de la liste arrayposition.Remove(position); Matrice[position, 0] = currentblock[3]; // char 3 a la position 0 Matrice[position, 1] = rand.Next(keyMD5.Length); // index du char aléatoire dans la clé Matrice[position, 2] = currentblock[2]; // char 2 a la position 1 Matrice[position, 3] = currentblock[1]; // char 1 a la position 2 Matrice[position, 4] = i; // position reél du block indispenssable au décryptage Matrice[position, 5] = currentblock[0]; // char 0 a la position 3 } #if DEBUG /*
  • Arrive ici, les char du texte sont completement mélanger
  • /
Console.Write("Text Melangé : \n"); for (int i = 0; i < countblock; i++) { Console.Write(String.Format("{0}{1}{2}{3}", (char)Matrice[i, 0], (char)Matrice[i, 2], (char)Matrice[i, 3], (char)Matrice[i, 5])); } Console.Write("\n"); #endif /*
  • Génération d'une chaine hexadecimale
  • /
//On commence par indiquer combien de char on a du ajouter a data StringBuilder crypted = new StringBuilder(excedent.ToString("X")); for (int i = 0; i < countblock; i++) { for (int j = 0; j < 6; j++) { int c = 0; crypted.Append(" "); switch (j) { case 0: case 2: case 3: case 5: c = (int)Matrice[i, j] ^ keyMD5[Matrice[i, 1]]; #if DEBUG Console.WriteLine("blocks[{0},{1}] c = (int){2} ^ {3} = {4};", i, j,(int)Matrice[i,j],(int)keyMD5[Matrice[i, 1]],c); #endif break; case 1: c = (int)Matrice[i, j] ^ keyMD5.Length; #if DEBUG Console.WriteLine("blocks[{0},{1}] c = (int){2} ^ {3} = {4};", i, j, (int)Matrice[i, j], keyMD5.Length, c); #endif break; case 4: c = (int)Matrice[i, j] ^ Matrice[i, 1]; #if DEBUG Console.WriteLine("blocks[{0},{1}] c = (int){2} ^ {3} = {4};", i, j, (int)Matrice[i, j], (int)keyMD5[Matrice[i, 1]], c); #endif break; } crypted.Append(c.ToString("X")); } } // Compression de la chaine Hexadecimal et return du la chaine compressé return crypted.ToString().CPRB_Compress(); } /// <summary> /// Dérypte un text suivant la clé 'KeyCryptage' et le clé de salage 'SalageKey' /// </summary> /// <param name="data"></param> /// <param name="KeyCryptage">Clé de cryptage</param> /// <param name="SalageKey">Clé de salage http://fr.wikipedia.org/wiki/Salage_(cryptographie)</param> /// <exception cref="System.ArgumentException"></exception> /// <returns></returns> public static string CPRB_Derypte(this string data, string KeyCryptage, String SalageKey) { if (data == null || data == string.Empty) throw new System.ArgumentException("La chaine ne peut pas etre null ou vide", "this"); if (KeyCryptage == null || KeyCryptage == string.Empty) throw new System.ArgumentException("La chaine ne peut pas etre null ou vide", "Key"); /*
  • Generation d'une clé crypté en md5 salé a partir de la clé passé en parametre
  • /
String keyMD5 = KeyCryptage.CPRB_KeyToMD5(SalageKey); /*
  • Découpage de data
  • /
String[] tokens =data.CPRB_Decompress().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); /*
  • Recperation de l'exedent de char
  • /
int excedent = 0; if(!Int32.TryParse(tokens[0], System.Globalization.NumberStyles.HexNumber,null, out excedent)) throw new System.ArgumentException("echec tryParse sur recuperation de l'excedent", tokens[0]); /*
  • Creation d'un tableau de string de taille X
  • X = (tokens.lenght - 1(exedent)) / 6(nb de chaine Hexadecimale par Block
  • /
String[] blocks = new String[(tokens.Length-1) / 6]; for (int i = 1; i < tokens.Length; i+= 6) { try { // Recuperation de l'index sur la clef keyMD5 int valindexkey = 0; if(Int32.TryParse(tokens[i + 1], System.Globalization.NumberStyles.HexNumber,null,out valindexkey)) valindexkey ^= keyMD5.Length; // Recuperation de l'index réel du block int valindexblock = 0; if(Int32.TryParse(tokens[i + 4], System.Globalization.NumberStyles.HexNumber,null,out valindexblock)) valindexblock ^= valindexkey; // Recuperation des caracteres réels int[] block = new int[4]; if(Int32.TryParse(tokens[i], System.Globalization.NumberStyles.HexNumber,null,out block[0])) block[0] ^= keyMD5[valindexkey]; if (Int32.TryParse(tokens[i + 2], System.Globalization.NumberStyles.HexNumber, null, out block[1])) block[1] ^= keyMD5[valindexkey]; if (Int32.TryParse(tokens[i + 3], System.Globalization.NumberStyles.HexNumber, null, out block[2])) block[2] ^= keyMD5[valindexkey]; if (Int32.TryParse(tokens[i + 5], System.Globalization.NumberStyles.HexNumber, null, out block[3])) block[3] ^= keyMD5[valindexkey]; // Formatage du block[X] blocks[valindexblock] = String.Format("{0}{1}{2}{3}", (char)block[3], (char)block[2], (char)block[1], (char)block[0]); } catch (Exception ex ) { Console.WriteLine(ex.Message); throw new System.ArgumentException("Echec d'analyse des Tokens"); } } // Suppression des caractéres en trop if((blocks.Length - 1) >= 0) blocks[blocks.Length - 1] = blocks[blocks.Length - 1].Remove(4 - excedent); return String.Join("", blocks); } #endregion ALGORHYTME CPRB CRYPTING BY POSITIONING RANDOM OF BLOCKS #region COMPRESSION / DÉCOMPRESSION GZIP /// <summary> /// Compression de chaine /// </summary> /// <param name="text"></param> /// <returns></returns> public static String CPRB_Compress(this String text) { byte[] buffer = Encoding.UTF8.GetBytes(text); MemoryStream ms = new MemoryStream(); using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true)) { zip.Write(buffer, 0, buffer.Length); } ms.Position = 0; MemoryStream outStream = new MemoryStream(); byte[] compressed = new byte[ms.Length]; ms.Read(compressed, 0, compressed.Length); byte[] gzBuffer = new byte[compressed.Length + 4]; System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length); System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4); StringBuilder result = new StringBuilder(); return Convert.ToBase64String(gzBuffer); } /// <summary> /// Décompression de chaine /// </summary> /// <param name="compressedText"></param> /// <returns></returns> public static String CPRB_Decompress(this String compressedText) { byte[] gzBuffer = Convert.FromBase64String(compressedText); using (MemoryStream ms = new MemoryStream()) { int msgLength = BitConverter.ToInt32(gzBuffer, 0); ms.Write(gzBuffer, 4, gzBuffer.Length - 4); byte[] buffer = new byte[msgLength]; ms.Position = 0; using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress)) { zip.Read(buffer, 0, buffer.Length); } return Encoding.UTF8.GetString(buffer); } } #endregion COMPRESSION / DÉCOMPRESSION GZIP #region SALAGE MD5 /// <summary> /// Crypte une chaine en MD5 avec salage http://fr.wikipedia.org/wiki/Salage_(cryptographie) /// </summary> /// <param name="target"></param> /// <param name="SalageKey">Clé de salage http://fr.wikipedia.org/wiki/Salage_(cryptographie)</param> /// <returns></returns> private static String CPRB_KeyToMD5(this String target, String SalageKey) { System.Security.Cryptography.MD5 md5HashAlgo = System.Security.Cryptography.MD5Cng.Create(); // Place le texte à hacher dans un tableau d'octets byte[] byteArrayToHash = Encoding.UTF8.GetBytes(target + SalageKey); // Hash le texte et place le résulat dans un tableau d'octets byte[] hashResult = md5HashAlgo.ComputeHash(byteArrayToHash); StringBuilder result = new StringBuilder(); for (int i = 0; i < hashResult.Length; i++) { // Affiche le Hash en hexadecimal result.Append(hashResult[i].ToString("X2")); } return result.ToString(); } #endregion SALAGE MD5 } }

Conclusion :


exemple d'utilisation de la class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YohanFrameWork.ExtendedType;
using YohanFrameWork.Security;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
string s = null;
s = @"Pendant que ma tante devisait ainsi avec Françoise, j?accompagnais mes parents à la messe. Que je l?aimais, que je la revois bien, notre Église! Son vieux porche par lequel nous entrions, noir, grêlé comme une écumoire, était dévié et profondément creusé aux angles (de même que le bénitier où il nous conduisait) comme si le doux effleurement des mantes des paysannes entrant à l?église et de leurs doigts timides prenant de l?eau bénite, pouvait, répété pendant des siècles, acquérir une force destructive, infléchir la pierre et l?entailler de sillons comme en trace la roue des carrioles dans la borne contre laquelle elle bute tous les jours.";
Console.WriteLine("Texte original : \n{0}\n", s);
s = s.CPRB_Crypte("azerty", AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine(String.Format("Texte codé avec : {0} et {1}\n{2}\n", "azerty", AppDomain.CurrentDomain.FriendlyName, s));
Console.WriteLine(String.Format("Texte Décodé avec : {0} et {1}\n{2}\n", "azerty", AppDomain.CurrentDomain.FriendlyName, s.CPRB_Derypte("azerty", AppDomain.CurrentDomain.FriendlyName)));
Console.WriteLine(String.Format("Texte Décodé avec : {0} et {1}\n{2}\n", "qwerty", AppDomain.CurrentDomain.FriendlyName, s.CPRB_Derypte("qwerty", AppDomain.CurrentDomain.FriendlyName)));
}
catch (ArgumentException ex )
{

Console.WriteLine(ex.Message);
}
Console.Read();
}
}
}

A voir également

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.