• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

如何创建一个DPAPI库Code(VB.NET&C#)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

 

C#  Code

using System;

using System.Text;
using System.Runtime.InteropServices;


namespace DataProtection
{
    
/// <summary>
    
/// Summary description for DataProtector.
    
/// </summary>
    public class DataProtector
    {
    
        [DllImport(
"Crypt32.dll", SetLastError=true,CharSet=System.Runtime.InteropServices.CharSet.Auto)] 
        
private static extern bool CryptProtectData(ref DATA_BLOB pDataIn, 
            String szDataDescr, 
            
ref DATA_BLOB pOptionalEntropy,
            IntPtr pvReserved, 
            
ref CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, 
            
int dwFlags, 
            
ref DATA_BLOB pDataOut);

        [DllImport(
"Crypt32.dll", SetLastError=true
             CharSet
=System.Runtime.InteropServices.CharSet.Auto)]
        
private static extern bool CryptUnprotectData(ref DATA_BLOB pDataIn, 
            String szDataDescr, 
            
ref DATA_BLOB pOptionalEntropy, 
            IntPtr pvReserved, 
            
ref CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, 
            
int dwFlags, 
            
ref DATA_BLOB pDataOut);
        [DllImport(
"kernel32.dll"
             CharSet
=System.Runtime.InteropServices.CharSet.Auto)]
        
private unsafe static extern int FormatMessage(int dwFlags, 
            
ref IntPtr lpSource, 
            
int dwMessageId,
            
int dwLanguageId, 
            
ref String lpBuffer, int nSize, 
            IntPtr 
*Arguments);

        [StructLayout(LayoutKind.Sequential, CharSet
=CharSet.Unicode)]
            
internal struct DATA_BLOB
        {
            
public int cbData;
            
public IntPtr pbData;
        }

        [StructLayout(LayoutKind.Sequential, CharSet
=CharSet.Unicode)]
            
internal struct CRYPTPROTECT_PROMPTSTRUCT
        {
            
public int cbSize;
            
public int dwPromptFlags;
            
public IntPtr hwndApp;
            
public String szPrompt;
        }
        
static private IntPtr NullPtr = ((IntPtr)((int)(0)));
        
private const int CRYPTPROTECT_UI_FORBIDDEN = 0x1;
        
private const int CRYPTPROTECT_LOCAL_MACHINE = 0x4;


        
public enum Store {USE_MACHINE_STORE = 1, USE_USER_STORE};


        
private Store store;

        
public DataProtector(Store tempStore)
        {
            store 
= tempStore;
        }

        
public byte[] Encrypt(byte[] plainText, byte[] optionalEntropy)
        {
            
bool retVal = false;

            DATA_BLOB plainTextBlob 
= new DATA_BLOB();
            DATA_BLOB cipherTextBlob 
= new DATA_BLOB();
            DATA_BLOB entropyBlob 
= new DATA_BLOB();

            CRYPTPROTECT_PROMPTSTRUCT prompt 
= new CRYPTPROTECT_PROMPTSTRUCT();
            InitPromptstruct(
ref prompt);

            
int dwFlags;
            
try
            {
                
try
                {
                    
int bytesSize = plainText.Length;
                    plainTextBlob.pbData 
= Marshal.AllocHGlobal(bytesSize);
                    
if(IntPtr.Zero == plainTextBlob.pbData)
                    {
                        
throw new Exception("Unable to allocate plaintext buffer.");
                    }
                    plainTextBlob.cbData 
= bytesSize;
                    Marshal.Copy(plainText, 
0, plainTextBlob.pbData, bytesSize);
                }
                
catch(Exception ex)
                {
                    
throw new Exception("Exception marshalling data. " + ex.Message);
                }
                
if(Store.USE_MACHINE_STORE == store)
                {
//Using the machine store, should be providing entropy.
                    dwFlags = CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDDEN;
                    
//Check to see if the entropy is null
                    if(null == optionalEntropy)
                    {
//Allocate something
                        optionalEntropy = new byte[0];
                    }
                    
try
                    {
                        
int bytesSize = optionalEntropy.Length;
                        entropyBlob.pbData 
= Marshal.AllocHGlobal(optionalEntropy.Length);;
                        
if(IntPtr.Zero == entropyBlob.pbData)
                        {
                            
throw new Exception("Unable to allocate entropy data buffer.");
                        }
                        Marshal.Copy(optionalEntropy, 
0, entropyBlob.pbData, bytesSize);
                        entropyBlob.cbData 
= bytesSize;
                    }
                    
catch(Exception ex)
                    {
                        
throw new Exception("Exception entropy marshalling data. " + 
                            ex.Message);
                    }
                }
                
else
                {
//Using the user store
                    dwFlags = CRYPTPROTECT_UI_FORBIDDEN;
                }
                retVal 
= CryptProtectData(ref plainTextBlob, ""ref entropyBlob, 
                    IntPtr.Zero, 
ref prompt, dwFlags, 
                    
ref cipherTextBlob);
                
if(false == retVal)
                {
                    
throw new Exception("Encryption failed. " + 
                        GetErrorMessage(Marshal.GetLastWin32Error()));
                }
            }
            
catch(Exception ex)
            {
                
throw new Exception("Exception encrypting. " + ex.Message);
            }
            
byte[] cipherText = new byte[cipherTextBlob.cbData];
            Marshal.Copy(cipherTextBlob.pbData, cipherText, 
0, cipherTextBlob.cbData);
            
return cipherText;
        }

        
public byte[] Decrypt(byte[] cipherText, byte[] optionalEntropy)
        {
            
bool retVal = false;
            DATA_BLOB plainTextBlob 
= new DATA_BLOB();
            DATA_BLOB cipherBlob 
= new DATA_BLOB();
            CRYPTPROTECT_PROMPTSTRUCT prompt 
= new CRYPTPROTECT_PROMPTSTRUCT();
            InitPromptstruct(
ref prompt);
            
try
            {
                
try
                {
                    
int cipherTextSize = cipherText.Length;
                    cipherBlob.pbData 
= Marshal.AllocHGlobal(cipherTextSize);
                    
if(IntPtr.Zero == cipherBlob.pbData)
                    {
                        
throw new Exception("Unable to allocate cipherText buffer.");
                    }
                    cipherBlob.cbData 
= cipherTextSize;  
                    Marshal.Copy(cipherText, 
0, cipherBlob.pbData, cipherBlob.cbData);
                }
                
catch(Exception ex)
                {
                    
throw new Exception("Exception marshalling data. " + ex.Message);
                }
                DATA_BLOB entropyBlob 
= new DATA_BLOB();
                
int dwFlags;
                
if(Store.USE_MACHINE_STORE == store)
                {
//Using the machine store, should be providing entropy.
                    dwFlags = CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDDEN;
                    
//Check to see if the entropy is null
                    if(null == optionalEntropy)
                    {
//Allocate something
                        optionalEntropy = new byte[0];
                    }
                    
try
                    {
                        
int bytesSize = optionalEntropy.Length;
                        entropyBlob.pbData 
= Marshal.AllocHGlobal(bytesSize);
                        
if(IntPtr.Zero == entropyBlob.pbData)
                        {
                            
throw new Exception("Unable to allocate entropy buffer.");
                        }
                        entropyBlob.cbData 
= bytesSize;
                        Marshal.Copy(optionalEntropy, 
0, entropyBlob.pbData, bytesSize);
                    }
                    
catch(Exception ex)
                    {
                        
throw new Exception("Exception entropy marshalling data. " + 
                            ex.Message);
                    }
                }
                
else
                {
//Using the user store
                    dwFlags = CRYPTPROTECT_UI_FORBIDDEN;
                }
                retVal 
= CryptUnprotectData(ref cipherBlob, nullref entropyBlob, 
                    IntPtr.Zero, 
ref prompt, dwFlags, 
                    
ref plainTextBlob);
                
if(false == retVal)
                {
                    
throw new Exception("Decryption failed. " + 
                        GetErrorMessage(Marshal.GetLastWin32Error()));
                }
                
//Free the blob and entropy.
                if(IntPtr.Zero != cipherBlob.pbData)
                {
                    Marshal.FreeHGlobal(cipherBlob.pbData);
                }
                
if(IntPtr.Zero != entropyBlob.pbData)
                {
                    Marshal.FreeHGlobal(entropyBlob.pbData);
                }
            }
            
catch(Exception ex)
            {
                
throw new Exception("Exception decrypting. " + ex.Message);
            }
            
byte[] plainText = new byte[plainTextBlob.cbData];
            Marshal.Copy(plainTextBlob.pbData, plainText, 
0, plainTextBlob.cbData);
            
return plainText;
        }


        
private void InitPromptstruct(ref CRYPTPROTECT_PROMPTSTRUCT ps) 
        {
            ps.cbSize 
= Marshal.SizeOf(typeof(CRYPTPROTECT_PROMPTSTRUCT));
            ps.dwPromptFlags 
= 0;
            ps.hwndApp 
= NullPtr;
            ps.szPrompt 
= null;
        }

        
private unsafe static String GetErrorMessage(int errorCode)
        {
            
int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
            
int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
            
int FORMAT_MESSAGE_FROM_SYSTEM  = 0x00001000;
            
int messageSize = 255;
            String lpMsgBuf 
= "";
            
int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | 
                FORMAT_MESSAGE_IGNORE_INSERTS;
            IntPtr ptrlpSource 
= new IntPtr();
            IntPtr prtArguments 
= new IntPtr();
            
int retVal = FormatMessage(dwFlags, ref ptrlpSource, errorCode, 0
                
ref lpMsgBuf, messageSize, &prtArguments);
            
if(0 == retVal)
            {
                
throw new Exception("Failed to format message for error code " + 
                    errorCode 
+ "");
            }
            
return lpMsgBuf;
        }


    }
}

 VB.NET Code

Imports System
Imports System.Text
Imports System.Runtime.InteropServices

Namespace DataProtectionVB

    
Public Enum Store
        MachineStore 
= 1
        UserStore
    
End Enum

#Region " Custom Exception"
    
Public Class DataProtectionException
        
Inherits Exception

        
Public Sub New()
            
MyBase.New()
        
End Sub

        
Public Sub New(ByVal message As String)
            
MyBase.New(message)
        
End Sub

        
Public Sub New(ByVal message As StringByVal innerException As Exception)
            
MyBase.New(message, innerException)
        
End Sub

    
End Class
#End Region

    
Public Class DataProtector

#Region " Dll Imports"

        
Private Declare Auto Function CryptProtectData Lib "Crypt32.dll" ( _
            
ByRef pDataIn As DATA_BLOB, _
            
ByVal szDataDescr As String, _
            
ByRef pOptionalEntropy As DATA_BLOB, _
            
ByVal pvReserved As IntPtr, _
            
ByRef pPromptStruct As CRYPTPROTECT_PROMPTSTRUCT, _
            
ByVal dwFlags As Integer, _
            
ByRef pDataOut As DATA_BLOB) As Boolean

        
Private Declare Auto Function CryptUnprotectData Lib "Crypt32.dll" ( _
            
ByRef pDataIn As DATA_BLOB, _
            
ByVal szDataDescr As String, _
            
ByRef pOptionalEntropy As DATA_BLOB, _
            
ByVal pvReserved As IntPtr, _
            
ByRef pPromptStruct As CRYPTPROTECT_PROMPTSTRUCT, _
            
ByVal dwFlags As Integer, _
            
ByRef pDataOut As DATA_BLOB) As Boolean

        
Private Declare Auto Function FormatMessage Lib "kernel32.dll" ( _
            
ByVal dwFlags As Integer, _
            
ByRef lpSource As IntPtr, _
            
ByVal dwMessageId As Integer, _
            
ByVal dwLanguageId As Integer, _
            
ByRef lpBuffer As String, _
            
ByVal nSize As Integer, _
            
ByVal Arguments As IntPtr) As Integer

#End Region

#Region " Structure definistions and constraints "
        
Friend Structure DATA_BLOB
            
Public cbData As Integer
            
Public pbData As IntPtr
        
End Structure

        
Friend Structure CRYPTPROTECT_PROMPTSTRUCT
            
Public cbSize As Integer
            
Public dwPromptFlags As Integer
            
Public hwndApp As IntPtr
            
Public szPrompt As String
        
End Structure

        
Private Const CRYPTOPROTECT_UI_FORBIDDEN = &H1
  

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
[CLR via C#]1.2 将托管模块合并成程序集发布时间:2022-07-10
下一篇:
C#16进制与字符串、字节数组之间的转换发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap