Я хочу защитить открытые и секретные ключи API пользователя в своем приложении UWP - PullRequest
0 голосов
/ 29 июня 2019

Я работаю над приложением UWP, где у пользователей будет запрашиваться их открытый / секретный ключ API для службы, к которой приложение получит доступ.Обычно я бы сохранял настройки в ApplicationData.Current.RoamingSettings, но с помощью ключей API я хотел бы сначала зашифровать их.

Если вы видите ниже, я не уверен, как продолжить сериализацию объекта IBuffer, так как я нажал «Данные этого типа не поддерживаются» , когда я проверяю, как сохранить его.

Большая часть приведенного ниже кода является копировальной пастой от https://docs.microsoft.com/en-us/uwp/api/windows.security.cryptography.dataprotection.dataprotectionprovider.

Я также открыт для других способов сделать это.Спасибо!

public class StaticDataProtection
    {

        private ApplicationDataContainer _roamingSettings = ApplicationData.Current.RoamingSettings;


        public async void SampleProtect()
        {
            // Initialize function arguments.
            String strMsg = "Some API key to be protected.";
            String strDescriptor = "LOCAL=user";
            BinaryStringEncoding encoding = BinaryStringEncoding.Utf8;

            // Protect a message to the local user.
            IBuffer buffProtected = await this.ProtectAsync(
                strMsg,
                strDescriptor,
                encoding);


            // FAILS
            // System.Exception: 'Data of this type is not supported.
            // Error trying to serialize the value to be written to the application data store
            _roamingSettings.Values["apiPublic"] = buffProtected;


            // How to retrieve later?
            IBuffer testRetrievedData = (IBuffer) _roamingSettings.Values["apiPublic"];



            // Decrypt the previously protected message.
            String strDecrypted = await this.UnprotectData(
                testRetrievedData, //originally buffProtected,
                encoding);


        }

        public async Task<IBuffer> ProtectAsync(
            String strMsg,
            String strDescriptor,
            BinaryStringEncoding encoding)
        {
            // Create a DataProtectionProvider object for the specified descriptor.
            DataProtectionProvider Provider = new DataProtectionProvider(strDescriptor);

            // Encode the plaintext input message to a buffer.
            encoding = BinaryStringEncoding.Utf8;
            IBuffer buffMsg = CryptographicBuffer.ConvertStringToBinary(strMsg, encoding);

            // Encrypt the message.
            IBuffer buffProtected = await Provider.ProtectAsync(buffMsg);

            // Execution of the SampleProtectAsync function resumes here
            // after the awaited task (Provider.ProtectAsync) completes.
            return buffProtected;
        }

        public async Task<String> UnprotectData(
            IBuffer buffProtected,
            BinaryStringEncoding encoding)
        {
            // Create a DataProtectionProvider object.
            DataProtectionProvider Provider = new DataProtectionProvider();

            // Decrypt the protected message specified on input.
            IBuffer buffUnprotected = await Provider.UnprotectAsync(buffProtected);

            // Execution of the SampleUnprotectData method resumes here
            // after the awaited task (Provider.UnprotectAsync) completes
            // Convert the unprotected message from an IBuffer object to a string.
            String strClearText = CryptographicBuffer.ConvertBinaryToString(encoding, buffUnprotected);

            // Return the plaintext string.
            return strClearText;
        }
    }

1 Ответ

0 голосов
/ 29 июня 2019

Так что мне нужно было на самом деле преобразовать объект IBuffer в байтовый массив, а затем его можно сериализовать и сохранить в ApplicationData.

// take in the IBuffer object
DataReader reader = DataReader.FromBuffer(buffProtected);

// make sure to use UnconsumedBufferLength to create the byte array instance
byte[] array = new byte[reader.UnconsumedBufferLength];

// read from IBuffer object into the byte array (referenced from the parameter itself)
reader.ReadBytes(array);


// finally store into the app
_roamingSettings.Values["apiPublic"] = array;



To retrieve the data later:

// cast to deserialize
byte[] deserializedArray = (byte[]) _roamingSettings.Values["apiPublic"];

// convert back into an IBuffer object
IBuffer toDecrypt = CryptographicBuffer.CreateFromByteArray(deserializedArray);

// proceed to decrypt.
...