Usare modelli crittografati con Windows ML

Esistono diversi metodi statici che è possibile applicare alla classe LearningModel per caricare modelli di Machine Learning, ad esempio caricare il modello da un file nell'app, da un file su disco o caricare un modello da un flusso.

Il caricamento da uno stream consente un migliore controllo sul modello. In questo caso, è possibile scegliere di crittografare il modello su disco e decrittografarlo solo in memoria prima di chiamare uno dei metodi LoadFromStream.

Questa esercitazione descrive come integrare un modello di Machine Learning crittografato con l'applicazione Windows ML (C#).

Le API di Windows ML non forniscono il servizio di crittografia di Machine Learning e non saranno responsabili di alcun danno o perdita di alcun tipo.

Ottenere il modello ONNX

In questa esercitazione si userà il modello SqueezeNet in formato ONNX per eseguire la crittografia, la decrittografia e il caricamento dal flusso.

Scaricare o clonare l'app di esempio Di rilevamento oggetti SqueezeNet da GitHub per ottenere il modello SqueezeNet.onnx.

Specificare le dichiarazioni e le variabili necessarie

  1. Copiare le seguenti dichiarazioni using per ottenere l'accesso a tutte le API necessarie:
using System;
using System.Threading.Tasks;
using Windows.AI.MachineLearning;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Controls;

Verranno definite due variabili speciali per una chiave e un vettore di inizializzazione.

La chiave è una variabile della classe CryptographicKey, che rappresenta una coppia di chiavi simmetrica (o asimmetrica). Sarà necessario un oggetto di questa classe perché si userà il AsymmetricKeyAlgorithmProvider metodo per creare o importare chiavi.

Il vettore di inizializzazione è una variabile della classe IBuffer, che rappresenta una matrice di byte utilizzata dalle interfacce di lettura e scrittura del flusso di byte.

Le variabili di CryptographicKey classe e IBuffer vengono usate per crittografare e decrittografare il flusso.

  1. Aggiungere le seguenti dichiarazioni di variabili e la classe MainPage subito dopo le istruzioni 'using' all'interno dello spazio dei nomi crypto.
namespace crypto
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private CryptographicKey _key;
        private IBuffer _initialization_vector;
        public MainPage()
        {
            this.InitializeComponent();

            Run();
        }
    }
}

Crittografare il modello

Le API Windows offrono un set completo di funzionalità e funzionalità, che possono migliorare le funzionalità del set di API di Windows ML. In questo caso si userà un servizio di crittografia e decrittografia fornito nell'API di Windows per produrre un flusso in memoria e si useranno le API di Windows ML per caricare il modello da tale flusso.

È possibile usare qualsiasi servizio di crittografia per crittografare il modello di Machine Learning, in base alla comodità. In questa esercitazione si userà il metodo di crittografia : SymmetricAlgorithmNames - .AesCbcPkcs7.

La classe SymmetricAlgorithmNames consente di recuperare algoritmi di chiave simmetrica per applicare la crittografia della chiave simmetrica nel modello. Questo tipo di crittografia richiede che venga usata anche la stessa chiave usata per la crittografia per la decrittografia.

Usando la SymmetricKeyAlgorithmProvider classe è possibile selezionare un algoritmo e creare la chiave. In questa esercitazione si userà l'algoritmo .AesCbcPkcs7. .

L'algoritmo AES_CBC_PKCS7 rappresenta un algoritmo AES (Advanced Encryption Standard), abbinato a una modalità di operazione a catena di blocchi (cipher-block chaining) e padding PKCS#7.

  1. Il codice seguente illustra come generare la chiave e crittografare il modello.
async Task<IBuffer> EncryptAsync(StorageFile model_file)
{
	// get a buffer for the model file
	var file_buffer = await Windows.Storage.FileIO.ReadBufferAsync(model_file);

	// set up the encryption algorithm
	var algorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
	uint key_length = 32;
	var key_buffer = CryptographicBuffer.GenerateRandom(key_length);
	_key = algorithm.CreateSymmetricKey(key_buffer);
	_initialization_vector = CryptographicBuffer.GenerateRandom(algorithm.BlockLength);

	// perform the encryption
	var encrypted_buffer = CryptographicEngine.Encrypt(_key, file_buffer, _initialization_vector);

	return encrypted_buffer;
}

[NOTA.] Interessato a saperne di più sulle chiavi crittografiche? Consultare la documentazione sulle chiavi crittografiche.

Decrittografare il modello e caricare dal flusso

Prima di caricare il modello, è necessario decrittografarlo usando il metodo CryptographicEngine.Decrypt. CryptographicEngine.Decrypt è un metodo per decrittografare il contenuto crittografato in precedenza usando un algoritmo simmetrico o asimmetrico. Quando si chiama il metodo, è necessario fornire la chiave generata in precedenza.

Per accedere al modello decrittografato, si userà la InMemoryRandomAccessStream classe , che fornisce l'accesso casuale dei dati nei flussi di input e output archiviati in memoria anziché su disco.

Come ultimo passaggio, si creerà una sessione per caricare il modello dal flusso usando il LearningModel.LoadFromStreamAsync metodo . È possibile chiamare questo metodo come attività sincrona o asincrona.

Il codice seguente illustra come decrittografare il modello usando la chiave generata, scriverlo in un flusso e quindi caricare il modello dal flusso.

async Task DecryptAndRunAsync(IBuffer encryptyed_buffer)
{
	// decrypt the buffer
	var decrypted_buffer = CryptographicEngine.Decrypt(_key, encryptyed_buffer, _initialization_vector);

	// write it to a stream
	var decrypted_stream = new InMemoryRandomAccessStream();
	await decrypted_stream.WriteAsync(decrypted_buffer);

	// load the model from the stream
	var model = await LearningModel.LoadFromStreamAsync(RandomAccessStreamReference.CreateFromStream(decrypted_stream));

	// create a session
	var session = new LearningModelSession(model);
}

Eseguire il modello

Copiare il metodo Run seguente per chiamare i metodi definiti in precedenza.

async Task Run()
{

	// get the model file
	var model_file = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/SqueezeNet.onnx"));

	// encrypt the model file.
	var encryptyed_buffer = await EncryptAsync(model_file);

	// decrypt the model file and load it
	await DecryptAndRunAsync(encryptyed_buffer);
}

Riassunto

Ecco fatto! Il modello è stato caricato correttamente nell'app di Windows ML.

Dopo aver caricato il modello, è possibile continuare a creare una sessione, associare input e output del modello e valutare il modello per completare l'app di Windows ML.

Risorse aggiuntive

Per altre informazioni sugli argomenti menzionati in questa esercitazione, visitare le risorse seguenti: