Réseau de sites : les codes FTP

Vous gérez un réseau de site sans jamais vous connecter en FTP, allez directement poster un commentaire pour nous expliquer votre méthode, sinon bonne lecture !

Le point de départ

Tout remonte à un cours de math en 2008 quand mon prof avait comme mission de nous initier à la cryptographie.

Il nous fit découvrir l’algorithme RSA pour Rivest Shamir Adleman, leurs auteurs (et non  Revenu de Solidarité Active). Celui là même qui est utilisé par le protocole SSL.

L’idée repose sur la génération d’une paire de clé : une public et une privée qui servent respectivement à crypter et à décrypter. La clé public peut être distribuée à n’importe qui, à l’inverse de la clé privée qui doit rester confidentielle.

Mais comme quasiment tous les cours, nous n’avons vu que la théorie avec les calculs de modulo. Donc à ce stade de mon développement, je me partais avec « ma bite et mon couteau ».

Premiers essais

Mon idée était de pouvoir saisir les codes FTP dans notre back office (environnement PHP), puis d’y accéder via un petit logiciel (environnement C#). Car si l’on crypte et l’on décrypte du même côté, une attaque informatique révélerai nos 2 clés et rien ne retiendrait les pirates.

En développeur un peu candide, je suis parti directement sur OpenSSL disponible dans WAMP, après l’avoir activé. Mais dès l’appel à la fonction openssl_pkey_new, j’avais une erreur. Puis en creusant un peu cela paraissait bien compliqué pour avoir simplement un fichier qui ressemblais à ça.

—–BEGIN PUBLIC KEY—–
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIWaWudcMlKuQY9bbaOM36BOdM
3fGBFyAFCINR1tFxMdd1+whHqVuycsyR1l8JDEK9kQ17aXEFEJwMa59IlhiCPnHN
LGi8wtHZruZi84fxNc7R83XTBhxbOao28QZjCxjY5jNKZdp8jNwbXhG18JGXNSVr
IQPQ79j9qOi1sH22nwIDAQAB
—–END PUBLIC KEY—–

Après avoir passé plusieurs heures en vain avec OpenSSL, je me suis demandé : Et en C# ? Puis je suis tombé sur Bouncy Castle, mon sauveur ! « A lightweight cryptography API for Java and C# ».

A partir de là j’ai pu :

  • Générer ma clé public pour PHP
  • Générer ma clé privée pour C#
  • Tester avec succès le décryptage de données venu de PHP.

Trêve de bavardage, place au code !

Générer la clé public

RsaKeyPairGenerator r = new RsaKeyPairGenerator();
r.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
AsymmetricCipherKeyPair keys = r.GenerateKeyPair();System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\mypublic.txt");
PemWriter pemWriter = new PemWriter(file);
pemWriter.WriteObject(keys.Public);
file.Close();

Démarrer un nouveau projet C# et commencez par copier/coller ce code.

Il va créer la clé public utilisable par PHP dans le fichier « C:\mypublic.txt »

Générer la clé privée

//BouncyCastle's Key objects
RsaPrivateCrtKeyParameters rpckp = ((RsaPrivateCrtKeyParameters)keys.Private);

//.NET RSA Key objects
System.Security.Cryptography.RSACryptoServiceProvider rcsp = new System.Security.Cryptography.RSACryptoServiceProvider();
System.Security.Cryptography.RSAParameters parms = new System.Security.Cryptography.RSAParameters();

//So the thing changed is offcourse the ToByteArrayUnsigned() instead of
//ToByteArray()
parms.Modulus = rpckp.Modulus.ToByteArrayUnsigned();
parms.P = rpckp.P.ToByteArrayUnsigned();
parms.Q = rpckp.Q.ToByteArrayUnsigned();
parms.DP = rpckp.DP.ToByteArrayUnsigned();
parms.DQ = rpckp.DQ.ToByteArrayUnsigned();
parms.InverseQ = rpckp.QInv.ToByteArrayUnsigned();
parms.D = rpckp.Exponent.ToByteArrayUnsigned();
parms.Exponent = rpckp.PublicExponent.ToByteArrayUnsigned();

//So now this now appears to work.
rcsp.ImportParameters(parms);
Console.WriteLine(rcsp.ToXmlString(false));

file = new System.IO.StreamWriter(@"C:\myprivate.txt");
file.WriteLine(rcsp.ToXmlString(true));
file.Close();

A la suite du premier morceau de code, vous pouvez ajouter celui là qui lui, va créer la clé privée utilisable par C# dans le fichier « C:\myprivate.txt »

Crypter les données

function encrypt_data($data)
{
$pubKey = openssl_pkey_get_public(file_get_contents(chemin du fichier clé public));
openssl_public_encrypt($data, $encryptedData, $pubKey);
return $encryptedData;
}

Vous aurez reconnu une fonction PHP qui utilise le premier fichier créé pour crypter des données.

Décrypter les données

public void decrypt(byte[] data)
{
System.Security.Cryptography.RSACryptoServiceProvider rcsp = new System.Security.Cryptography.RSACryptoServiceProvider();
rcsp.FromXmlString("coller votre clé privée ici");

var str = Encoding.UTF8.GetString(rcsp.Decrypt(data, false));
var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<<string>>(str);
}

Et voici le dernier bout de code pour décrypter du côté de C#.

Amusez-vous !

J’ajouterai que pour faciliter l’enregistrement en BDD et le transit des données, j’encode par dessus en base64. Et pour corser le tout, dans ma fonction PHP je sale. Mais tout ça c’est à vous de le coder !

A propos Xavier BOËT

Ingénieur en architecture logiciel, je suis devenu entrepreneur dans le référencement à travers Force-Référencement. Aujourd'hui j'aide nos clients à être plus visible dans les moteurs de recherche tout en continuant à développer des outils pour le référencement via Stateo
Ce contenu a été publié dans Développement. Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *