Documentation

Fisy est une application en ligne de commande dédiée à la copie et à la sauvegarde de fichiers. Son pilotage et le paramétrage des tâches de recopie se fait via un seul fichier de configuration de type XML dont la description se trouve dans la documentation ci-après.
Une fois le fichier de configuration crée, executer Fisy avec la ligne de commande :  fisy nomDuFichierDeConfiguration.xml

Fichier de configuration

Ce fichier de configuration XML est un fichier où vous allez définir tous vos choix de sauvegarde. Par exemple, quels fichiers doivent être sauvegardés (définir la source et la destination), quel est le type de copie à lancer, faut-il utiliser le chiffrement, quel est le niveau de traçabilité des tâches (les logs), etc...
Pour cela vous pouvez vous inspirer des fichiers "configuration_example.xml" et "configuration_template.xml" présents dans le répertoire d'installation de Fisy et contenant des exemples de configuration. A noter qu'un fichier XML est un fichier texte lisible pour un humain, vous pouvez donc en créer un ou en ouvrir un avec un éditeur de texte tel que le Bloc-notes pour ceux qui sont sous Windows.

Voici un exemple minimal d'un fichier de configuration Fisy définissant une tâche de recopie de type "synchronisation" de c:\data\source vers d:\backup\target <?xml version="1.0" encoding="UTF-8"?>
<fisy>
  <task name="MyFirstTask" type="SYNCHRONIZE">
    <src path="c:\data\source" />
    <dest path="d:\data\target" />
    <log path="d:\data\log" level="INFO" />
  </task>
</fisy>

Avec :

  • name : un identifiant représentant le nom de la tâche.
  • type : une tâche de type synchronisation (voir ci-dessous).
  • src : le répertoire source.
  • dest : le répertoire destination.
  • log : la traçabilité de la synchronisation (voir ci-dessous).
Il est tout à fait possible d'enchaîner plusieurs tâches de recopie, pour cela il suffit de déclarer les balises task les unes derrière les autres dans la configuration.

Type de tâche

Fisy est capable de réaliser des copies de fichiers selon 3 méthodes.

Synchronisation SYNCHRONIZE

Synchronisation unidirectionnelle d'un répertoire source vers un répertoire destination. A la fin de l'exécution de cette tâche, la destination devient identique à la source.
Actions : 

  • - Si le fichier ou le répertoire présent dans la destination n'existe pas dans la source alors le supprimer de la destination.
  • - Si le fichier ou le répertoire présent dans la source n'existe pas dans la destination alors créer/copier dans la destination.
  • - Si le fichier présent dans la source est également présent dans la destination alors copier/remplacer si la source est plus récente que la destination (à noter que Fisy ne se préoccupe pas de la date des répertoires dans ce cas).

Copie timestampée TIMESTAMP_COPY

Sauvegarde d'une arborescence de fichiers dans un répertoire timestampé.
Actions : 

  • - Crée un répertoire timestampé dans la destination.
  • - Copie toute la source dans ce répertoire.

Si une contrainte est définie (propriété constaint sur la balise task) alors Fisy compare la date de la dernière sauvegarde et la plage d'exclusion "[date du jour, date du jour - temps de la contrainte]". Si la dernière sauvegarde est dans cette plage cela signifie qu'il est encore trop tôt pour faire une autre sauvegarde et Fisy n'exécute pas la tâche.

Exemple, sauvegarder 1 fois par semaine :  <fisy>
  <task name="MyConstraintTask" type="TIMESTAMP_COPY" constraint="1W" >
...

Si un temps de rétention est défini (propriété retainTime sur la balise task) alors Fisy recherche toutes les sauvegardes plus anciennes que "date du jour - temps de rétention" et les supprime. Cette propriété permet de supprimer les sauvegardes trop anciennes.

Exemple, supprimer les sauvegardes de plus d'un an :  <fisy>
  <task name="MyRetainTask" type="TIMESTAMP_COPY" retainTime="1Y" >
...

Un répertoire timestampé est un répertoire contenant une information d'horodatage. Ici le répertoire est de la forme YYYYmmDD_HHMMSS_<Nom de la tâche>.

Copie complète OVERWRITE_COPY

Sauvegarde complète. Tous les fichiers et répertoires de la source sont recopiés dans le répertoire destination. A la fin de l'exécution de cette tâche, la destination devient identique à la source.
Actions : 

  • - Supprime tout le contenu du répertoire destination.
  • - Fait la copie de la source vers la destination.
Comme vu dans les différentes actions, Fisy est capable de supprimer ou de remplacer un fichier dans le répertoire destination. Si nous résumons : 
SYNCHRONIZE : supprime les fichiers et les répertoires présents dans la destination si non présents dans la source. Remplace les fichiers destinations s'ils sont plus anciens que dans la source.
TIMESTAMP_COPY : supprime les anciennes sauvegardes si la propriété retainTime est définie.
OVERWRITE_COPY : supprime toute la destination avant de réaliser la tâche de copie.

Les logs (la traçabilité)

Les logs permettent de tracer toutes les opérations réalisées par Fisy lors de l'exécution d'une tâche de copie et de sauvegarde.
Il existe 3 niveaux de trace définissant la verbosité des logs DEBUG, INFO et ERROR et sont à renseigner dans la propriété level de la balise log (Nous vous conseillons de positionner les logs sur INFO).
Si un temps de rétention est défini (propriété retainTime sur la balise task) alors Fisy recherche toutes les logs plus anciennes que "date du jour - temps de rétention" et les supprime. Cette propriété permet de supprimer les logs trop anciennes.

Exemple de log :  X#20140926:183319#Start synchronize
I#20140926:183319#Delete 'D:\data\target\dir1\file1.txt'
I#20140926:183319#Copy 'C:\data\source\dir2\file2.txt' to 'D:\data\target\dir2\file2.txt'
I#20140926:183319#Mkdir 'D:\data\target\dir3\'
I#20140926:183319#Copy 'C:\data\source\dir3\file3.txt' to 'D:\data\target\dir3\file3.txt'
X#20140926:183319#End synchronize

RetainTime et Constraint

Retain time et constraint sont des informations temporelles utilisées dans les logs et dans les sauvegardes de type TIMESTAMP_COPY. Elles permettent de ne pas exécuter une tâche si celle-ci est trop récente (propriété constraint) ou de supprimer les éléments si ils sont trop vieux (propriété retainTime dans les balises log et task -- uniquement pour les copies timestampées --).
La syntaxe est la suivante : <quantité><unité>.
Exemples : 

  • 2H = 2 heures.
  • 10W = 10 semaines.
  • 5D = 5 jours.
  • 2M = 2 mois.
  • 1Y = 1 année.

Le chiffrement

Depuis la version 2.0, Fisy est capable de chiffrer (et de déchiffrer) les données à la volée lors de l'exécution d'une tâche de copie. Pour cela l'application utilise l'algorithme de chiffrement AES qu'il applique sur les noms des fichiers, les noms des répertoires et le contenu des fichiers. Ainsi les données deviennent illisibles sans une clé de déchiffrage et peuvent être envoyées dans un service distant tel que le Cloud tout en restant à l'abri des regards indiscrets.
Pour activer le chiffrement, il suffit d'ajouter la balise cipher dans la tâche de recopie et de renseigner la clé (propriété keyFile) ainsi que la direction du chiffrement (propriété direction).

Exemple : 
<?xml version="1.0" encoding="UTF-8"?>
<fisy>
  <task name="MyFirstTask" type="SYNCHRONIZE">
    <src path="c:\data\source" />
    <dest path="d:\data\target" />
    <log path="d:\data\log" level="INFO" />
    <cipher keyFile="c:\my_key.dat" direction="PLAIN_CIPHER" />
  </task>
</fisy>

Avec :

  • direction : direction du chiffrement, PLAIN_CIPHER = chiffrer, CIPHER_PLAIN = déchiffrer.
Chiffrer, déchiffrer VS crypter, décrypter...
En cryptologique il est préférable d'utiliser les termes chiffrer et déchiffrer plutôt que crypter et décrypter qui sont des abus de langages. Crypter est un anglicisme et décrypter représente l'action de retrouver le message en clair sans la clé de chiffrement.

Générer la clé

Pour générer la clé de chiffrement il suffit d'utiliser l'application "Fisy Key Generator" fournie avec Fisy et présent dans le répertoire d'installation.
Son exécution se fait via la ligne de commande suivante :  fisyKeyGen <key size> <key file>

