📄 dataprotection.vb
字号:
'---------------------------------------------------------------------
' This file is part of the Microsoft .NET Framework SDK Code Samples.
'
' Copyright (C) Microsoft Corporation. All rights reserved.
'
' This source code is intended only as a supplement to Microsoft
' Development Tools and/or on-line documentation. See these other
' materials for detailed information regarding Microsoft code samples.
'
' THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
' KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
' IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
' PARTICULAR PURPOSE.
'---------------------------------------------------------------------
Imports System
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Security
<Serializable()> _
Public NotInheritable Class DataProtection
<Flags()> _
Public Enum CryptProtectPromptFlags
CRYPTPROTECT_PROMPT_ON_UNPROTECT = &H1
CRYPTPROTECT_PROMPT_ON_PROTECT = &H2
CRYPTPROTECT_PROMPT_RESERVED = &H4
CRYPTPROTECT_PROMPT_STRONG = &H8
CRYPTPROTECT_PROMPT_REQUIRE_STRONG = &H10
End Enum
<Flags()> _
Public Enum CryptProtectDataFlags
CRYPTPROTECT_UI_FORBIDDEN = &H1
CRYPTPROTECT_LOCAL_MACHINE = &H4
CRYPTPROTECT_CRED_SYNC = &H8
CRYPTPROTECT_AUDIT = &H10
CRYPTPROTECT_NO_RECOVERY = &H20
CRYPTPROTECT_VERIFY_PROTECTION = &H40
CRYPTPROTECT_CRED_REGENERATE = &H80
End Enum
Public Shared Function ProtectData(ByVal data As String, ByVal name As String) As String
Return ProtectData(data, name, CryptProtectDataFlags.CRYPTPROTECT_UI_FORBIDDEN Or CryptProtectDataFlags.CRYPTPROTECT_LOCAL_MACHINE)
End Function
Public Shared Function ProtectData(ByVal data As Byte(), ByVal name As String) As Byte()
Return ProtectData(data, name, CryptProtectDataFlags.CRYPTPROTECT_UI_FORBIDDEN Or CryptProtectDataFlags.CRYPTPROTECT_LOCAL_MACHINE)
End Function
Public Shared Function ProtectData(ByVal data As String, ByVal name As String, ByVal flags As CryptProtectDataFlags) As String
Dim dataIn As Byte() = Encoding.Unicode.GetBytes(data)
Dim dataOut As Byte() = ProtectData(dataIn, name, flags)
If Not dataOut Is Nothing Then
Return (Convert.ToBase64String(dataOut))
Else
Return Nothing
End If
End Function
Private Shared Function ProtectData(ByVal data As Byte(), ByVal name As String, ByVal dwFlags As CryptProtectDataFlags) As Byte()
Dim cipherText As Byte() = Nothing
'copy data into unmanaged memory
Dim din As New DPAPI.DATA_BLOB()
din.cbData = data.Length
din.pbData = Marshal.AllocHGlobal(din.cbData)
If din.pbData.Equals(IntPtr.Zero) Then Throw New OutOfMemoryException("Unable to allocate memory for buffer.")
Marshal.Copy(data, 0, din.pbData, din.cbData)
Dim dout As New DPAPI.DATA_BLOB()
Try
Dim cryptoRetval As Boolean = DPAPI.CryptProtectData(din, name, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, dwFlags, dout)
If cryptoRetval Then 'ERROR_SUCCESS?
Dim startIndex As Integer = 0
ReDim cipherText(dout.cbData)
Marshal.Copy(dout.pbData, cipherText, startIndex, dout.cbData)
DPAPI.LocalFree(dout.pbData)
Else
Dim errCode As Integer = Marshal.GetLastWin32Error()
Dim buffer As New StringBuilder(256)
Win32Error.FormatMessage(Win32Error.FormatMessageFlags.FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, errCode, 0, buffer, buffer.Capacity, IntPtr.Zero)
End If
Finally
'free the allocated memroy in use
If Not din.pbData.Equals(IntPtr.Zero) Then Marshal.FreeHGlobal(din.pbData)
End Try
Return cipherText
End Function
Public Shared Function UnprotectData(ByVal data As Byte()) As Byte()
Return UnprotectData(data, CryptProtectDataFlags.CRYPTPROTECT_UI_FORBIDDEN)
End Function
Public Shared Function UnprotectData(ByVal data As String) As String
Dim dataIn As Byte() = Convert.FromBase64String(data)
Dim dataOut As Byte() = UnprotectData(dataIn)
If Not dataOut Is Nothing Then
Return Encoding.Unicode.GetString(dataOut)
Else
Return Nothing
End If
End Function
Friend Shared Function UnprotectData(ByVal data As Byte(), ByVal dwFlags As CryptProtectDataFlags) As Byte()
Dim clearText As Byte() = Nothing
'copy data into unmanaged memory
Dim din As New DPAPI.DATA_BLOB()
din.cbData = data.Length
din.pbData = Marshal.AllocHGlobal(din.cbData)
If din.pbData.Equals(IntPtr.Zero) Then Throw New OutOfMemoryException("Unable to allocate memory for buffer.")
Marshal.Copy(data, 0, din.pbData, din.cbData)
Dim dout As New DPAPI.DATA_BLOB()
Try
Dim cryptoRetval As Boolean = DPAPI.CryptUnprotectData(din, Nothing, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, dwFlags, dout)
If cryptoRetval Then 'ERROR_SUCCESS?
ReDim clearText(dout.cbData)
Marshal.Copy(dout.pbData, clearText, 0, dout.cbData)
DPAPI.LocalFree(dout.pbData)
Else
Dim errCode As Integer = Marshal.GetLastWin32Error()
Dim buffer As New StringBuilder(256)
Win32Error.FormatMessage(Win32Error.FormatMessageFlags.FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, errCode, 0, buffer, buffer.Capacity, IntPtr.Zero)
End If
Finally
'free the allocated memory in use
If Not din.pbData.Equals(IntPtr.Zero) Then Marshal.FreeHGlobal(din.pbData)
End Try
Return clearText
End Function
Friend Shared Sub InitPromptstruct(ByRef ps As DPAPI.CRYPTPROTECT_PROMPTSTRUCT)
ps.cbSize = Marshal.SizeOf(GetType(DPAPI.CRYPTPROTECT_PROMPTSTRUCT))
ps.dwPromptFlags = 0
ps.hwndApp = IntPtr.Zero
ps.szPrompt = Nothing
End Sub
End Class
<SuppressUnmanagedCodeSecurityAttribute()> _
Friend Class DPAPI
<DllImport("crypt32")> _
Public Shared Function CryptProtectData(ByRef dataIn As DATA_BLOB, ByVal szDataDescr As String, ByVal optionalEntropy As IntPtr, ByVal pvReserved As IntPtr, ByVal pPromptStruct As IntPtr, ByVal dwFlags As DataProtection.CryptProtectDataFlags, ByRef pDataOut As DATA_BLOB) As Boolean
End Function
<DllImport("crypt32")> _
Public Shared Function CryptUnprotectData(ByRef dataIn As DATA_BLOB, ByVal ppszDataDescr As StringBuilder, ByVal optionalEntropy As IntPtr, ByVal pvReserved As IntPtr, ByVal pPromptStruct As IntPtr, ByVal dwFlags As DataProtection.CryptProtectDataFlags, ByRef pDataOut As DATA_BLOB) As Boolean
End Function
<DllImport("Kernel32.dll")> _
Public Shared Function LocalFree(ByVal hMem As IntPtr) As IntPtr
End Function
<StructLayout(LayoutKind.Sequential)> _
Public Structure DATA_BLOB
Public cbData As Integer
Public pbData As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure CRYPTPROTECT_PROMPTSTRUCT
Public cbSize As Integer '= Marshal.SizeOf(typeof(CRYPTPROTECT_PROMPTSTRUCT))
Public dwPromptFlags As Integer '= 0
Public hwndApp As IntPtr '= IntPtr.Zero
Public szPrompt As String ' = nothing
End Structure
End Class
Friend Class Win32Error
<Flags()> _
Public Enum FormatMessageFlags : int
FORMAT_MESSAGE_ALLOCATE_BUFFER = &H100
FORMAT_MESSAGE_IGNORE_INSERTS = &H200
FORMAT_MESSAGE_FROM_STRING = &H400
FORMAT_MESSAGE_FROM_HMODULE = &H800
FORMAT_MESSAGE_FROM_SYSTEM = &H1000
FORMAT_MESSAGE_ARGUMENT_ARRAY = &H2000
FORMAT_MESSAGE_MAX_WIDTH_MASK = &HFF
End Enum
<DllImport("Kernel32.dll")> _
Public Shared Function FormatMessage(ByVal flags As FormatMessageFlags, ByVal source As IntPtr, ByVal messageId As Integer, ByVal languageId As Integer, ByVal buffer As StringBuilder, ByVal size As Integer, ByVal arguments As IntPtr) As Integer
End Function
End Class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -