分享

如何:使用数据保护

 寒江雪书院 2017-05-03

.NET Framework 提供对数据保护 API (DPAPI) 的访问,这允许你使用来自当前用户帐户或计算机的信息对数据进行加密。 当使用 DPAPI 时,你会使显式生成和存储加密密钥的困难问题得到缓解。

使用 ProtectedMemory 类加密内存中的字节数组。 此功能在 Microsoft Windows XP 和更高版本操作系统中可用。 你可以指定由当前进程加密的内存只能由当前进程、由所有进程、或从相同的用户上下文解密。 请参阅 MemoryProtectionScope 枚举以获取 ProtectedMemory 选项的详细说明。

使用 ProtectedData 类来加密字节数组的副本。 此功能在 Microsoft Windows 2000 和更高版本操作系统中可用。 你可以指定由当前用户帐户加密的数据仅能通过相同的用户帐户解密,也可以指定由当前用户帐户加密的数据可以通过计算机上的任何帐户进行解密。 请参阅 DataProtectionScope 枚举以获取 ProtectedData 选项的详细说明。

若要使用数据保护对内存中数据进行加密

  1. 调用静态 Protect 方法,同时传递要加密的字节数组、平均信息量和内存保护范围。

若要使用数据保护对内存中数据进行解密

  1. 调用静态 Unprotect 方法,同时传递要解密的字节数组和内存保护范围。

若要使用数据保护将数据加密到文件或流

  1. 创建随机平均信息量。

  2. 调用静态 Protect 方法,同时传递要加密的字节数组、平均信息量和数据保护范围。

  3. 将加密的数据写入文件或流。

若要使用数据保护从文件或流解密数据

  1. 从文件或流中读取加密的数据。

  2. 调用静态 Unprotect 方法,同时传递要解密的字节数组和数据保护范围。

示例

下面的代码示例演示加密和解密的两种形式。 首先,该代码示例对内存中的字节数组进行加密,然后将其解密。 接下来,该代码示例对字节数组的副本进行加密、将其保存到文件、从文件加载回数据,然后对数据进行解密。 此示例显示原始数据、加密的数据和已解密的数据。

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

public class MemoryProtectionSample
{
    public static void Main()
    {
        Run();
    }

    public static void Run()
    {
        try
        {

            ///////////////////////////////
            //
            // Memory Encryption - ProtectedMemory
            //
            ///////////////////////////////

            // Create the original data to be encrypted (The data length should be a multiple of 16).
            byte[] toEncrypt = UnicodeEncoding.ASCII.GetBytes("ThisIsSomeData16");

            Console.WriteLine("Original data: " + UnicodeEncoding.ASCII.GetString(toEncrypt));
            Console.WriteLine("Encrypting...");

            // Encrypt the data in memory.
            EncryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon);

            Console.WriteLine("Encrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt));
            Console.WriteLine("Decrypting...");

            // Decrypt the data in memory.
            DecryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon);

            Console.WriteLine("Decrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt));


            ///////////////////////////////
            //
            // Data Encryption - ProtectedData
            //
            ///////////////////////////////

            // Create the original data to be encrypted
            toEncrypt = UnicodeEncoding.ASCII.GetBytes("This is some data of any length.");

            // Create a file.
            FileStream fStream = new FileStream("Data.dat", FileMode.OpenOrCreate);

            // Create some random entropy.
            byte[] entropy = CreateRandomEntropy();

            Console.WriteLine();
            Console.WriteLine("Original data: " + UnicodeEncoding.ASCII.GetString(toEncrypt));
            Console.WriteLine("Encrypting and writing to disk...");

            // Encrypt a copy of the data to the stream.
            int bytesWritten = EncryptDataToStream(toEncrypt, entropy, DataProtectionScope.CurrentUser, fStream);

            fStream.Close();

            Console.WriteLine("Reading data from disk and decrypting...");

            // Open the file.
            fStream = new FileStream("Data.dat", FileMode.Open);

            // Read from the stream and decrypt the data.
            byte[] decryptData = DecryptDataFromStream(entropy, DataProtectionScope.CurrentUser, fStream, bytesWritten);

            fStream.Close();

            Console.WriteLine("Decrypted data: " + UnicodeEncoding.ASCII.GetString(decryptData));


        }
        catch (Exception e)
        {
            Console.WriteLine("ERROR: " + e.Message);
        }

    }


    public static void EncryptInMemoryData(byte[] Buffer, MemoryProtectionScope Scope )
    {
        if (Buffer.Length <= 0)
            throw new ArgumentException("Buffer");
        if (Buffer == null)
            throw new ArgumentNullException("Buffer");


        // Encrypt the data in memory. The result is stored in the same same array as the original data.
        ProtectedMemory.Protect(Buffer, Scope);

    }

    public static void DecryptInMemoryData(byte[] Buffer, MemoryProtectionScope Scope)
    {
        if (Buffer.Length <= 0)
            throw new ArgumentException("Buffer");
        if (Buffer == null)
            throw new ArgumentNullException("Buffer");


        // Decrypt the data in memory. The result is stored in the same same array as the original data.
        ProtectedMemory.Unprotect(Buffer, Scope);

    }

    public static byte[] CreateRandomEntropy()
    {
        // Create a byte array to hold the random value.
        byte[] entropy = new byte[16];

        // Create a new instance of the RNGCryptoServiceProvider.
        // Fill the array with a random value.
        new RNGCryptoServiceProvider().GetBytes(entropy);

        // Return the array.
        return entropy;


    }

    public static int EncryptDataToStream(byte[] Buffer, byte[] Entropy, DataProtectionScope Scope, Stream S)
    {
        if (Buffer.Length <= 0)
            throw new ArgumentException("Buffer");
        if (Buffer == null)
            throw new ArgumentNullException("Buffer");
        if (Entropy.Length <= 0)
            throw new ArgumentException("Entropy");
        if (Entropy == null)
            throw new ArgumentNullException("Entropy");
        if (S == null)
            throw new ArgumentNullException("S");

        int length = 0;

        // Encrypt the data in memory. The result is stored in the same same array as the original data.
        byte[] encrptedData = ProtectedData.Protect(Buffer, Entropy, Scope);

        // Write the encrypted data to a stream.
        if (S.CanWrite && encrptedData != null)
        {
            S.Write(encrptedData, 0, encrptedData.Length);

            length = encrptedData.Length;
        }

        // Return the length that was written to the stream. 
        return length;

    }

    public static byte[] DecryptDataFromStream(byte[] Entropy, DataProtectionScope Scope, Stream S, int Length)
    {
        if (S == null)
            throw new ArgumentNullException("S");
        if (Length <= 0 )
            throw new ArgumentException("Length");
        if (Entropy == null)
            throw new ArgumentNullException("Entropy");
        if (Entropy.Length <= 0)
            throw new ArgumentException("Entropy");



        byte[] inBuffer = new byte[Length];
        byte[] outBuffer;

        // Read the encrypted data from a stream.
        if (S.CanRead)
        {
            S.Read(inBuffer, 0, Length);

            outBuffer = ProtectedData.Unprotect(inBuffer, Entropy, Scope);
        }
        else
        {
            throw new IOException("Could not read the stream.");
        }

        // Return the length that was written to the stream. 
        return outBuffer;

    }


}

编译代码

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多