Avec :

  • key size : la taille de la clé. Il existe 3 valeurs possibles 128, 192 et 256 représentants les tailles standard des clés utilisées par AES.
  • key file : nom du fichier contenant la clé.

Par exemple pour créer une clé de 128 bits sauvegardée dans le fichier "my_key.dat", exécuter la ligne de commande : fisyKeyGen 128 my_key.dat

Attention, la version par défaut de Java est capable de générer des clés au-delà de 128 bits mais est incapable de les utiliser pour le chiffrement ! (A cause de lois en vigueur dans certains par pays). Si vous souhaitez travailler avec les clés 192 et 256, il vous faudra retourner sur le site officiel de Java et télécharger l'extension "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files". Cette extension se présente sous la forme d'un patch que vous devrez appliquer à votre JVM (lire le fichier readme.txt).
Ne perdez pas la clé ! Sans cette clé il n'est plus possible de déchiffrer les données et il n'existe pas de recours ou de moyen détourné pour la retrouver.
N'hésitez pas non plus à la dupliquer/copier dans des lieux sûrs et évitez les situations "bêtes" comme une sauvegarde des données d'un disque dans le Cloud et de laisser la clé sur ce disque. Si celui-ci crash les données sont sauvegardées mais la clé est perdue...

Spécification technique du chiffrage

Comme indiqué précédemment, le chiffrement des données se fait via AES avec utilisation au choix de l'une des 3 tailles de clé 128 192 ou 256.
Afin d'améliorer le chiffrement, le mode d'opération "CBC" a été apposé à l'algorithme AES impliquant l'emploi d'un vecteur d'initialisation (IV) lors des opérations de chiffrement/déchiffrement. Techniquement parlant cet IV est une table d'entier de 16 octets qui doit être créée à chaque chiffrement d'un message et qui est utilisée pour complexifier les encryptages de type bloc (tel que AES) -- voir Wikipedia --. Une fois cet IV utilisé celui-ci est transmis avec le message chiffré pour l'opération inverse de déchiffrement, d'ailleurs, contrairement à toute attente, cet IV peut être transmis en clair.
Au niveau de Fisy, ces IV sont insérés en début de fichier dans le cas d'un chiffrement de type "contenu de fichier" et sont convertis en base 64 puis insérés en début de nom de fichier dans le cas d'un chiffrement de type "nom de fichier". Autant pour le premier type ce système s'y prête bien, autant pour le type "nom de fichier" cela peut poser des problèmes car nous sommes limités en taille sur les noms.
Le choix a donc été fait de couper le chiffrement en 2 parties distincts. L'une pour le contenu des fichiers respecte entièrement le standard AES/CBC tandis que l'autre pour le nom des fichiers respecte le standard AES/CBC mais avec un vecteur d'initialisation un peu plus petit que la norme afin de ne pas atteindre la taille maximum. Cette faiblesse est minimisée par le fait qu'il y a peu de données à chiffrer (un nom de fichier est très petit devant un contenu de fichier) et que décrypter un nom de fichier a une porté limité si on ne connaît pas son contenu. De plus c'est toujours mieux qu'un chiffrement sans IV (mode ECB).
A noter que cette séparation a pour conséquence une génération de 2 clés et non d'une seule dans l'application "Fisy Key Generator". Bien entendu ces 2 clés sont générées aléatoirement et n'ont aucun lien ni de dépendance entre elles.

Faire son module de chiffrage

Pour toute personne souhaitant améliorer le chiffrage sous Fisy et maitrisant le langage de programmation Java, il est tout à fait possible de créer son propre module de chiffrement. Le mode opératoire est assez simple, il suffit de prendre les sources de la librairie CpasCipher (fournies avec Fisy) et de redéfinir la classe AESFileFunction qui contient l'implémentation des 2 chiffrements de type "contenu de fichier" et "nom de fichier".
Voici les méthodes à modifier :  public String encryptPath(String path) throws GeneralSecurityException;
public String decryptPath(String path) throws GeneralSecurityException;
public void encryptFile(File fileIn, File fileOut) throws IOException, GeneralSecurityException;
public void decryptFile(File fileIn, File fileOut) throws IOException, GeneralSecurityException;
Une fois le développement terminé, il faudra recompiler les sources de la librairie tout en veillant à mettre dans le classpath ainsi que dans le manifest la librairie commons-codec-1.9.jar.