我想在我的 UWP 应用程序中保护用户的 API public 和密钥
I want to protect the users' API public and secret keys in my UWP app
我正在开发一个 UWP 应用程序,用户将被要求提供应用程序将访问的服务的 API public/secret 密钥。通常,我会将首选项存储在 ApplicationData.Current.RoamingSettings
中,但是使用 API 密钥,我想先加密它们。
如果您在下面看到,我不确定如何继续序列化 IBuffer 对象,因为我在测试如何存储它时遇到 "Data of this type is not supported"。
下面的大部分代码是从 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;
}
}
所以我要做的就是把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.
我正在开发一个 UWP 应用程序,用户将被要求提供应用程序将访问的服务的 API public/secret 密钥。通常,我会将首选项存储在 ApplicationData.Current.RoamingSettings
中,但是使用 API 密钥,我想先加密它们。
如果您在下面看到,我不确定如何继续序列化 IBuffer 对象,因为我在测试如何存储它时遇到 "Data of this type is not supported"。
下面的大部分代码是从 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;
}
}
所以我要做的就是把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.