📄 cryptoapitransform.cls
字号:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "CryptoAPITransform"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
' CopyRight (c) 2006 Kelly Ethridge
'
' This file is part of VBCorLib.
'
' VBCorLib is free software; you can redistribute it and/or modify
' it under the terms of the GNU Library General Public License as published by
' the Free Software Foundation; either version 2.1 of the License, or
' (at your option) any later version.
'
' VBCorLib is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
' GNU Library General Public License for more details.
'
' You should have received a copy of the GNU Library General Public License
' along with Foobar; if not, write to the Free Software
' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'
' Module: CryptoAPITransform
'
''
' Utilizes the Windows CryptoAPI cryptography services to perform data transformations.
'
' @remarks This class is used to support 3 cryptographic service providers within the
' CryptoAPI: DES, TripleDES, and RC2.
'
' @see DESCryptoServiceProvider
' @see TripleDESCryptoServiceProvider
' @see RC2CryptoServiceProvider
'
Option Explicit
Implements IObject
Implements ICryptoTransform
Private mBlockSize As Long
Private mCipherKey As Long
Private mPadding As PaddingMode
Private mIsEncrypting As Boolean
Private mLastBlock() As Byte
Private mKeepLastBlock As Boolean
Private mHasLastBlock As Boolean
''
' Returns if the current transfrom can be reused after calling TransformFinalBlock.
'
' @return Returns True if it can be reused, False otherwise.
' @remarks This always returns True.
'
Public Property Get CanReuseTransform() As Boolean
CanReuseTransform = True
End Property
''
' Returns if this transform can process more than one block per TransformBlock call.
'
' @return This always returns True.
'
Public Property Get CanTransformMultipleBlocks() As Boolean
CanTransformMultipleBlocks = True
End Property
''
' Returns the size of one block of data that is to be processed.
'
' @return The size of one block of data to be processed.
' @remarks When calling the TransformBlock method, the InputCount must be zero or a multiple of this value.
'
Public Property Get InputBlockSize() As Long
InputBlockSize = mBlockSize
End Property
''
' Returns the size of the resulting block of data after an input block of data has been processed.
'
' @return The size of the resulting block of data after an input block of data has been processed.
'
Public Property Get OutputBlockSize() As Long
OutputBlockSize = mBlockSize
End Property
''
' This returns the actual handle to a key created by the CryptoAPI service.
'
' @return A handle to a CryptoAPI key.
'
Public Property Get KeyHandle() As Long
KeyHandle = mCipherKey
End Property
''
' This will release the key and context of the CryptoAPI provider.
'
Public Sub Clear()
Call CryptoAPI.DestroyKey(mCipherKey)
Erase mLastBlock
End Sub
''
' Resets the transform so a new set of data can begin to be processed.
'
Public Sub Reset()
mHasLastBlock = False
Call CryptEncrypt(mCipherKey, 0, True, 0, ByVal 0&, 0, 0)
ReDim mLastBlock(0 To mBlockSize - 1)
Call CryptDecrypt(mCipherKey, 0, True, 0, mLastBlock(0), InputBlockSize)
ReDim mLastBlock(0 To mBlockSize - 1)
End Sub
''
' Processes a set of data, encrypting or decrypting it.
'
' @param InputBuffer The data to be processed.
' @param InputOffset The index to begin processing from.
' @param InputCount The amount of data to be processed.
' @param OutputBuffer The buffer to place the processed data.
' @param OutputOffset The index to begin placing the processed data.
' @return The number of bytes that were processed.
' @remarks The InputCount must be an exact multiple of the InputBlockSize or an exception will be thrown.
'
Public Function TransformBlock(ByRef InputBuffer() As Byte, ByVal InputOffset As Long, ByVal InputCount As Long, ByRef OutputBuffer() As Byte, ByVal OutputOffset As Long) As Long
' During normal transformations, the number of bytes to be worked on must be
' an exact multiple of mBlockSize. There can be no partial blocks.
If (InputCount <= 0) Or (InputCount Mod mBlockSize <> 0) Then _
Throw Cor.NewArgumentException("Invalid value.", "InputCount")
Dim Result As Long
Result = VerifyArrayRange(SAPtr(InputBuffer), InputOffset, InputCount)
If Result <> NO_ERROR Then Call ThrowArrayRangeException(Result, "InputBuffer", InputOffset, "InputOffset", InputCount, "InputCount", False)
' We can use the InputCount for the number of bytes to be outputted because
' this cipher keeps the original number of bytes in the encrypted output, except
' for any padding which is not added in this process.
Result = VerifyArrayRange(SAPtr(OutputBuffer), OutputOffset, InputCount)
If Result <> NO_ERROR Then Call ThrowArrayRangeException(Result, "OutputBuffer", OutputOffset, "OutputOffset", InputCount, "", False)
If mIsEncrypting Then
TransformBlock = EncryptBlock(InputBuffer, InputOffset, InputCount, OutputBuffer, OutputOffset)
Else
TransformBlock = DecryptBlock(InputBuffer, InputOffset, InputCount, OutputBuffer, OutputOffset)
End If
End Function
''
' Processes a set of data adding any padding needed to complete the process.
'
' @param InputBuffer The final data to be processed.
' @param InputOffset The index to begin processing from.
' @param InputCount The amount of data to be processed.
' @return The final block of processed data.
' @remarks Once a final block has been processed, the transform is reset to begin transforming new data.
'
Public Function TransformFinalBlock(ByRef InputBuffer() As Byte, ByVal InputOffset As Long, ByVal InputCount As Long) As Byte()
If cArray.IsNull(InputBuffer) Then _
Throw Cor.NewArgumentNullException("InputBuffer cannot be null", "InputBuffer")
If InputOffset < LBound(InputBuffer) Then _
Throw Cor.NewArgumentOutOfRangeException(Environment.GetResourceString(ArgumentOutOfRange_LBound), "InputOffset", InputOffset)
If (cArray.GetLength(InputBuffer) - InputCount < InputOffset) Then _
Throw Cor.NewArgumentException(Environment.GetResourceString(Argument_InvalidCountOffset))
If mIsEncrypting Then
TransformFinalBlock = EncryptFinalBlock(InputBuffer, InputOffset, InputCount)
Else
TransformFinalBlock = DecryptFinalBlock(InputBuffer, InputOffset, InputCount)
End If
End Function
''
' Returns a boolean indicating if the value and this object
' instance are the same instance.
'
' @param value The value to test equality on.
' @return Boolean indicating equality.
' @see IObject
'
Public Function Equals(ByRef Value As Variant) As Boolean
Equals = Object.Equals(Me, Value)
End Function
''
' Returns a psuedo-unique number used to help identify this
' object in memory. The current method is to return the value
' obtained from ObjPtr. If a different method needs to be impelmented
' then change the method here in this function.
'
' An override might be necessary if the hashcode should be
' derived from a value contained within the class.
'
Public Function GetHashCode() As Long
GetHashCode = ObjPtr(CUnk(Me))
End Function
''
' Returns a string representation of this object instance.
' The default method simply returns the application name
' and class name in which this class resides.
'
' A Person class may return the person's name instead.
'
Public Function ToString() As String
ToString = Object.ToString(Me, App)
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Friend Interface
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Friend Sub Init(ByVal Algorithm As Long, ByRef RgbKey() As Byte, ByRef RgbIV() As Byte, ByVal Base As SymmetricAlgorithmBase, ByVal IsEncrypting As Boolean, Optional ByVal EffectiveKeySize As Long = 0, Optional ByVal UseSalt As Boolean = False)
With Base
If .Mode = CipherMode.OFB Then _
Throw Cor.NewCryptographicException("Output Feedback (OFB) mode is not supported.")
mCipherKey = CryptoAPI.ImportPlainTextKey(CryptoAPI.DefaultProvider, Algorithm, RgbKey, UseSalt)
Call CryptoAPI.SetKeyParam(mCipherKey, KP_MODE, .Mode)
If .Mode <> CipherMode.ECB Then Call CryptoAPI.SetKeyParam(mCipherKey, KP_IV, RgbIV)
If .Mode = CipherMode.CFB Then Call CryptoAPI.SetKeyParam(mCipherKey, KP_MODE_BITS, .FeedbackSize)
If EffectiveKeySize > 0 Then Call CryptoAPI.SetKeyParam(mCipherKey, KP_EFFECTIVE_KEYLEN, EffectiveKeySize)
mBlockSize = .BlockSize \ 8
mPadding = .Padding
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -