L’objectif de cet article est de montrer comment, d’une manière facile à mettre en œuvre, vous pouvez signer et vérifier des documents de manière transparente.
L’avantage évident de cette approche est la tranquillité d’esprit lorsque les documents sont ouverts à nouveau, avec la certitude qu’ils n’ont pas été modifiés entre-temps.
Ceci est particulièrement important si vous stockez des documents 4D Write Pro sous forme de modèles intelligents contenant du code 4D en tant que fichiers externes sur le disque. Avant d’exécuter ce code, vous voulez vous assurer que le fichier n’a pas été modifié de l’extérieur.
Ou, dans le cas de documents externes, être certain qu’ils proviennent du bon expéditeur et qu’ils n’ont pas été modifiés au cours de leur parcours numérique.
Le principe que nous allons décrire s’applique aux documents 4D Write Pro, mais aussi à tout autre type de document, moyennant quelques modifications mineures.
Exemple de base de données
Chiffrement ou signature ?
Nous allons ici nous concentrer sur l’authentification d’un document, c’est-à-dire comment s’assurer qu’il n’a pas été modifié entre le moment où il a été enregistré par son propriétaire original (légal/officiel/etc.) et le moment où il est lu par son destinataire (ou relu par son propriétaire !). Nous ne parlons pas ici de cryptage, bien que cela soit également possible, mais c’est un autre sujet ! (Si vous vous intéressez à la cryptographie, reportez-vous à ce BLOG)
Création d’une signature.
Le processus de création d’une signature est assez simple : à partir du document original, nous créons une signature basée sur le document entier (en tant que BLOB) à l’aide d’une clé « privée ». Cette signature (et uniquement cette signature) sera stockée dans le document lui-même, généralement à la fin du document.
Relire la signature
Avant d’ouvrir le document, la signature officielle est relue. Un nouveau BLOB sera créé à partir de l’ensemble du document (sans la clé de fin, donc théoriquement identique à l’original) et sera vérifié, cette fois à l’aide d’une clé publique, intimement liée à la clé privée qui a été utilisée pour créer la signature. Le résultat de cette vérification déterminera la suite des événements !
À ce stade, trois possibilités s’offrent à nous…
Nous avons supposé que le document était signé, mais ce n’est pas forcément le cas. Si le document ne contient pas de signature, la prudence est de mise, mais il n’est pas nécessairement corrompu.
L’ouverture ou non du document dépend du développeur, de l’utilisateur, des circonstances, de l’environnement… Bref, c’est à vous de décider !
La deuxième possibilité est que la signature corresponde au contenu. Bonne nouvelle alors. Vous pouvez être sûr que le document est celui que vous avez créé ou qui vous a été confié/envoyé/etc., et surtout qu’il n’a pas été modifié depuis sa création. Vous pouvez donc l’ouvrir en toute tranquillité, à condition bien sûr de faire confiance à l’expéditeur. Vous êtes ensuite libre de le modifier, de le sauvegarder, de le signer à nouveau ou non, en fonction de son utilisation future. Si vous devez le modifier et le renvoyer à l’expéditeur, il est bon de le signer vous-même, afin que la même opération puisse être effectuée par le futur destinataire.
Enfin, la troisième possibilité est que le document ait été altéré (voire corrompu) lors du transfert. La moindre virgule ajoutée ou supprimée, la moindre formule modifiée, etc. feront que la signature ne correspondra plus !
Vous le saurez immédiatement et pourrez ainsi prendre les mesures qui s’imposent.
C’est parti !
Dans cet exemple, nous allons signer un ou plusieurs fichiers existants déjà enregistrés au format 4D Write Pro, c’est-à-dire avec une extension . « 4wp ». Comme nous allons gérer des fichiers, nous allons utiliser les classes 4D.File et 4D.FileHandle. Et comme nous allons gérer des clés de chiffrement, de signature et de vérification, nous utiliserons également la classe 4D.CryptoKey (voir le BLOG correspondant si vous n’êtes pas encore familiarisé avec ces classes…).
SAFE Créer des clés par défaut
Tout d’abord, nous allons créer une paire de clés privées/publiques et les stocker une fois pour toutes en tant qu’entité dans la base de données (cette paire de clés sera utilisée comme clés « par défaut » plus tard, à titre d’exemple).
$cryptoKey:=ds.CryptoKey.new()
$keyOptions:={type: "RSA"; size: 2048}
$key:=4D.CryptoKey.new($keyOptions)
$cryptoKey.privateKey:=$key.getPrivateKey()
$cryptoKey.publicKey:=$key.getPublicKey()
$cryptoKey.save()
Signature du document SAFE
Ensuite, vous devez ajouter une signature à la fin d’un fichier (4D.File) à l’aide d’une clé privée.
En résumé, voici ce qu’il faut faire :
// create a new key based on private key
$keyOptions:={type: "PEM"; pem: $privateKey}
$key:=4D.CryptoKey.new($keyOptions)
//…
// create the signature with the .sign() function
$signOptions:={hash: "SHA512"; encodingEncrypted: "Base64URL"}
$signature:=$key.sign($documentAsBlob; $signOptions)
// append signature (as a BLOB) at the end of the document
TEXT TO BLOB($signature; $blobSignature; UTF8 text without length)
$fileHandle.offset:=$documentSize
$fileHandle.writeBlob($blobSignature)
SAFE Vérifier la signature
Enfin, AVANT d’ouvrir le document, il faut vérifier sa signature. Cela se fait par la méthode suivante, à laquelle on passe un fichier (4D.File) et, optionnellement, une clé publique
// create a new key based on public key
$signOptions:={hash: "SHA512"; encodingEncrypted: "Base64URL"}
$type:={Type; "PEM"; pem; $publicKey}
$key:=4D.CryptoKey.new($type)
// read the real signature
//…
$fileHandle.offset:=$documentSize-$length
$blobSignature:=$fileHandle.readBlob($length)
$textSignature:=BLOB to text($blobSignature; UTF8 text without length)
// check the signature using the .verify() function
$check:=$key.verify($documentAsBlob; $signature; $signOptions)
If ($check.success)
$result:=1
Else
$result:=-1
End if
Cela fonctionne avec .4wp, mais qu’en est-il des autres documents ?
Lorsque 4D Write Pro charge un document .4wp, la fin du document est automatiquement détectée afin que vous sachiez où vous arrêter. La signature ajoutée à la fin du fichier ne le perturbe pas. En d’autres termes, que le document soit signé ou non, que la signature soit correcte ou non, le .4wp sera chargé sans problème, d’où la nécessité de vérifier sa signature au préalable.
Pour d’autres types de documents, il est possible (voire probable) que l’ajout d’une signature à la fin perturbe le chargement, il peut donc être nécessaire – après validation bien sûr – de supprimer la signature.
SAFE Désigner un document
C’est pourquoi cette autre méthode a été créée pour effectuer l’opération inverse.
Elle supprime la signature d’un document pour le remettre dans son état d’origine, et si le document n’est pas signé, elle ne fait rien.
$fileHandle:=$file.open("write")
//… calculate signature length then…
$fileHandle.setSize($documentSize-$length)
Conclusion
Cet exemple simple montre comment signer un document et vérifier la signature avant de l’ouvrir. Lors de l’échange de documents entre deux sites, deux paires de clés publiques/privées sont nécessaires, mais le principe reste le même. Le créateur du document signe avec une clé privée et le lecteur vérifie avec la clé publique fournie par le créateur.
Les clés publiques et privées sont des biens précieux, permettant à la fois la signature et l’authentification, c’est pourquoi il est conseillé de les sauvegarder dans le fichier Data lui-même !