📄 rijndaelmanagedtransform.cls
字号:
Select Case mMode
Case CipherMode.ECB: Call EncryptECB(OutputBuffer, 0, TotalBytes)
Case CipherMode.CBC: Call EncryptCBC(OutputBuffer, 0, TotalBytes)
Case CipherMode.CFB: Call EncryptCFB(OutputBuffer, 0, TotalBytes)
End Select
Else
OutputBuffer = Cor.NewBytes()
End If
Call Reset
EncryptFinalBlock = OutputBuffer
End Function
Private Function DecryptFinalBlock(ByRef InputBuffer() As Byte, ByVal InputOffset As Long, ByVal InputCount As Long) As Byte()
If (InputCount Mod mInputBlockSize) <> 0 Then _
Throw Cor.NewCryptographicException("Invalid data length.")
Dim TotalBytes As Long
TotalBytes = InputCount
' If we kept the last block from the previous decrypt call then we need
' to include it in this final decryption call, so up the total bytes to process.
If mHasLastBlock Then
TotalBytes = TotalBytes + mInputBlockSize
End If
' If we still don't have anything to process (no previous block and nothing in this block)
' then simply reset everything and return an empty byte array representing the final block.
If TotalBytes = 0 Then
Call Reset
DecryptFinalBlock = Cor.NewBytes
Exit Function
End If
' Allocate the buffer that all the work will be performed on.
Dim OutputBuffer() As Byte
ReDim OutputBuffer(0 To TotalBytes - 1)
' If we kept the last block from the previous decrypt call then we need
' to now copy that block into the working buffer.
Dim OutputOffset As Long
If mHasLastBlock Then
Call CopyMemory(OutputBuffer(0), mLastBlock(0), mInputBlockSize)
OutputOffset = mInputBlockSize
mHasLastBlock = False
End If
' If there is something in the InputBuffer to be processed, then
' add it to the working buffer, too.
If InputCount > 0 Then Call CopyMemory(OutputBuffer(OutputOffset), InputBuffer(InputOffset), InputCount)
' Have the decryption routine work on the bytes in the output buffer. The decrypted bytes
' will be placed back into the same buffer.
Select Case mMode
Case CipherMode.ECB: Call DecryptECB(OutputBuffer, 0, TotalBytes)
Case CipherMode.CBC: Call DecryptCBC(OutputBuffer, 0, TotalBytes)
Case CipherMode.CFB: Call DecryptCFB(OutputBuffer, 0, TotalBytes)
End Select
' Remove the padding based on the type of padding expected.
Dim DepadCount As Long
DepadCount = CryptoHelper.DepadBlock(OutputBuffer, mPadding, mInputBlockSize)
' Calculate how many plain text bytes we really have.
Dim NewSize As Long
NewSize = TotalBytes - DepadCount
If NewSize > 0 Then
' Chop of the end padding bytes now. This is pretty efficient
' because the data is not actually moved since we are shrinking the array.
ReDim Preserve OutputBuffer(0 To NewSize - 1)
Else
' Nothing is left, so return an empty array.
OutputBuffer = Cor.NewBytes
End If
Call Reset
DecryptFinalBlock = OutputBuffer
End Function
''
' This function is usually be called repeatedly. The last block may be buffered and not processed
' on the same call. It may be processed during the next call or the call to TransformFinalBlock.
'
Private Function DecryptBlock(ByRef InputBuffer() As Byte, ByVal InputOffset As Long, ByVal InputCount As Long, ByRef OutputBuffer() As Byte, ByVal OutputOffset As Long) As Long
Dim NextOutputOffset As Long
NextOutputOffset = OutputOffset
' Start of attempting to process the original requested number of bytes.
Dim TotalBytes As Long
TotalBytes = InputCount
' If we buffered the last block from the previous call, then we now need to
' include it in this decryption process as the first block of the InputBuffer.
If mHasLastBlock Then
Call CopyMemory(OutputBuffer(NextOutputOffset), mLastBlock(0), mInputBlockSize)
NextOutputOffset = NextOutputOffset + mInputBlockSize
TotalBytes = TotalBytes + mInputBlockSize
mHasLastBlock = False
End If
' If we are still needing to keep the last block after each call, then we need
' to copy it now and not include it in the current operation by decrementing the
' number of bytes to be processed.
If mKeepLastBlock Then
TotalBytes = TotalBytes - mInputBlockSize
InputCount = InputCount - mInputBlockSize
Call CopyMemory(mLastBlock(0), InputBuffer(InputOffset + InputCount), mInputBlockSize)
mHasLastBlock = True
End If
' If there is anything left in the InputBuffer to process we need to copy it to the
' output buffer which the decryption routine will work on.
If InputCount > 0 Then Call CopyMemory(OutputBuffer(NextOutputOffset), InputBuffer(InputOffset), InputCount)
' Have the decryption routine work on the bytes in the output buffer. The decrypted bytes
' will be placed back into the same buffer.
Select Case mMode
Case CipherMode.ECB: Call DecryptECB(OutputBuffer, OutputOffset, TotalBytes)
Case CipherMode.CBC: Call DecryptCBC(OutputBuffer, OutputOffset, TotalBytes)
Case CipherMode.CFB: Call DecryptCFB(OutputBuffer, OutputOffset, TotalBytes)
End Select
' Return how many bytes we actually decrypted.
DecryptBlock = TotalBytes
End Function
Private Function EncryptBlock(ByRef InputBuffer() As Byte, ByVal InputOffset As Long, ByVal InputCount As Long, ByRef OutputBuffer() As Byte, ByVal OutputOffset As Long) As Long
' Since the cipher changes the data within the same array, we need to copy the
' plain text data to the output buffer and let the cipher work on that buffer.
Call CopyMemory(OutputBuffer(OutputOffset), InputBuffer(InputOffset), InputCount)
Select Case mMode
Case CipherMode.ECB: Call EncryptECB(OutputBuffer, OutputOffset, InputCount)
Case CipherMode.CBC: Call EncryptCBC(OutputBuffer, OutputOffset, InputCount)
Case CipherMode.CFB: Call EncryptCFB(OutputBuffer, OutputOffset, InputCount)
End Select
EncryptBlock = InputCount
End Function
''
' ECB feedback doesn't actually use any feedback or IV values. Each block is individually processed.
'
' This performs inplace encryption. The array should be the output array so as not to
' mangle the original input array.
'
Private Sub EncryptECB(ByRef Bytes() As Byte, ByVal Index As Long, ByVal Count As Long)
' encrypt a single blocks worth of data at a time.
Dim i As Long
For i = 0 To Count - 1 Step mInputBlockSize
Select Case mBlockSizeBits
Case 128: Call Encrypt128(Bytes, Index + i)
Case 192: Call Encrypt192(Bytes, Index + i)
Case 256: Call Encrypt256(Bytes, Index + i)
End Select
Next i
End Sub
''
' CBC feedback uses the IV array to kind of pre-mangle the data to be encrypted. Once a block
' has been encrypted, the IV is updated for the next block encryption.
'
Private Sub EncryptCBC(ByRef Bytes() As Byte, ByVal Index As Long, ByVal Count As Long)
Dim i As Long
For i = 0 To Count - 1 Step mInputBlockSize
' apply the CBC feedback before encrypting the text.
Dim j As Long
For j = 0 To mInputBlockSize - 1
Bytes(Index + i + j) = Bytes(Index + i + j) Xor mWorkingIV(j)
Next j
Select Case mBlockSizeBits
Case 128: Call Encrypt128(Bytes, Index + i)
Case 192: Call Encrypt192(Bytes, Index + i)
Case 256: Call Encrypt256(Bytes, Index + i)
End Select
' update the IV we are using for the next block to be mangled.
Call CopyMemory(ByVal mWorkingIVPtr, Bytes(Index + i), mInputBlockSize)
Next i
End Sub
''
' CFB will encrypt the current IV array instead of the plain text. Then the encrypted
' IV array will be Xor'd with the plain text data.
'
Private Sub EncryptCFB(ByRef Bytes() As Byte, ByVal Index As Long, ByVal Count As Long)
Dim i As Long
For i = 0 To Count - 1 Step mInputBlockSize
' encrypt the IV array first.
Call CopyMemory(ByVal mTempIVPtr, ByVal mWorkingIVPtr, mBlockSizeBytes)
Select Case mBlockSizeBits
Case 128: Call Encrypt128(mTempIV, 0)
Case 192: Call Encrypt192(mTempIV, 0)
Case 256: Call Encrypt256(mTempIV, 0)
End Select
' Xor the IV array with the plain text.
Dim j As Long
For j = 0 To mInputBlockSize - 1
Bytes(Index + i + j) = Bytes(Index + i + j) Xor mTempIV(j)
Next j
' move the unused portion down to be used next time around. The unused
' portion will be encrypted again, as well.
If (mBlockSizeBytes - mInputBlockSize) > 0 Then
Call CopyMemory(ByVal mWorkingIVPtr, mWorkingIV(mInputBlockSize), mBlockSizeBytes - mInputBlockSize)
End If
' Copy the cipher text back to the IV to be used in the next block.
Call CopyMemory(mWorkingIV(mBlockSizeBytes - mInputBlockSize), Bytes(Index + i), mInputBlockSize)
Next i
End Sub
''
' Performs a straight decryption on each individual inputblocksize of bytes. No feedback
' is used on the data.
'
Private Sub DecryptECB(ByRef Bytes() As Byte, ByVal Index As Long, ByVal Count As Long)
Dim i As Long
For i = 0 To Count - 1 Step mInputBlockSize
Select Case mBlockSizeBits
Case 128: Call Decrypt128(Bytes, Index + i)
Case 192: Call Decrypt192(Bytes, Index + i)
Case 256: Call Decrypt256(Bytes, Index + i)
End Select
Next i
End Sub
''
' CBC feedback uses the IV array to kind of pre-mangle the data to be encrypted. Once a block
' has been encrypted, the IV is updated for the next block encryption.
'
Private Sub DecryptCBC(ByRef Bytes() As Byte, ByVal Index As Long, ByVal Count As Long)
Dim i As Long
For i = 0 To Count - 1 Step mInputBlockSize
Call CopyMemory(ByVal mTempIVPtr, Bytes(Index + i), mBlockSizeBytes)
Select Case mBlockSizeBits
Case 128: Call Decrypt128(Bytes, Index + i)
Case 192: Call Decrypt192(Bytes, Index + i)
Case 256: Call Decrypt256(Bytes, Index + i)
End Select
Dim j As Long
For j = 0 To mInputBlockSize - 1
Bytes(Index + i + j) = Bytes(Index + i + j) Xor mWorkingIV(j)
Next j
Call CopyMemory(ByVal mWorkingIVPtr, ByVal mTempIVPtr, mBlockSizeBytes)
Next i
End Sub
''
' CFB will encrypt the current IV array instead of the plain text. Then the encrypted
' IV array will be Xor'd with the plain text data.
'
Private Sub DecryptCFB(ByRef Bytes() As Byte, ByVal Index As Long, ByVal Count As Long)
Dim i As Long
For i = 0 To Count - 1 Step mInputBlockSize
Call CopyMemory(ByVal mTempIVPtr, ByVal mWorkingIVPtr, mBlockSizeBytes)
Select Case mBlockSizeBits
Case 128: Call Encrypt128(mTempIV, 0)
Case 192: Call Encrypt192(mTempIV, 0)
Case 256: Call Encrypt256(mTempIV, 0)
End Select
If (mBlockSizeBytes - mInputBlockSize) > 0 Then
Call CopyMemory(ByVal mWorkingIVPtr, mWorkingIV(mInputBlockSize), mBlockSizeBytes - mInputBlockSize)
End If
Call CopyMemory(mWorkingIV(mBlockSizeBytes - mInputBlockSize), Bytes(Index + i), mInputBlockSize)
Dim j As Long
For j = 0 To mInputBlockSize - 1
Bytes(Index + i + j) = Bytes(Index + i + j) Xor mTempIV(j)
Next j
Next i
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Encryption/Decryption blocks are unrolled to increase performance,
' therefore, there is an encryption and decryption routine for
' each block size.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub Encrypt128(ByRef Bytes() As Byte, ByVal Index As Long)
Dim bPtr As Long
bPtr = VarPtr(Bytes(Index))
MemLong(mSPtr) = MemLong(bPtr) Xor mExpKey(0)
MemLong(mSPtr + 4) = MemLong(bPtr + 4) Xor mExpKey(1)
MemLong(mSPtr + 8) = MemLong(bPtr + 8) Xor mExpKey(2)
MemLong(mSPtr + 12) = MemLong(bPtr + 12) Xor mExpKey(3)
With mTmp
Dim j As Long
j = 4
Dim i As Long
For i = 1 To mNr - 1
.T0 = mT0(.s(0)) Xor mT1(.s(5)) Xor mT2(.s(10)) Xor mT3(.s(15)) Xor mExpKey(j)
.T1 = mT0(.s(4)) Xor mT1(.s(9)) Xor mT2(.s(14)) Xor mT3(.s(3)) Xor mExpKey(j + 1)
.T2 = mT0(.s(8)) Xor mT1(.s(13)) Xor mT2(.s(2)) Xor mT3(.s(7)) Xor mExpKey(j + 2)
.T3 = mT0(.s(12)) Xor mT1(.s(1)) Xor mT2(.s(6)) Xor mT3(.s(11)) Xor mExpKey(j + 3)
j = j + 4
Call CopyMemory(ByVal mSPtr, ByVal mTmpPtr, 16)
Next i
MemLong(bPtr) = (mT4(.s(0)) And &HFF&) Xor (mT4(.s(5)) And &HFF00&) Xor (mT4(.s(10)) And &HFF0000) Xor (mT4(.s(15)) And &HFF000000) Xor mExpKey(j)
MemLong(bPtr + 4) = (mT4(.s(4)) And &HFF&) Xor (mT4(.s(9)) And &HFF00&) Xor (mT4(.s(14)) And &HFF0000) Xor (mT4(.s(3)) And &HFF000000) Xor mExpKey(j + 1)
MemLong(bPtr + 8) = (mT4(.s(8)) And &HFF&) Xor (mT4(.s(13)) And &HFF00&) Xor (mT4(.s(2)) And &HFF0000) Xor (mT4(.s(7)) And &HFF000000) Xor mExpKey(j + 2)
MemLong(bPtr + 12) = (mT4(.s(12)) And &HFF&) Xor (mT4(.s(1)) And &HFF00&) Xor (mT4(.s(6)) And &HFF0000) Xor (mT4(.s(11)) And &HFF000000) Xor mExpKey(j + 3)
End With
End Sub
Private Sub Encrypt192(ByRef Bytes() As Byte, ByVal Index As Long)
Dim bPtr As Long
bPtr = VarPtr(Bytes(Index))
MemLong(mSPtr) = MemLong(bPtr) Xor mExpKey(0)
MemLong(mSPtr + 4) = MemLong(bPtr + 4) Xor mExpKey(1)
MemLong(mSPtr + 8) = MemLong(bPtr + 8) Xor mExpKey(2)
MemLong(mSPtr + 12) = MemLong(bPtr + 12) Xor mExpKey(3)
MemLong(mSPtr + 16) = MemLong(bPtr + 16) Xor mExpKey(4)
MemLong(mSPtr + 20) = MemLong(bPtr + 20) Xor mExpKey(5)
With mTmp
Dim j As Long
j = 6
Dim i As Long
For i = 1 To mNr - 1
.T0 = mT0(.s(0)) Xor mT1(.s(5)) Xor mT2(.s(10)) Xor mT3(.s(15)) Xor mExpKey(j)
.T1 = mT0(.s(4)) Xor mT1(.s(9)) Xor mT2(.s(14)) Xor mT3(.s(19)) Xor mExpKey(j + 1)
.T2 = mT0(.s(8)) Xor mT1(.s(13)) Xor mT2(.s(18)) Xor mT3(.s(23)) Xor mExpKey(j + 2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -