Aller au contenu

Video Encryption SDK — Exemples de code

Vue d'ensemble

Cette page fournit des exemples de code complets et opérationnels pour chiffrer et déchiffrer des fichiers vidéo avec le Video Encryption SDK. Les exemples couvrent :

  • Chiffrement de base — chiffrer des fichiers vidéo avec protection par mot de passe
  • Déchiffrement de fichier — déchiffrer et lire des fichiers vidéo chiffrés
  • Scénarios avancés — clés binaires, clés basées sur fichier, paramètres d'encodage personnalisés
  • Gestion d'erreurs — vérification d'erreurs et récupération robustes

Tous les exemples incluent des implémentations complètes en C++, C# et Delphi.

Nommage de l'interface selon les wrappers de langage

L'en-tête natif C++ (encryptor_intf.h) déclare cette interface sous le nom ICryptoConfig avec IID_ICryptoConfig. Les wrappers C# et Delphi exposent la même interface sous IVFCryptoConfig (et le fournisseur de mot de passe sous IVFPasswordProvider). Les deux noms partagent le GUID {BAA5BD1E-3B30-425e-AB3B-CC20764AC253} et désignent la même interface COM — les extraits C++ ci-dessous utilisent ICryptoConfig tandis que les extraits C#/Delphi utilisent IVFCryptoConfig.


Prérequis

Projets C++

#include <dshow.h>
#include <streams.h>
#include "encryptor_intf.h"
#pragma comment(lib, "strmiids.lib")
#pragma comment(lib, "quartz.lib")

Projets C

using System;
using System.Runtime.InteropServices;
using VisioForge.DirectShowAPI;
using VisioForge.DirectShowLib;
Paquets NuGet requis : - VisioForge.DirectShowAPI - VisioForge.DirectShowLib

Projets Delphi

uses
  DirectShow9,
  EncryptorIntf;

Exemple 1 : chiffrement vidéo de base

Chiffrez un fichier vidéo avec un mot de passe textuel.

Implémentation C

using System;
using System.Runtime.InteropServices;
using VisioForge.DirectShowAPI;
using VisioForge.DirectShowLib;

public class BasicVideoEncryption
{
    private IFilterGraph2 filterGraph;
    private IMediaControl mediaControl;
    private IMediaEventEx mediaEvent;

    public void EncryptVideo(string inputFile, string outputFile, string password)
    {
        try
        {
            // Creer le graphe de filtres
            filterGraph = (IFilterGraph2)new FilterGraph();
            mediaControl = (IMediaControl)filterGraph;
            mediaEvent = (IMediaEventEx)filterGraph;

            // Ajouter le filtre source
            int hr = filterGraph.AddSourceFilter(inputFile, "Source", out IBaseFilter sourceFilter);
            DsError.ThrowExceptionForHR(hr);

            // Ajouter l'encodeur video (H.264)
            var videoEncoder = FilterGraphTools.AddFilterFromClsid(
                filterGraph,
                Consts.CLSID_VFH264Encoder,
                "H.264 Encoder"
            );

            // Ajouter l'encodeur audio (AAC)
            var audioEncoder = FilterGraphTools.AddFilterFromClsid(
                filterGraph,
                Consts.CLSID_VFAACEncoder,
                "AAC Encoder"
            );

            // Ajouter le multiplexeur de chiffrement
            var encryptMuxer = (IBaseFilter)Activator.CreateInstance(
                Type.GetTypeFromCLSID(new Guid("F1D3727A-88DE-49ab-A635-280BEFEFF902"))
            );

            hr = filterGraph.AddFilter(encryptMuxer, "Encrypt Muxer");
            DsError.ThrowExceptionForHR(hr);

            // Configurer le mot de passe de chiffrement
            var cryptoConfig = encryptMuxer as IVFCryptoConfig;
            if (cryptoConfig != null)
            {
                // Appliquer le mot de passe via la methode utilitaire
                cryptoConfig.ApplyString(password);

                // Verifier que le mot de passe est defini
                hr = cryptoConfig.HavePassword();
                if (hr != 0)
                {
                    throw new Exception("Failed to set encryption password");
                }

                Console.WriteLine("Encryption password configured successfully");
            }
            else
            {
                throw new Exception("IVFCryptoConfig interface not available");
            }

            // Definir le fichier de sortie
            var fileSink = encryptMuxer as IFileSinkFilter;
            if (fileSink != null)
            {
                hr = fileSink.SetFileName(outputFile, null);
                DsError.ThrowExceptionForHR(hr);
            }

            // Construire les connexions du graphe de filtres
            ICaptureGraphBuilder2 captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
            hr = captureGraph.SetFiltergraph(filterGraph);
            DsError.ThrowExceptionForHR(hr);

            // Connecter le chemin video : Source -> Encodeur H.264 -> Multiplexeur de chiffrement
            hr = captureGraph.RenderStream(
                null,
                MediaType.Video,
                sourceFilter,
                videoEncoder,
                encryptMuxer
            );
            DsError.ThrowExceptionForHR(hr);

            // Connecter le chemin audio : Source -> Encodeur AAC -> Multiplexeur de chiffrement
            hr = captureGraph.RenderStream(
                null,
                MediaType.Audio,
                sourceFilter,
                audioEncoder,
                encryptMuxer
            );
            DsError.ThrowExceptionForHR(hr);

            Console.WriteLine("Filter graph built successfully");
            Console.WriteLine("Starting encryption...");

            // Demarrer l'encodage
            hr = mediaControl.Run();
            DsError.ThrowExceptionForHR(hr);

            // Attendre la fin
            EventCode eventCode;
            do
            {
                hr = mediaEvent.WaitForCompletion(1000, out eventCode);
            }
            while (eventCode == 0);

            Console.WriteLine("Encryption completed successfully!");

            // Nettoyage
            Marshal.ReleaseComObject(captureGraph);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"ERROR: {ex.Message}");
            throw;
        }
        finally
        {
            Stop();
        }
    }

    public void Stop()
    {
        if (mediaControl != null)
        {
            mediaControl.Stop();
        }

        if (filterGraph != null)
        {
            FilterGraphTools.RemoveAllFilters(filterGraph);
        }

        if (mediaEvent != null) Marshal.ReleaseComObject(mediaEvent);
        if (mediaControl != null) Marshal.ReleaseComObject(mediaControl);
        if (filterGraph != null) Marshal.ReleaseComObject(filterGraph);
    }
}

// Utilisation :
// var encryptor = new BasicVideoEncryption();
// encryptor.EncryptVideo(@"C:\input.mp4", @"C:\output.encrypted.mp4", "MySecurePassword123");

Implémentation C++

#include <dshow.h>
#include <streams.h>
#include "encryptor_intf.h"

class BasicVideoEncryption
{
private:
    IGraphBuilder* pGraph;
    IMediaControl* pControl;
    IMediaEvent* pEvent;

public:
    BasicVideoEncryption() : pGraph(NULL), pControl(NULL), pEvent(NULL) {}

    HRESULT EncryptVideo(LPCWSTR inputFile, LPCWSTR outputFile, LPCWSTR password)
    {
        HRESULT hr;

        // Creer le graphe de filtres
        hr = CoCreateInstance(
            CLSID_FilterGraph,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IGraphBuilder,
            (void**)&pGraph
        );
        if (FAILED(hr)) return hr;

        // Recuperer les interfaces de controle et d'evenements
        pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
        pGraph->QueryInterface(IID_IMediaEvent, (void**)&pEvent);

        // Ajouter le filtre source
        IBaseFilter* pSource = NULL;
        hr = pGraph->AddSourceFilter(inputFile, L"Source", &pSource);
        if (FAILED(hr)) goto cleanup;

        // Ajouter l'encodeur video (H.264)
        IBaseFilter* pVideoEncoder = NULL;
        hr = CoCreateInstance(
            CLSID_VFH264Encoder,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IBaseFilter,
            (void**)&pVideoEncoder
        );
        if (FAILED(hr)) goto cleanup;
        hr = pGraph->AddFilter(pVideoEncoder, L"H.264 Encoder");

        // Ajouter l'encodeur audio (AAC)
        IBaseFilter* pAudioEncoder = NULL;
        hr = CoCreateInstance(
            CLSID_VFAACEncoder,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IBaseFilter,
            (void**)&pAudioEncoder
        );
        if (FAILED(hr)) goto cleanup;
        hr = pGraph->AddFilter(pAudioEncoder, L"AAC Encoder");

        // Ajouter le multiplexeur de chiffrement
        IBaseFilter* pMuxer = NULL;
        hr = CoCreateInstance(
            CLSID_EncryptMuxer,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IBaseFilter,
            (void**)&pMuxer
        );
        if (FAILED(hr)) goto cleanup;
        hr = pGraph->AddFilter(pMuxer, L"Encrypt Muxer");

        // Configurer le chiffrement
        ICryptoConfig* pCrypto = NULL;
        hr = pMuxer->QueryInterface(IID_ICryptoConfig, (void**)&pCrypto);
        if (SUCCEEDED(hr))
        {
            // Definir le mot de passe
            hr = pCrypto->put_Password(
                (LPBYTE)password,
                wcslen(password) * sizeof(wchar_t)
            );

            if (SUCCEEDED(hr))
            {
                // Verifier que le mot de passe est defini
                HRESULT hrPassword = pCrypto->HavePassword();
                if (hrPassword == S_OK)
                {
                    wprintf(L"Encryption password configured successfully\n");
                }
                else
                {
                    wprintf(L"WARNING: Password not set\n");
                }
            }

            pCrypto->Release();
        }

        // Definir le fichier de sortie
        IFileSinkFilter* pFileSink = NULL;
        hr = pMuxer->QueryInterface(IID_IFileSinkFilter, (void**)&pFileSink);
        if (SUCCEEDED(hr))
        {
            hr = pFileSink->SetFileName(outputFile, NULL);
            pFileSink->Release();
        }

        // Construire le graphe via Intelligent Connect
        ICaptureGraphBuilder2* pBuilder = NULL;
        hr = CoCreateInstance(
            CLSID_CaptureGraphBuilder2,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_ICaptureGraphBuilder2,
            (void**)&pBuilder
        );
        if (SUCCEEDED(hr))
        {
            pBuilder->SetFiltergraph(pGraph);

            // Connecter le chemin video
            pBuilder->RenderStream(
                NULL,
                &MEDIATYPE_Video,
                pSource,
                pVideoEncoder,
                pMuxer
            );

            // Connecter le chemin audio
            pBuilder->RenderStream(
                NULL,
                &MEDIATYPE_Audio,
                pSource,
                pAudioEncoder,
                pMuxer
            );

            pBuilder->Release();
        }

        wprintf(L"Starting encryption...\n");

        // Demarrer le graphe
        hr = pControl->Run();
        if (FAILED(hr)) goto cleanup;

        // Attendre la fin
        long evCode;
        pEvent->WaitForCompletion(INFINITE, &evCode);

        wprintf(L"Encryption completed successfully!\n");

cleanup:
        if (pMuxer) pMuxer->Release();
        if (pVideoEncoder) pVideoEncoder->Release();
        if (pAudioEncoder) pAudioEncoder->Release();
        if (pSource) pSource->Release();

        Stop();

        return hr;
    }

    void Stop()
    {
        if (pControl)
        {
            pControl->Stop();
        }

        if (pEvent) pEvent->Release();
        if (pControl) pControl->Release();
        if (pGraph) pGraph->Release();

        pEvent = NULL;
        pControl = NULL;
        pGraph = NULL;
    }
};

// Utilisation :
// BasicVideoEncryption encryptor;
// encryptor.EncryptVideo(L"C:\\input.mp4", L"C:\\output.encrypted.mp4", L"MySecurePassword123");

Implémentation Delphi

uses
  DirectShow9,
  ActiveX,
  EncryptorIntf;

type
  TBasicVideoEncryption = class
  private
    FFilterGraph: IGraphBuilder;
    FMediaControl: IMediaControl;
    FMediaEvent: IMediaEvent;
  public
    function EncryptVideo(const InputFile, OutputFile, Password: WideString): HRESULT;
    procedure Stop;
  end;

function TBasicVideoEncryption.EncryptVideo(const InputFile, OutputFile, Password: WideString): HRESULT;
var
  SourceFilter: IBaseFilter;
  VideoEncoder: IBaseFilter;
  AudioEncoder: IBaseFilter;
  EncryptMuxer: IBaseFilter;
  CryptoConfig: IVFCryptoConfig;
  FileSink: IFileSinkFilter;
  CaptureGraph: ICaptureGraphBuilder2;
  EventCode: Integer;
