Program,Life,Society.....

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 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
        
Private Const CRYPTPROTECT_LOCAL_MACHINE = &H4
#End Region

#Region " Constructors "
        
Private _store As Store

        
Public Sub New(ByVal store As Store)
            _store 
= store
        
End Sub
#End Region

#Region " Encrypt and Decrypt "
        
Public Function Encrypt(ByVal plainText As Byte()) As Byte()
            
Dim entropy(0As Byte
            
Return Encrypt(plainText, entropy)
        
End Function

        
Public Function Encrypt(ByVal plainText As Byte(), _
                    
ByVal entropyText As Byte()) As Byte()

            
Dim retVal As Boolean = False

            
Dim plainTextBlob As New DATA_BLOB
            
Dim cipherTextBlob As New DATA_BLOB
            
Dim entropyBlob As New DATA_BLOB

            
Dim prompt As New CRYPTPROTECT_PROMPTSTRUCT

            InitProptstruct(prompt)

            
Dim dwFlags As Integer
            
Try
                
Try
                    
Dim bytesSize As Integer = plainText.Length
                    plainTextBlob.pbData 
= Marshal.AllocHGlobal(bytesSize)
                    
If plainTextBlob.pbData.Equals(IntPtr.Zero) Then
                        
Throw New OutOfMemoryException( _
                            
"Unable to allocate memory for buffer.")
                    
End If
                    plainTextBlob.cbData 
= bytesSize
                    Marshal.Copy(plainText, 
0, plainTextBlob.pbData, bytesSize)
                
Catch ex As Exception
                    
Throw New Exception("Exception marshalling data.", ex)
                
End Try
                
If _store = Store.MachineStore Then
                    dwFlags 
= CRYPTPROTECT_LOCAL_MACHINE Or CRYPTOPROTECT_UI_FORBIDDEN
                    
Try
                        
Dim bytesSize = entropyText.Length
                        entropyBlob.pbData 
= Marshal.AllocHGlobal(bytesSize)
                        
If entropyBlob.pbData.Equals(IntPtr.Zero) Then
                            
Throw New OutOfMemoryException( _
                                
"Unable to allocate entropy data buffer.")
                        
End If
                        Marshal.Copy(entropyText, 
0, entropyBlob.pbData, bytesSize)
                        entropyBlob.cbData 
= bytesSize
                    
Catch ex As Exception
                        
Throw New Exception("Exception marshalling data.", ex)
                    
End Try
                
Else
                    dwFlags 
= CRYPTOPROTECT_UI_FORBIDDEN
                
End If
                retVal 
= CryptProtectData(plainTextBlob, String.Empty, entropyBlob, _
                                        IntPtr.Zero, prompt, dwFlags, cipherTextBlob)
                
If retVal = False Then
                    
Throw New DataProtectionException( _
                        
"Encryption failed. " & GetErrorMessage(Marshal.GetLastWin32Error))
                
End If
            
Catch ex As Exception
                
Throw New Exception("Exception encrypting.", ex)
            
End Try

            
Dim cipherText(cipherTextBlob.cbData) As Byte
            Marshal.Copy(cipherTextBlob.pbData, cipherText, 
0, cipherTextBlob.cbData)
            
Return cipherText

        
End Function

        
Public Function Decrypt(ByVal cipherText As Byte()) As Byte()
            
Dim entropy(0As Byte
            
Return Decrypt(cipherText, entropy)
        
End Function

        
Public Function Decrypt(ByVal cipherText As Byte(), _
                
ByVal entropyText As Byte()) As Byte()

            
Dim retVal As Boolean

            
Dim plainTextBlob As New DATA_BLOB
            
Dim cipherBlob As New DATA_BLOB

            
Dim prompt As New CRYPTPROTECT_PROMPTSTRUCT

            InitProptstruct(prompt)

            
Try
                
Try
                    
Dim cipherTextSize As Integer = cipherText.Length
                    cipherBlob.pbData 
= Marshal.AllocHGlobal(cipherTextSize)
                    
If cipherBlob.pbData.Equals(IntPtr.Zero) Then
                        
Throw New Exception("Unable to allocate cipherText buffer.")
                    
End If
                    cipherBlob.cbData 
= cipherTextSize
                    Marshal.Copy(cipherText, 
0, cipherBlob.pbData, cipherBlob.cbData)
                
Catch ex As Exception
                    
Throw New Exception("Exception marshalling data.", ex)
                
End Try
                
Dim entropyBlob As New DATA_BLOB
                
Dim dwFlags As Integer
                
If _store = Store.MachineStore Then
                    dwFlags 
= CRYPTPROTECT_LOCAL_MACHINE Or CRYPTOPROTECT_UI_FORBIDDEN
                    
Try
                        
Dim byteSize As Integer = entropyText.Length
                        entropyBlob.pbData 
= Marshal.AllocHGlobal(byteSize)
                        
If entropyBlob.pbData.Equals(IntPtr.Zero) Then
                            
Throw New OutOfMemoryException( _
                                
"Unable to allocate entropy buffer.")
                        
End If
                        entropyBlob.cbData 
= byteSize
                        Marshal.Copy(entropyText, 
0, entropyBlob.pbData, byteSize)
                    
Catch ex As Exception
                        
Throw New Exception("Exception entropy marshalling data.", ex)
                    
End Try
                
Else
                    dwFlags 
= CRYPTOPROTECT_UI_FORBIDDEN
                
End If
                retVal 
= CryptUnprotectData(cipherBlob, String.Empty, _
                                    entropyBlob, IntPtr.Zero, _
                                    prompt, dwFlags, plainTextBlob)
                
If retVal = False Then
                    
Throw New DataProtectionException( _
                        
"Decryption failed. " & GetErrorMessage(Marshal.GetLastWin32Error))
                
End If

                
If Not cipherBlob.Equals(IntPtr.Zero) Then
                    Marshal.FreeHGlobal(cipherBlob.pbData)
                
End If

                
If Not entropyBlob.pbData.Equals(IntPtr.Zero) Then
                    Marshal.FreeHGlobal(entropyBlob.pbData)
                
End If

            
Catch ex As Exception
                
Throw New Exception("Exception decrypting.", ex)
            
End Try

            
Dim plainText(plainTextBlob.cbData) As Byte
            Marshal.Copy(plainTextBlob.pbData, plainText, 
0, plainTextBlob.cbData)
            
Return plainText
        
End Function
#End Region

#Region " Helper Functions "
        
Private Sub InitProptstruct(ByRef ps As CRYPTPROTECT_PROMPTSTRUCT)
            ps.cbSize 
= Marshal.SizeOf(ps.GetType)
            ps.dwPromptFlags 
= 0
            ps.hwndApp 
= IntPtr.Zero
            ps.szPrompt 
= String.Empty
        
End Sub

        
Private Function GetErrorMessage(ByVal errorCode As IntegerAs String
            
Dim FORMAT_MESSAGE_ALLOCATE_BUFFER As Integer = &H100
            
Dim FORMAT_MESSAGE_IGNORE_INSERTS As Integer = &H200
            
Dim FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000

            
Dim messageSize As Integer = 255

            
Dim lpMsgBuf As String = ""
            Dim dwFlags As Integer = _
                FORMAT_MESSAGE_ALLOCATE_BUFFER _
                
Or FORMAT_MESSAGE_IGNORE_INSERTS _
                
Or FORMAT_MESSAGE_FROM_SYSTEM
            
Dim ptrlpSource As New IntPtr
            
Dim prtArguments As New IntPtr
            
Dim retVal = FormatMessage( _
                dwFlags, ptrlpSource, errorCode, 
0, lpMsgBuf, messageSize, prtArguments)
            
If retVal = 0 Then
                
Throw New Exception( _
                    
"Failed to format message for error code " & errorCode & "")
            
End If
            
Return lpMsgBuf

        
End Function
#End Region

    
End Class

End Namespace


 

posted on 2005-06-20 12:19  vuejs3  阅读(1033)  评论(0编辑  收藏  举报