Calculer et vérifier un checksum pour dialoguer avec l'extérieur

Comme je l'ai indiqué lorsque j'ai présenté l'équivalent des fonctions suivantes en Delphi il arrive que l'on ait besoin de faire des échanges d'informations entre différents sites, logiciels, applications à travers une API et que l'intégrité de ces informations doivent être contrôlée.

Côté Delphi c'est pour la partie "cliente" des projets, sous forme de logiciel pour Windows, MacOS ou Linux, d'application mobile pour iOS ou Android, ou sur des serveurs avec les fonctionnalités WebBrocker et IntraWeb.

Le côté PHP est plus pour les serveurs qui sont à la source de l'API et des données échangées.

Dans le cas des API que je mets en place il me faut contrôler parfois l'intégrité de ce qui est échangé et j'utilise donc un calcul de checksum entre les paramètres et une clé secrête connue par les deux interlocuteurs mais ne transitant pas (ou très rarement) en clair. Je pourrais aussi pousser la sécurité à crypter le tout. N'ayant pas de fonctions de cryptographie compatibles dans tous les langages utlisés, je limite la crypto au https (ce qui est léger, je le reconnais).

Le calcul du checksum se fait par la fonction getVerifChecksum() qui prend les informations à contrôler et les clés en paramètres pour ressortir une chaine de 10 caractères. Le calcul est simple : on concatène tout, on fait un calcul de MD5 dessus puis on en ressort une partie.

	// return a checksum value for "verif" URL param
	function getVerifChecksum($param, $key1="", $key2="", $key3="", $key4="", $key5="", $public=true)
	{
		$verif = "";
		if (is_array($param)) {
			$par = "";
			foreach($param as $value) {
				$par .= $value;
			}
			$verif = md5($par.$key1.$key2.$key3.$key4.$key5);
		}
		else {
			$verif = md5($param.$key1.$key2.$key3.$key4.$key5);
		}
		return ($public)?substr($verif,mt_rand(0,strlen($verif)-10),10):$verif;
	}

La vérification se fait en comparant un calcul du checksum et la chaine de contrôle reçue avec les éléments à contrôler. C'est la fonction checkVerifChecksum() qui s'en charge. On lui passe les mêmes paramètres que pour getVerifChecksum(), dans le même ordre, et la variable $verif qui contient le code de contrôle reçu.

	// check a "verif" checksum value
	// return TRUE if ok, FALSE if not
	function checkVerifChecksum($verif, $param, $key1="", $key2="", $key3="", $key4="", $key5="")
	{
		if ((strlen($verif) < 1) && isset($_POST["verif"]))
		{
			$verif = $_POST["verif"];
		}
		if ((strlen($verif) < 1) && isset($_GET["verif"]))
		{
			$verif = $_GET["verif"];
		}
		return (false !== strpos(getVerifChecksum($param, $key1, $key2, $key3, $key4, $key5, false),$verif));
	}

En faisant ainsi on se retouve à s'assurer que ce qui est envoyé est cohérent avec ce qu'on reçoit. Que ça n'a pas été modifié en chemin.

Ca ne permet pas de s'assurer de l'authenticité de l'émetteur des informations puisque le même contrôle des mêmes informations donnera toujours le même résultat. Il faudrait ajouter une notion de session ou un paramètres variable, ce qui était l'objet du projet Log'n Pass utilisable pour se connecter avec une double authentification mais aussi récupérer par programme une valeur changeant chaque minute.