begin
  Result := E_FAIL;

  try
    // Creer le graphe de filtres
    Result := CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER,
                               IID_IGraphBuilder, FFilterGraph);
    if Failed(Result) then Exit;

    // Recuperer les interfaces de controle et d'evenements
    FFilterGraph.QueryInterface(IID_IMediaControl, FMediaControl);
    FFilterGraph.QueryInterface(IID_IMediaEvent, FMediaEvent);

    // Ajouter le filtre source
    Result := FFilterGraph.AddSourceFilter(PWideChar(InputFile), 'Source', SourceFilter);
    if Failed(Result) then Exit;

    // Ajouter l'encodeur video (H.264)
    Result := CoCreateInstance(CLSID_VFH264Encoder, nil, CLSCTX_INPROC_SERVER,
                               IID_IBaseFilter, VideoEncoder);
    if Succeeded(Result) then
      FFilterGraph.AddFilter(VideoEncoder, 'H.264 Encoder');

    // Ajouter l'encodeur audio (AAC)
    Result := CoCreateInstance(CLSID_VFAACEncoder, nil, CLSCTX_INPROC_SERVER,
                               IID_IBaseFilter, AudioEncoder);
    if Succeeded(Result) then
      FFilterGraph.AddFilter(AudioEncoder, 'AAC Encoder');

    // Ajouter le multiplexeur de chiffrement
    Result := CoCreateInstance(CLSID_EncryptMuxer, nil, CLSCTX_INPROC_SERVER,
                               IID_IBaseFilter, EncryptMuxer);
    if Failed(Result) then Exit;
    FFilterGraph.AddFilter(EncryptMuxer, 'Encrypt Muxer');

    // Configurer le chiffrement
    if Supports(EncryptMuxer, IVFCryptoConfig, CryptoConfig) then
    begin
      // Definir le mot de passe
      // pBuffer est un tampon binaire opaque (PByte) ; on caste via PWideChar pour reutiliser
      // le tampon de chaine large, longueur en octets = nombre de caracteres * 2.
      Result := CryptoConfig.put_Password(PByte(PWideChar(Password)), Length(Password) * 2);

      if Succeeded(Result) then
      begin
        // Verifier que le mot de passe est defini
        if CryptoConfig.HavePassword = S_OK then
          WriteLn('Encryption password configured successfully')
        else
          WriteLn('WARNING: Password not set');
      end;
    end;

    // Definir le fichier de sortie
    if Supports(EncryptMuxer, IFileSinkFilter, FileSink) then
      FileSink.SetFileName(PWideChar(OutputFile), nil);

    // Construire les connexions du graphe
    Result := CoCreateInstance(CLSID_CaptureGraphBuilder2, nil, CLSCTX_INPROC_SERVER,
                               IID_ICaptureGraphBuilder2, CaptureGraph);
    if Succeeded(Result) then
    begin
      CaptureGraph.SetFiltergraph(FFilterGraph);

      // Connecter le chemin video
      CaptureGraph.RenderStream(nil, @MEDIATYPE_Video, SourceFilter,
                                VideoEncoder, EncryptMuxer);

      // Connecter le chemin audio
      CaptureGraph.RenderStream(nil, @MEDIATYPE_Audio, SourceFilter,
                                AudioEncoder, EncryptMuxer);
    end;

    WriteLn('Starting encryption...');

    // Demarrer le graphe
    Result := FMediaControl.Run;
    if Failed(Result) then Exit;

    // Attendre la fin
    repeat
      FMediaEvent.WaitForCompletion(1000, EventCode);
    until EventCode <> 0;

    WriteLn('Encryption completed successfully!');

  finally
    Stop;
  end;
end;

procedure TBasicVideoEncryption.Stop;
begin
  if Assigned(FMediaControl) then
    FMediaControl.Stop;

  FMediaEvent := nil;
  FMediaControl := nil;
  FFilterGraph := nil;
end;

// Utilisation :
// var
//   Encryptor: TBasicVideoEncryption;
// begin
//   Encryptor := TBasicVideoEncryption.Create;
//   try
//     Encryptor.EncryptVideo('C:\input.mp4', 'C:\output.encrypted.mp4', 'MySecurePassword123');
//   finally
//     Encryptor.Free;
//   end;
// end;

Exemple 2 : déchiffrement et lecture vidéo

Déchiffrez un fichier vidéo chiffré et lisez-le.

Implémentation C

public class VideoDecryption
{
    private IFilterGraph2 filterGraph;
    private IMediaControl mediaControl;
    private IMediaEventEx mediaEvent;
    private IVideoWindow videoWindow;
    public void DecryptAndPlay(string encryptedFile, string password, IntPtr windowHandle)
    {
        try
        {
            // Creer le graphe de filtres
            filterGraph = (IFilterGraph2)new FilterGraph();
            mediaControl = (IMediaControl)filterGraph;
            mediaEvent = (IMediaEventEx)filterGraph;
            videoWindow = (IVideoWindow)filterGraph;
            // Ajouter le demultiplexeur de dechiffrement
            var decryptDemuxer = (IBaseFilter)Activator.CreateInstance(
                Type.GetTypeFromCLSID(new Guid("D2C761F0-9988-4f79-9B0E-FB2B79C65851"))
            );
            int hr = filterGraph.AddFilter(decryptDemuxer, "Decrypt Demuxer");
            DsError.ThrowExceptionForHR(hr);
            // Configurer le dechiffrement (DOIT utiliser le meme mot de passe que pour le chiffrement)
            var cryptoConfig = decryptDemuxer as IVFCryptoConfig;
            if (cryptoConfig != null)
            {
                // Appliquer le mot de passe
                cryptoConfig.ApplyString(password);
                // Verifier que le mot de passe est defini
                hr = cryptoConfig.HavePassword();
                if (hr != 0)
                {
                    throw new Exception("Failed to set decryption password");
                }
                Console.WriteLine("Decryption password configured successfully");
            }
            else
            {
                throw new Exception("IVFCryptoConfig interface not available");
            }
            // Charger le fichier chiffre
            var fileSource = decryptDemuxer as IFileSourceFilter;
            if (fileSource != null)
            {
                hr = fileSource.Load(encryptedFile, null);
                DsError.ThrowExceptionForHR(hr);
            }
            // Construire le graphe - rendre les sorties video et audio
            ICaptureGraphBuilder2 captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
            hr = captureGraph.SetFiltergraph(filterGraph);
            DsError.ThrowExceptionForHR(hr);
            // Rendre la sortie video
            hr = captureGraph.RenderStream(
                null,
                MediaType.Video,
                decryptDemuxer,
                null,
                null
            );
            DsError.ThrowExceptionForHR(hr);
            // Rendre la sortie audio
            hr = captureGraph.RenderStream(
                null,
                MediaType.Audio,
                decryptDemuxer,
                null,
                null
            );
            // L'audio est optionnel, ne pas echouer s'il est absent
            // Configurer la fenetre video
            hr = videoWindow.put_Owner(windowHandle);
            hr = videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings);
            hr = videoWindow.put_MessageDrain(windowHandle);
            Console.WriteLine("Starting playback...");
            // Demarrer la lecture
            hr = mediaControl.Run();
            DsError.ThrowExceptionForHR(hr);
            Console.WriteLine("Decryption and playback started successfully!");
            Marshal.ReleaseComObject(captureGraph);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"ERROR: {ex.Message}");
            throw;
        }
    }
    public void Stop()
    {
        if (mediaControl != null)
        {
            mediaControl.Stop();
        }
        if (videoWindow != null)
        {
            videoWindow.put_Visible(OABool.False);
            videoWindow.put_Owner(IntPtr.Zero);
        }
        if (filterGraph != null)
        {
            FilterGraphTools.RemoveAllFilters(filterGraph);
        }
        if (videoWindow != null) Marshal.ReleaseComObject(videoWindow);
        if (mediaEvent != null) Marshal.ReleaseComObject(mediaEvent);
        if (mediaControl != null) Marshal.ReleaseComObject(mediaControl);
        if (filterGraph != null) Marshal.ReleaseComObject(filterGraph);
    }
    public void SetVideoWindowSize(int width, int height)
    {
        if (videoWindow != null)
        {
            videoWindow.SetWindowPosition(0, 0, width, height);
        }
    }
}
// Utilisation :
// var decryptor = new VideoDecryption();
// decryptor.DecryptAndPlay(@"C:\output.encrypted.mp4", "MySecurePassword123", this.Handle);

Exemple 3 : utiliser un fichier comme clé de chiffrement

Utilisez le contenu d'un fichier comme clé de chiffrement au lieu d'un mot de passe.

Implémentation C

public class FileKeyEncryption
{
    public void EncryptWithFileKey(string inputFile, string outputFile, string keyFile)
    {
        var filterGraph = (IFilterGraph2)new FilterGraph();
        var mediaControl = (IMediaControl)filterGraph;

        try
        {
            // Configurer le graphe de filtres (source, encodeurs, multiplexeur)
            // ... (identique a l'exemple 1)

            // Ajouter le multiplexeur de chiffrement
            var encryptMuxer = (IBaseFilter)Activator.CreateInstance(
                Type.GetTypeFromCLSID(new Guid("F1D3727A-88DE-49ab-A635-280BEFEFF902"))
            );
            filterGraph.AddFilter(encryptMuxer, "Encrypt Muxer");

            // Configurer le chiffrement en utilisant le fichier comme cle
            var cryptoConfig = encryptMuxer as IVFCryptoConfig;
            if (cryptoConfig != null)
            {
                // Utiliser le contenu du fichier comme cle de chiffrement (hash SHA-256 du fichier)
                cryptoConfig.ApplyFile(keyFile);

                Console.WriteLine($"Using key file: {keyFile}");
                Console.WriteLine("File content hashed with SHA-256 for encryption");

                // Verifier
                int hr = cryptoConfig.HavePassword();
                if (hr == 0)
                {
                    Console.WriteLine("Encryption key configured successfully");
                }
            }

            // Poursuivre la configuration et l'encodage du graphe de filtres...
        }
        finally
        {
            // Nettoyage
        }
    }

    public void DecryptWithFileKey(string encryptedFile, string keyFile)
    {
        var filterGraph = (IFilterGraph2)new FilterGraph();

        try
        {
            // Ajouter le demultiplexeur de dechiffrement
            var decryptDemuxer = (IBaseFilter)Activator.CreateInstance(
                Type.GetTypeFromCLSID(new Guid("D2C761F0-9988-4f79-9B0E-FB2B79C65851"))
            );
            filterGraph.AddFilter(decryptDemuxer, "Decrypt Demuxer");

            // Configurer le dechiffrement en utilisant le meme fichier de cle
            var cryptoConfig = decryptDemuxer as IVFCryptoConfig;
            if (cryptoConfig != null)
            {
                // DOIT utiliser le meme fichier de cle que pour le chiffrement
                cryptoConfig.ApplyFile(keyFile);

                Console.WriteLine($"Using key file for decryption: {keyFile}");
            }

            // Poursuivre la configuration de la lecture...
        }
        finally
        {
            // Nettoyage
        }
    }
}

// Utilisation :
// var encryptor = new FileKeyEncryption();
// encryptor.EncryptWithFileKey(@"C:\input.mp4", @"C:\output.encrypted.mp4", @"C:\keys\encryption.key");
// encryptor.DecryptWithFileKey(@"C:\output.encrypted.mp4", @"C:\keys\encryption.key");

Exemple 4 : utilisation de données de clé binaires

Générez et utilisez des données de clé binaires pour le chiffrement.

Implémentation C

using System.Security.Cryptography;
using System.IO;
public class BinaryKeyEncryption
{
    public byte[] GenerateRandomKey(int keySize = 32)
    {
        // Generer une cle aleatoire cryptographiquement sure
        byte[] key = new byte[keySize];
        using (var rng = new RNGCryptoServiceProvider())
        {
            rng.GetBytes(key);
        }
        return key;
    }
    public void SaveKeyToFile(byte[] key, string keyFile)
    {
        File.WriteAllBytes(keyFile, key);
        Console.WriteLine($"Key saved to: {keyFile}");
    }
    public byte[] LoadKeyFromFile(string keyFile)
    {
        return File.ReadAllBytes(keyFile);
    }
    public void EncryptWithBinaryKey(string inputFile, string outputFile, byte[] keyData)
    {
        var filterGraph = (IFilterGraph2)new FilterGraph();
        try
        {
            // Configurer le graphe de filtres et ajouter le multiplexeur de chiffrement
            var encryptMuxer = (IBaseFilter)Activator.CreateInstance(
                Type.GetTypeFromCLSID(new Guid("F1D3727A-88DE-49ab-A635-280BEFEFF902"))
            );
            filterGraph.AddFilter(encryptMuxer, "Encrypt Muxer");
            // Configurer le chiffrement avec une cle binaire
            var cryptoConfig = encryptMuxer as IVFCryptoConfig;
            if (cryptoConfig != null)
            {
                // Appliquer la cle binaire (sera hachee en SHA-256)
                cryptoConfig.ApplyBinary(keyData);
                Console.WriteLine($"Binary key applied (length: {keyData.Length} bytes)");
                // Verifier
                int hr = cryptoConfig.HavePassword();
                if (hr == 0)
                {
                    Console.WriteLine("Encryption key configured successfully");
                }
            }
            // Poursuivre l'encodage...
        }
        finally
        {
            // Nettoyage
        }
    }
    public void CompleteWorkflow()
    {
        // Generer une cle de chiffrement aleatoire
        byte[] encryptionKey = GenerateRandomKey(32);
        Console.WriteLine($"Generated {encryptionKey.Length * 8}-bit encryption key");
        // Sauvegarder la cle de maniere securisee
        string keyFile = @"C:\keys\video_encryption_key.bin";
        SaveKeyToFile(encryptionKey, keyFile);
        // Chiffrer la video avec la cle binaire
        EncryptWithBinaryKey(
            @"C:\input.mp4",
            @"C:\output.encrypted.mp4",
            encryptionKey
        );
        Console.WriteLine("Video encrypted successfully!");
        Console.WriteLine($"Key file: {keyFile}");
        Console.WriteLine("Keep this key file secure - it's required for decryption!");
        // Plus tard, pour le dechiffrement :
        // byte[] key = LoadKeyFromFile(keyFile);
        // DecryptWithBinaryKey(@"C:\output.encrypted.mp4", key);
    }
}
// Utilisation :
// var encryptor = new BinaryKeyEncryption();
// encryptor.CompleteWorkflow();

Exemple 5 : chiffrement avec paramètres d'encodage personnalisés

Chiffrez la vidéo avec des paramètres d'encodage H.264 spécifiques.

Implémentation C

