DPAPI特别有用,因为它能够消除使用密码的应用程序所带来的密钥管理问题。虽然加密能确保数据安全,但您必须采取额外的步骤来确保密钥的安全。 DPAPI 使用与 DPAPI 函数的调用代码关联的用户帐户的密码,以便派生加密密钥。因此,是操作系统(而非应用程序)管理着密钥。
    DPAPI能够与计算机存储或用户存储(需要一个已加载的用户配置文件)配合使用。DPAPI 默认情况下用于用户存储,但您可以通过将 CRYPTPROTECT_LOCAL_MACHINE 标志传递给 DPAPI 函数来指定使用计算机存储。
    这种用户配置文件方式提供了一个额外的安全层,因为它限制了哪些用户能访问机密内容。只有加密该数据的用户才能解密该数据。但是,当通过 ASP.NET Web 应用程序使用 DPAPI 时,使用用户配置文件需要您执行额外的开发工作,因为您需要采取明确的步骤来加载和卸载用户配置文件(ASP.NET 不会自动加载用户配置文件)。
    计算机存储方式更容易开发,因为它不需要管理用户配置文件。但是,除非使用一个附加的熵参数,否则并不安全,因为该计算机的任何用户都可以解密数据。(熵是一个设计用来使解密机密内容更为困难的随机值)。使用附加的熵参数出现的问题在于它必须由应用程序安全地存储起来,这带来了另一个密钥管理问题。

注意:

    如果您将 DPAPI 和计算机存储一起使用,那么加密字符串仅适用于给定的计算机,因此您必须在每台计算机上生成加密数据。不要在场或群集中将加密数据从一台计算机复制到另一台计算机。
    如果将 DPAPI 和用户存储一起使用,则可以用一个漫游的用户配置文件在任何一台计算机上解密数据。
    DPAPI只在2k以上的系统上才有,win9x系列就不要想了.

下面的演示如何调用DPAPI(DataProtection类,来自于MS的IssueVision)

DPAPI// Uses the Data Protection API (DPAPI) to encrypt and decrypt secrets
DPAPI
// based on the logged in user or local machine. 
DPAPI

DPAPI
using System;
DPAPI
using System.Runtime.InteropServices;
DPAPI
using System.Security;
DPAPI
using System.Text;
DPAPI
DPAPI
DPAPI
namespace ConsoleApplication
{

DPAPI    
/// Class1 的摘要说明。
DPAPI    
/// </summary>
DPAPI    class Class1
{

DPAPI        
/// 应用程序的主入口点。
DPAPI        
/// </summary>
DPAPI        [STAThread]
DPAPI        
static void Main(string[] args)
{
DPAPI            
//
DPAPI            
// TODO: 在此处添加代码以启动应用程序
DPAPI            
//
DPAPI
            string strSource, strEncrypt, strDecrypt;
DPAPI            
DPAPI            Console.WriteLine(
"请输入一个字符串,按回车结束:");
DPAPI            strSource 
= Console.ReadLine();
DPAPI            
DPAPI            Console.WriteLine(
"以下为使用DPAPI加密得到的密码:");
DPAPI            strEncrypt 
= DataProtection.Encrypt(strSource, DataProtection.Store.Machine);
DPAPI            Console.WriteLine(strEncrypt);
DPAPI
DPAPI            Console.WriteLine(
"以下为使用DPAPI解密得到的字符串:");
DPAPI            strDecrypt 
= DataProtection.Decrypt(strEncrypt, DataProtection.Store.Machine);
DPAPI            Console.WriteLine(strDecrypt);
DPAPI
DPAPI            Console.WriteLine(
"按回车结束。。。");
DPAPI            Console.ReadLine();
DPAPI            
DPAPI        }

DPAPI    }

DPAPI
DPAPI
DPAPI    
public sealed class DataProtection 
{
DPAPI        
// use local machine or user to encrypt and decrypt the data
DPAPI
        public enum Store
{
DPAPI            Machine,
DPAPI            User
DPAPI        }

DPAPI
DPAPI        
// const values
DPAPI
        private class Consts 
{
DPAPI            
// specify an entropy so other DPAPI applications can't see the data
DPAPI
            public readonly static byte[] EntropyData = ASCIIEncoding.ASCII.GetBytes("B0D125B7-967E-4f94-9305-A6F9AF56A19A");
DPAPI        }

DPAPI
DPAPI        
// static class
DPAPI
        private DataProtection()
{
DPAPI        }

DPAPI
DPAPI        
// public methods
DPAPI
DPAPI        
// encrypt the data using DPAPI, returns a base64-encoded encrypted string
DPAPI
        public static string Encrypt(string data, Store store)
{
DPAPI            
// holds the result string
DPAPI
            string  result = "";
DPAPI
DPAPI            
// blobs used in the CryptProtectData call
DPAPI
            Win32.DATA_BLOB inBlob = new Win32.DATA_BLOB();
DPAPI            Win32.DATA_BLOB entropyBlob 
= new Win32.DATA_BLOB();
DPAPI            Win32.DATA_BLOB outBlob 
= new Win32.DATA_BLOB();
DPAPI
DPAPI            
try 
{
DPAPI                
// setup flags passed to the CryptProtectData call
DPAPI
                int flags = Win32.CRYPTPROTECT_UI_FORBIDDEN | 
DPAPI                    (
int)((store == Store.Machine) ? Win32.CRYPTPROTECT_LOCAL_MACHINE : 0);
DPAPI
DPAPI                
// setup input blobs, the data to be encrypted and entropy blob
DPAPI
                SetBlobData(ref inBlob, ASCIIEncoding.ASCII.GetBytes(data));
DPAPI                SetBlobData(
ref entropyBlob, Consts.EntropyData);
DPAPI
DPAPI                
// call the DPAPI function, returns true if successful and fills in the outBlob
DPAPI
                if (Win32.CryptProtectData(ref inBlob, ""ref entropyBlob, IntPtr.Zero, IntPtr.Zero, flags, ref outBlob)) 
{
DPAPI                    
byte[] resultBits = GetBlobData(ref outBlob);
DPAPI                    
if (resultBits != null
DPAPI                        result 
= Convert.ToBase64String(resultBits);
DPAPI                }

DPAPI            }

DPAPI            
catch
{
DPAPI                
// an error occurred, return an empty string
DPAPI
            }
DPAPI            
finally 
{
DPAPI                
// clean up
DPAPI
                if (inBlob.pbData.ToInt32() != 0
DPAPI                    Marshal.FreeHGlobal(inBlob.pbData);
DPAPI
DPAPI                
if (entropyBlob.pbData.ToInt32() != 0
DPAPI                    Marshal.FreeHGlobal(entropyBlob.pbData);
DPAPI            }

DPAPI
DPAPI            
return result;
DPAPI        }

DPAPI
DPAPI        
// decrypt the data using DPAPI, data is a base64-encoded encrypted string
DPAPI
        public static string Decrypt( string  data,  Store store) 
{
DPAPI            
// holds the result string
DPAPI
            string result = "";
DPAPI
DPAPI            
// blobs used in the CryptUnprotectData call
DPAPI
            Win32.DATA_BLOB inBlob = new Win32.DATA_BLOB();
DPAPI            Win32.DATA_BLOB entropyBlob 
= new Win32.DATA_BLOB();
DPAPI            Win32.DATA_BLOB outBlob 
= new Win32.DATA_BLOB();
DPAPI
DPAPI            
try 
{
DPAPI                
// setup flags passed to the CryptUnprotectData call
DPAPI
                int flags = Win32.CRYPTPROTECT_UI_FORBIDDEN |
DPAPI                    (
int)((store == Store.Machine) ? Win32.CRYPTPROTECT_LOCAL_MACHINE : 0);
DPAPI
DPAPI                
// the CryptUnprotectData works with a byte array, convert string data
DPAPI
                byte[] bits = Convert.FromBase64String(data);
DPAPI
DPAPI                
// setup input blobs, the data to be decrypted and entropy blob
DPAPI
                SetBlobData(ref inBlob, bits);
DPAPI                SetBlobData(
ref entropyBlob, Consts.EntropyData);
DPAPI
DPAPI                
// call the DPAPI function, returns true if successful and fills in the outBlob
DPAPI
                if (Win32.CryptUnprotectData(ref inBlob, nullref entropyBlob, IntPtr.Zero, IntPtr.Zero, flags, ref outBlob)) 
{
DPAPI                    
byte[] resultBits = GetBlobData(ref outBlob);
DPAPI                    
if (resultBits != null
DPAPI                        result 
= ASCIIEncoding.ASCII.GetString(resultBits);
DPAPI                }

DPAPI            }

DPAPI            
catch 
{
DPAPI                
// an error occurred, return an empty string
DPAPI
            }
DPAPI            
finally 
{
DPAPI                
// clean up
DPAPI
                if (inBlob.pbData.ToInt32() != 0
DPAPI                    Marshal.FreeHGlobal(inBlob.pbData);
DPAPI        
DPAPI                
if (entropyBlob.pbData.ToInt32() != 0
DPAPI                    Marshal.FreeHGlobal(entropyBlob.pbData);
DPAPI            }

DPAPI
DPAPI            
return result;
DPAPI        }

DPAPI
DPAPI
DPAPI        
// internal methods
DPAPI


DPAPI
DPAPI        
private class Win32 
{
DPAPI            
public const int CRYPTPROTECT_UI_FORBIDDEN = 0x1;
DPAPI            
public const int CRYPTPROTECT_LOCAL_MACHINE = 0x4;
DPAPI
DPAPI            [StructLayout(LayoutKind.Sequential)]
DPAPI                
public struct DATA_BLOB
{
DPAPI                
public int cbData;
DPAPI                
public IntPtr pbData;
DPAPI            }

DPAPI
DPAPI            [DllImport(
"crypt32", CharSet=CharSet.Auto)]
DPAPI            
public static extern bool CryptProtectData(ref DATA_BLOB pDataIn, string szDataDescr, ref DATA_BLOB pOptionalEntropy, IntPtr pvReserved, IntPtr pPromptStruct, int dwFlags, ref DATA_BLOB pDataOut);
DPAPI
DPAPI            [DllImport(
"crypt32", CharSet=CharSet.Auto)]
DPAPI            
public static extern bool CryptUnprotectData(ref DATA_BLOB pDataIn, StringBuilder szDataDescr, ref DATA_BLOB pOptionalEntropy, IntPtr pvReserved, IntPtr pPromptStruct, int dwFlags, ref DATA_BLOB pDataOut);
DPAPI
DPAPI            [DllImport(
"kernel32")] 
DPAPI            
public static extern IntPtr LocalFree(IntPtr hMem);
DPAPI        }

DPAPI
DPAPI        
#endregion
DPAPI
DPAPI        
// helper method that fills in a DATA_BLOB, copies 
DPAPI        
// data from managed to unmanaged memory
DPAPI
        private static void SetBlobData(ref Win32.DATA_BLOB blob,  byte[] bits) 
{
DPAPI            blob.cbData 
= bits.Length;
DPAPI            blob.pbData 
= Marshal.AllocHGlobal(bits.Length);
DPAPI            Marshal.Copy(bits, 
0, blob.pbData, bits.Length);
DPAPI        }

DPAPI
DPAPI        
// helper method that gets data from a DATA_BLOB, 
DPAPI        
// copies data from unmanaged memory to managed
DPAPI
        private static byte[] GetBlobData(ref Win32.DATA_BLOB blob) 
{
DPAPI            
// return an empty string if the blob is empty
DPAPI
            if (blob.pbData.ToInt32() == 0
DPAPI                
return null;
DPAPI
DPAPI            
// copy information from the blob
DPAPI
            byte[] data = new byte[blob.cbData];
DPAPI            Marshal.Copy(blob.pbData, data, 
0, blob.cbData);
DPAPI            Win32.LocalFree(blob.pbData);
DPAPI
DPAPI            
return data;
DPAPI        }

DPAPI    }

DPAPI
DPAPI
DPAPI}


DPAPI

相关文章:

  • 2022-12-23
  • 2021-08-22
  • 2021-04-30
  • 2021-08-26
  • 2021-07-28
  • 2022-12-23
  • 2021-10-29
  • 2022-12-23
猜你喜欢
  • 2022-01-11
  • 2021-08-26
  • 2021-05-21
  • 2021-05-16
  • 2022-12-23
  • 2021-07-20
  • 2022-01-15
相关资源
相似解决方案