Windows Phone: proteggere i file presenti sul telefono

Scritto da  Roberto Albano il martedì 27 marzo 2012  •  Linguaggio: C#   • Livello: 200


Quando sviluppiamo una app che deve salvare dei dati sul telefono, questi possono essere salvati nello spazio previsto per l'applicazione, in quello che viene chiamato "Isolated Storage".

Sebbene questi file non siano facilmente accessibili, è sempre cosa buona e giusta salvare questi file in una forma non leggibile, ovvero criptandoli adeguatamente, specialmente quando in questi file vengano salvati dati sensibili come nel caso, ad esempio, delle password.

Per gestire queste situazioni, esiste una classe apposita: System.Security.Cryptography.ProtectedData

Tramite questa classe è possibile criptare e decriptare le informazioni che saranno poi salvate sul telefono con maggiore sicurezza. I metodi che consentono di effettuare queste informazioni si chiamano Protect e Unprotect.

ProtectedData.Protect(byte[] userData, byte[] optionalEntropy)
 
ProtectedData.Unprotect(byte[] encryptedData, byte[] optionalEntropy)

 

L'operazione di criptatura come quella di decriptatura viene eseguita non direttamente su un file ma su un array di byte, consentendo quindi una maggiore versatilità del metodo, non necessariamente per dati diretti appunto verso un file ma, volendo, anche verso un database o quant'altro.

Un parametro opzionale non a caso chiamato optionalEntropy consente di introdurre una complessità aggiuntiva all'operazione, e di conseguenza aumentare ancora il livello di sicurezza.
Ovviamente questo stesso dato deve essere utilizzato nella fase inversa, altrimenti l'operazione di decriptatura non andrebbe a buon fine, generando anche una exception.
L'utilizzo di questo parametro aggiuntivo, di contro, implica un onere aggiuntivo che è proprio quello di salvare a sua volta questa informazione in maniera sicura.
Di sicuro se il dato da proteggere è molto importante potrebbe valerne comunque la pena.

Per spiegare meglio il funzionamento di quanto detto finora, è stata sviluppata una semplice  classe CryptoHelper:

public class CryptoHelper
{
    private CryptoHelper() { }
 
    private IsolatedStorageFile isostore = null;
    public IsolatedStorageFile IsoStore
    {
        get { return isostore ?? (isostore = IsolatedStorageFile.GetUserStoreForApplication()); }
    }
 
    private static CryptoHelper instance = null;
    public static CryptoHelper Instance
    {
        get { return instance ?? (instance = new CryptoHelper()); }
    }
 
    public void CryptContentAndSave(string Content, string Entropy, string FileName)
    {
        byte[] UnprotectedContentAsByteArray = Encoding.UTF8.GetBytes(Content);
        byte[] AdditionalEntropy = (string.IsNullOrEmpty(Entropy) || string.IsNullOrWhiteSpace(Entropy))
                                   ? null
                                   : Encoding.UTF8.GetBytes(Entropy);
        byte[] ProtectedContentAsByteArray = ProtectedData.Protect(UnprotectedContentAsByteArray, AdditionalEntropy);
        if (IsoStore.FileExists(FileName)) IsoStore.DeleteFile(FileName);
        IsolatedStorageFileStream writestream = new IsolatedStorageFileStream(FileName, System.IO.FileMode.Create, FileAccess.Write, IsoStore);
        Stream writer = new StreamWriter(writestream).BaseStream;
        writer.Write(ProtectedContentAsByteArray, 0, ProtectedContentAsByteArray.Length);
        writer.Close();
        writestream.Close();
    }
 
    public string DecryptFileAndGetContent(string FileName, string Entropy)
    {
        string UnprotectedContent = string.Empty;
        if (IsoStore.FileExists(FileName))
        {
            using (IsolatedStorageFileStream Filestream = new IsolatedStorageFileStream(FileName, FileMode.Open, IsoStore))
            {
                Stream reader = new StreamReader(Filestream).BaseStream;
                byte[] ProtectedContentAsByteArray = new byte[reader.Length];
                byte[] AdditionalEntropy = (string.IsNullOrEmpty(Entropy) || string.IsNullOrWhiteSpace(Entropy))
                                           ? null
                                           : Encoding.UTF8.GetBytes(Entropy);
                reader.Read(ProtectedContentAsByteArray, 0, ProtectedContentAsByteArray.Length);
                reader.Close();
                Filestream.Close();
                byte[] UnprotectedContentAsByteArray = ProtectedData.Unprotect(ProtectedContentAsByteArray, AdditionalEntropy);
                UnprotectedContent = Encoding.UTF8.GetString(UnprotectedContentAsByteArray, 0, UnprotectedContentAsByteArray.Length);
            };
        }
        return UnprotectedContent;
    }
}

 


Tags: Windows Phone 7,wp7

 
x