IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQLite Discussion :

SQLCipher + FireDac


Sujet :

SQLite

  1. #1
    Membre confirmé
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    230
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 230
    Par défaut SQLCipher + FireDac
    Bonjour,

    Avec Delphi 12, on développe une application qui utilise des bases SQLite. On souhaite crypter ces bases et on évalue les différentes possibilités.
    J'ai évalué les composants UniDac qui proposent de crypter/décrypter facilement les bases et maintenant je veux évaluer SQLCipher.

    La compilation de SQLCipher étant un peu plus complexe que la compilation de SQLite, j'ai opté pour le téléchargement d'une DLL SqlCipher 32 bits.

    Dans mon projet Delphi, j'ai les composants TFDConnection et TFDPhysSQLiteDriverLink de FireDac que je paramètre pour l'ouverture de ma base _FileName:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
      with FDConnection do
      begin
          // Chemin DLL SQLite spécifique
          var CustomSQLiteDllPath := 'C:\dev\Projet UniDac\sqlite3_cipher_86.dll';
          FDPhysSQLiteDriverLink1.EngineLinkage := slDynamic;
          FDPhysSQLiteDriverLink1.VendorLib:= CustomSQLiteDllPath ;
     
          with Params do
          begin
            Clear ;
            Add('DriverID=Sqlite') ;
            Add('Database='+_FileName);
            Add('EnableBCD=False') ;
            Add('StringFormat=Unicode') ;
            Add('LockingMode=Normal');
            Add('Synchronous=Normal');
            Add('BlobSize=-1');
            Add('CommitRetain=False');
            Add('WaitOnLocks=True');
            Add('Trim Char=False');
          end;
    end;
    Lors de l'exécution j'ai une erreur qui indique un problème de présence de la DLL et/ou un problème d'architecture (x64/x86):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    classe d'exception EFDException avec le message '[FireDAC][Phys][SQLite]-314. Impossible de charger la bibliothèque du fournisseur [C:\dev\Projet UniDac\sqlite3_cipher_86.dll]. Le module spécifié est introuvable
    Conseil : vérifiez qu'il est dans le PATH ou dans les répertoires EXE de l'application et qu'il a un nombre de bits de x86.'.
    --> Je pensais que l'application ne trouvait pas la DLL. Pour test, j'ai supprimé la DLL de mon répertoire et à l'exécution j'ai le message classique qui indique que la DLL n'est pas présente:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Le projet Project1.exe a déclenché la classe d'exception EFOpenError avec le message 'Impossible d'ouvrir le fichier "C:\dev\Projet UniDac\sqlite3_cipher_86.dll". Le fichier spécifié est introuvable'.
    La DLL téléchargée est 32bits.

    Je ne comprends pas cette erreur... Dois-je paramétrer autrement TFDConnection pour que cela fonctionne ?

    Merci pour vos conseils.

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 932
    Billets dans le blog
    66
    Par défaut
    Bonjour,

    Je n'ai jamais utilisé le chiffrement de SQLite mais je sais qu'il y a eu plusieurs note sur ce sujet de la part d'EMB
    déjà j'ai cet exemple "daté" https://docwiki.embarcadero.com/Code...ryption_Sample à voir, l'utilisation de FDSQLiteSecurity pour la bibliothèque citée me semble nécessaire, pas celle de la connexion
    et il me semble qu'il y a une histoire de paramètre à la connection (déjà avec D11 AMHA)

  3. #3
    Membre confirmé
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    230
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 230
    Par défaut
    Bonjour SergioMaster, merci pour tes conseils.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    classe d'exception EFDException avec le message '[FireDAC][Phys][SQLite]-314. Impossible de charger la bibliothèque du fournisseur [C:\dev\Projet UniDac\sqlite3_cipher_86.dll]. Le module spécifié est introuvable
    Conseil : vérifiez qu'il est dans le PATH ou dans les répertoires EXE de l'application et qu'il a un nombre de bits de x86.'.
    Sqlcipher a besoin d'une DLL de cryptage (libcrypto-3.dll) et elle n'tait pas présente. J'ai utilisé l'utilitaire Dependency Walker pour connaître les dépendances de la dll sqlcipher.


    J'ai défini ces quelques types et fonctions issus de la DLL qui me permettront d'appliquer un mot de masse, crypter/décrypter des bases:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    type
      Psqlite3 = Pointer;
     
    function sqlite3_open(filename: PAnsiChar; var db: Psqlite3): Integer; cdecl; external 'sqlcipher.dll';
    function sqlite3_close(db: Psqlite3): Integer; cdecl; external 'sqlcipher.dll';
    function sqlite3_exec(db: Psqlite3; sql: PAnsiChar; callback: Pointer; arg: Pointer; errmsg: PPAnsiChar): Integer; cdecl; external 'sqlcipher.dll';
    function sqlite3_errmsg(db: Psqlite3): PAnsiChar; cdecl; external 'sqlcipher.dll';
    Exemple rapide pour crypter une base:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    var
      DB: Psqlite3;
      SQL: String ;
      Res: Integer;
     
    ...
     
    // Ouvre la base non chiffrée
    Res := sqlite3_open(PAnsiChar(AnsiString(SourceDB)), DB);
     
    // ATTACH la nouvelle base cible avec un mot de passe
    SQL := 'ATTACH DATABASE "' + AnsiString(CibleDB) + '" AS encrypted KEY "' + AnsiString(MotDePasse) + '";';
    Res := sqlite3_exec(DB, PAnsiChar(SQL), nil, nil, @ErrMsg); //Res pour tester/récupérer une erreur
     
    // Effectue la copie des données dans la base chiffrée
    SQL := 'SELECT sqlcipher_export(''encrypted'');';
    Res := sqlite3_exec(DB, PAnsiChar(SQL), nil, nil, @ErrMsg);
     
    // Détache la base cible
    SQL := 'DETACH DATABASE encrypted;';
    Res := sqlite3_exec(DB, PAnsiChar(SQL), nil, nil, @ErrMsg);
     
    sqlite3_close(DB);
    Une fois qu'une base est cryptée par sqlcipher, on peut l'ouvrir avec les composants FireDac (à priori pas besoin de FDSQLiteSecurity) en paramétrant FDConnection pour utiliser la DLL sqlCipher en dynamique et en définissant le mot de passe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
      with FDConnection do
      begin
          // Chemin DLL SQLite spécifique
          var CustomSQLiteDllPath := 'C:\dev\Projet UniDac\sqlcipher.dll';
          FDPhysSQLiteDriverLink1.EngineLinkage := slDynamic;
          FDPhysSQLiteDriverLink1.VendorLib:= CustomSQLiteDllPath ;
     
          with Params do
          begin
            Clear ;
            Add('DriverID=Sqlite') ;
            Add('Database='+_FileName);
            Add('Password=MotDePasse');
            Add('EnableBCD=False') ;
            Add('StringFormat=Unicode') ;
            Add('LockingMode=Normal');
            Add('Synchronous=Normal');
            Add('BlobSize=-1');
            Add('CommitRetain=False');
            Add('WaitOnLocks=True');
            Add('Trim Char=False');
          end;
    end;

Discussions similaires

  1. Mise à jour de Firedac (Update 2)
    Par SergioMaster dans le forum Delphi
    Réponses: 11
    Dernier message: 02/05/2014, 21h37
  2. XE2 FireDac ODBC : message d'erreur
    Par artmicro dans le forum Bases de données
    Réponses: 1
    Dernier message: 23/08/2013, 09h05
  3. XE4 , Firedac et datasnap
    Par SergioMaster dans le forum Bases de données
    Réponses: 8
    Dernier message: 01/06/2013, 09h40
  4. Embarcadero propose FireDAC pour l'accès aux Bdd
    Par John Colibri dans le forum Delphi
    Réponses: 0
    Dernier message: 01/03/2013, 06h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo