The data stored in Windows Storage for Win8 Apps (equivalent of IsolatedStorage for WP8) can be accessed by users directly, even by using Windows Explorer.
The files are stored under C:\Users\<User>\AppData\Local\Packages\<AppName>\LocalState and even if <AppName> is actually a combination of publisher name, app name and another sequence of letters, it is pretty easy to tell which app is which.
If you are going to store data and you want to keep your users from modifying it, you have to make sure you have the right mechanisms in place for doing so.
Luckily, WinRT has some useful libraries for helping you accomplish file signing in Windows.Security.Cryptography namespace.
The classes in this namespace can help you ensure the integrity of a file by creating a digital signature whenever you save it, and by verifying the signature whenever you read the file.
Wikipedia is a good starting point for finding out more about Digital Signatures and RSA.
Here is how you initialize the all the variables needed for signing and signature verification:
var hashAlgorithmName = HashAlgorithmNames.Sha1;
var asymmetricKeyAlgorithmName = AsymmetricAlgorithmNames.RsaPkcs1;
hashAlgorithm = HashAlgorithmProvider.OpenAlgorithm(hashAlgorithmName);
asymmetricKeyAlgorithm = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(asymmetricKeyAlgorithmName);
var privateKeyBuffer = Convert.FromBase64String(privateKeyString).AsBuffer();
privateKey = asymmetricKeyAlgorithm.ImportKeyPair(privateKeyBuffer, CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey);
Here is how you create a signature:
public IBuffer Sign(IBuffer byteArrayBuffer)
{
var hashBuffer = hashAlgorithm.HashData(byteArrayBuffer);
var encryptedBuffer = CryptographicEngine.Encrypt(privateKey, hashBuffer, null);
var hashString = CryptographicBuffer.EncodeToBase64String(hashBuffer);
Debug.WriteLine("This is the hash:" + hashString);
var encryptedHashString = CryptographicBuffer.EncodeToBase64String(encryptedBuffer);
Debug.WriteLine("This is the encrypted hash:" + encryptedHashString);
return encryptedBuffer;
}
Here is how you verify a signature:
public bool VerifySign(IBuffer originalBuffer, IBuffer encodedHashBuffer)
{
var originalHashBuffer = hashAlgorithm.HashData(originalBuffer);
var decriptedHashBuffer = CryptographicEngine.Decrypt(privateKey, encodedHashBuffer, null);
byte[] originalHashArray;
byte[] decriptedHashArray;
CryptographicBuffer.CopyToByteArray(originalHashBuffer, out originalHashArray);
var originalHashString = Convert.ToBase64String(originalHashArray);
Debug.WriteLine("Original hash:" + originalHashString);
CryptographicBuffer.CopyToByteArray(decriptedHashBuffer, out decriptedHashArray);
var decryptedHashString = Convert.ToBase64String(decriptedHashArray);
Debug.WriteLine("Decrypted hash:" + decryptedHashString);
return originalHashString == decryptedHashString;
}
Notes:
- In order to make it work, you need a private key which you can generate using:
var key = asym.CreateKeyPair(512);
- For the sake of simplicity, I keep the private file as a resource inside the app, which is not necessarily a good idea. The only reason I do it in this way is because I want to prevent anyone from easily changing the content of the saved files. However, this approach can easily be improved by storing the private key into a secure location and retrieving it over a secure channel.
Remember! Signing a file won’t keep your users from seeing its content, it will only prevent them from modifying it, or let you know if they they did.
Good luck!
59.332580
18.064900