public class CustomEncodingEncryption
{
    public void EncryptWithCustomSettings(
        string inputFile,
        string outputFile,
        string password,
        int videoBitrate = 5000000,
        int audioBitrate = 192000)
    {
        var filterGraph = (IFilterGraph2)new FilterGraph();
        var mediaControl = (IMediaControl)filterGraph;

        try
        {
            // Ajouter la source
            filterGraph.AddSourceFilter(inputFile, "Source", out IBaseFilter sourceFilter);

            // Ajouter et configurer l'encodeur H.264
            var videoEncoder = FilterGraphTools.AddFilterFromClsid(
                filterGraph,
                Consts.CLSID_VFH264Encoder,
                "H.264 Encoder"
            );

            // Configurer l'encodeur H.264 (si l'interface est disponible)
            var h264Config = videoEncoder as IH264Encoder;
            if (h264Config != null)
            {
                h264Config.put_Bitrate(videoBitrate);
                h264Config.put_Profile(77); // Profil Main
                h264Config.put_Level(41);   // Niveau 4.1 (1080p)
                h264Config.put_RateControl(1); // CBR
                h264Config.put_GOP(60);     // 2 secondes a 30 fps

                Console.WriteLine($"H.264 configured: {videoBitrate / 1000000.0} Mbps, Main profile, Level 4.1");
            }

            // Ajouter et configurer l'encodeur AAC
            var audioEncoder = FilterGraphTools.AddFilterFromClsid(
                filterGraph,
                Consts.CLSID_VFAACEncoder,
                "AAC Encoder"
            );

            // Configurer l'encodeur AAC (si l'interface est disponible)
            var aacConfig = audioEncoder as IVFAACEncoder;
            if (aacConfig != null)
            {
                aacConfig.SetBitrate((uint)audioBitrate);
                aacConfig.SetProfile(2); // AAC-LC
                aacConfig.SetOutputFormat(0); // AAC brut pour MP4

                Console.WriteLine($"AAC configured: {audioBitrate / 1000} kbps, AAC-LC profile");
            }

            // Ajouter le multiplexeur de chiffrement
            var encryptMuxer = (IBaseFilter)Activator.CreateInstance(
                Type.GetTypeFromCLSID(new Guid("F1D3727A-88DE-49ab-A635-280BEFEFF902"))
            );
            filterGraph.AddFilter(encryptMuxer, "Encrypt Muxer");

            // Configurer le chiffrement
            var cryptoConfig = encryptMuxer as IVFCryptoConfig;
            if (cryptoConfig != null)
            {
                cryptoConfig.ApplyString(password);
                Console.WriteLine("Encryption configured");
            }

            // Definir le fichier de sortie
            var fileSink = encryptMuxer as IFileSinkFilter;
            fileSink?.SetFileName(outputFile, null);

            // Construire les connexions
            ICaptureGraphBuilder2 captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
            captureGraph.SetFiltergraph(filterGraph);

            captureGraph.RenderStream(null, MediaType.Video, sourceFilter, videoEncoder, encryptMuxer);
            captureGraph.RenderStream(null, MediaType.Audio, sourceFilter, audioEncoder, encryptMuxer);

            Console.WriteLine("Starting encoding with custom settings...");

            // Lancer l'encodage
            int hr = mediaControl.Run();
            DsError.ThrowExceptionForHR(hr);

            // Attendre la fin
            var mediaEvent = (IMediaEventEx)filterGraph;
            EventCode eventCode;
            do
            {
                hr = mediaEvent.WaitForCompletion(1000, out eventCode);
            }
            while (eventCode == 0);

            Console.WriteLine("Encoding and encryption completed!");

            Marshal.ReleaseComObject(captureGraph);
        }
        finally
        {
            // Nettoyage
            mediaControl?.Stop();
            FilterGraphTools.RemoveAllFilters(filterGraph);
        }
    }
}

// Utilisation :
// var encryptor = new CustomEncodingEncryption();
// encryptor.EncryptWithCustomSettings(
//     @"C:\input.mp4",
//     @"C:\output.encrypted.mp4",
//     "MySecurePassword123",
//     videoBitrate: 8000000,  // 8 Mbps
//     audioBitrate: 256000    // 256 kbps
// );

Exemple 6 : gestion d'erreurs et validation

Gestion d'erreurs complète pour le chiffrement/déchiffrement.

Implémentation C

Bonnes pratiques

Sécurité des mots de passe

  1. Utiliser des mots de passe forts
  2. Minimum 16 caractères
  3. Mélange de majuscules, minuscules, chiffres, symboles
  4. Éviter les mots du dictionnaire
  5. Utiliser un gestionnaire de mots de passe pour générer/stocker

  6. Stockage des clés

  7. Ne jamais coder les mots de passe en dur dans le code source
  8. Utiliser un stockage sécurisé (Windows DPAPI, KeyVault, etc.)
  9. Mettre en place des contrôles d'accès appropriés

  10. Distribution des clés

  11. Utiliser des canaux sécurisés pour la distribution des clés
  12. Envisager le chiffrement à clé publique pour l'échange de clés
  13. Mettre en place des politiques de rotation des clés

Sécurité de l'implémentation

BON : gestion sécurisée du mot de passe

public void SetEncryptionPassword(IVFCryptoConfig config)
{
    // Recuperer le mot de passe depuis le stockage securise
    string password = SecureStorage.GetPassword();

    try
    {
        config.ApplyString(password);
    }
    finally
    {
        // Effacer le mot de passe de la memoire
        password = null;
        GC.Collect();
    }
}

MAUVAIS : mot de passe codé en dur

public void SetEncryptionPassword(IVFCryptoConfig config)
{
    config.ApplyString("MyPassword123"); // A NE PAS FAIRE !
}

Sécurité des fichiers

  • Utilisez des permissions de fichier appropriées pour les fichiers chiffrés
  • Mettez en place une suppression sécurisée des fichiers temporaires
  • Envisagez de chiffrer les fichiers de clés avec un chiffrement supplémentaire
  • Journalisez les accès au contenu chiffré pour la traçabilité

Lignes directrices d'implémentation

  1. Toujours valider les entrées
  2. Vérifier l'existence du fichier avant traitement
  3. Valider que le mot de passe n'est pas vide
  4. Vérifier la disponibilité des interfaces de filtre

  5. Gestion d'erreurs

  6. Vérifier les valeurs HRESULT des appels COM
  7. Utiliser des blocs try-catch pour les exceptions
  8. Fournir des messages d'erreur significatifs

  9. Gestion des ressources

  10. Toujours libérer les objets COM
  11. Utiliser des blocs finally pour le nettoyage
  12. Arrêter le graphe de filtres avant la libération

  13. Tests

  14. Tester avec divers formats d'entrée
  15. Vérifier que les fichiers chiffrés peuvent être déchiffrés
  16. Tester les conditions d'erreur (mauvais mot de passe, etc.)

Dépannage

Codes d'erreur courants

HRESULT Description Solution
E_INVALIDARG Tampon ou taille invalide Vérifier le pointeur de tampon et les paramètres de taille
E_POINTER Pointeur null S'assurer que les pointeurs sont valides avant l'appel
E_FAIL Échec général Vérifier l'état et la configuration du filtre
S_FALSE Aucun mot de passe défini Appeler put_Password avant HavePassword
### Exemple de gestion d'erreurs
public bool ConfigureEncryption(IBaseFilter muxer, string password)
{
    var cryptoConfig = muxer as IVFCryptoConfig;
    if (cryptoConfig == null)
    {
        Console.WriteLine("ERROR: Filter does not support IVFCryptoConfig");
        return false;
    }
    try
    {
        // Definir le mot de passe
        cryptoConfig.ApplyString(password);
        // Verifier
        int hr = cryptoConfig.HavePassword();
        if (hr != 0)
        {
            Console.WriteLine("ERROR: Password not set correctly");
            return false;
        }
        Console.WriteLine("Encryption configured successfully");
        return true;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"ERROR: Failed to configure encryption: {ex.Message}");
        return false;
    }
}
---

Problèmes courants

Erreur « Filter not registered »

Problème : CLSID introuvable

Solution :

# Enregistrer les filtres (executer en tant qu'administrateur)
regsvr32 "C:\Path\To\EncryptMuxer.ax"
regsvr32 "C:\Path\To\DecryptDemuxer.ax"

Erreur « Interface not available »

Problème : impossible d'interroger IVFCryptoConfig

Solution : - Vérifier que la version du filtre est correcte - Vérifier que le filtre est correctement enregistré - S'assurer que les interfaces COM sont compatibles

Le déchiffrement échoue avec une vidéo brouillée

Problème : mauvais mot de passe utilisé pour le déchiffrement

Solution : - Vérifier que le même mot de passe est utilisé pour le chiffrement et le déchiffrement - Vérifier l'encodage du mot de passe (Unicode vs ANSI) - S'assurer qu'il n'y a pas de fautes de frappe dans le mot de passe

Le fichier de sortie est vide ou corrompu

Problème : l'encodage a échoué silencieusement

Solution : - Vérifier que tous les filtres encodeurs sont correctement connectés - Vérifier la validité des configurations d'encodeur - Surveiller IMediaEventEx pour les événements d'erreur - Vérifier la disponibilité d'espace disque


Voir aussi