Creates an input block suitably padded for encryption by a block cipher in ECB or CBC mode.
Public Declare Function PAD_BytesBlock Lib "diCryptoSys.dll" (ByRef lpOutput As Byte, ByVal nOutputLen As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal nBlockLen As Long, ByVal nOptions As Long) As Long
nRet = PAD_BytesBlock(lpOutput(0), nOutputLen, abInput(0), nInputLen, nBlockLen, 0)
' Note the "(0)" after the byte array parameters
long __stdcall PAD_BytesBlock(unsigned char *lpOutput, long nOutputLen, const unsigned char *lpInput, long nBytes, long nBlkLen, long nOptions);
If successful, the return value is the number of bytes in the output; otherwise it returns a negative error code.
Public Function padBytesBlock
(lpInput() As Byte, nBlkLen As Long, Optional nOptions As Long = 0) As Byte()
Cipher.Pad Method (Byte[], CipherAlgorithm, Padding)
or use the method associated with the relevant encryption algorithm class:
Aes128.Pad Method (Byte[])
Blowfish.Pad Method (Byte[])
Des.Pad Method (Byte[])
Tdea.Pad Method (Byte[])
static Cipher.pad(data, alg, pad=Pad.PKCS5)
If nOutBytes is set to zero or lpOutput set to 0 (or NULL
in C or ByVal 0&
in VBA),
then the required number of bytes will be returned. The output is always longer than the input.
Only block lengths of 8 or 16 bytes are supported.
For more details of the supported padding schemes, see Padding schemes for block ciphers.
Dim abInput() As Byte Dim lpOutput() As Byte Dim nOutputLen As Long Dim nInputLen As Long Dim nBlockLen As Long Dim i As Long ' Prepare test input 5 bytes long nInputLen = 5 ReDim abInput(nInputLen - 1) For i = 0 To nInputLen - 1 abInput(i) = &HFF Next Debug.Print "Input data=0x" & cnvHexStrFromBytes(abInput) ' Find out the required length nBlockLen = 8 nOutputLen = PAD_BytesBlock(0, 0, abInput(0), nInputLen, nBlockLen, 0) Debug.Print "Required length is " & nOutputLen & " bytes" ' Check for error If (nOutputLen <= 0) Then Exit Function ' Pre-dimension output ReDim lpOutput(nOutputLen - 1) nOutputLen = PAD_BytesBlock(lpOutput(0), nOutputLen, abInput(0), nInputLen, nBlockLen, 0) Debug.Print "Padded data=0x" & cnvHexStrFromBytes(lpOutput) ' Now set input as padded output and remove padding abInput = lpOutput nInputLen = nOutputLen ' Remove padding... ' No need to query for length because we know the output will be shorter than input ' so make sure output is as long as the input nOutputLen = nInputLen ReDim lpOutput(nOutputLen - 1) nOutputLen = PAD_UnpadBytes(lpOutput(0), nOutputLen, abInput(0), nInputLen, nBlockLen, 0) Debug.Print "Unpadded length is " & nOutputLen & " bytes" ' Check for error If (nOutputLen <= 0) Then Exit Function ' Re-dimension the output to the correct length ReDim Preserve lpOutput(nOutputLen - 1) Debug.Print "Unpadded data=0x" & cnvHexStrFromBytes(lpOutput)
This should result in output as follows:
Input data=0xFFFFFFFFFF Required length is 8 bytes Padded data=0xFFFFFFFFFF030303 Unpadded length is 5 bytes Unpadded data=0xFFFFFFFFFF
Dim lpInput() As Byte Dim lpBlock() As Byte Dim lpUnpadded() As Byte lpInput = cnvBytesFromHexStr("FFFFFFFFFF") Debug.Print "Input data = 0x" & cnvHexStrFromBytes(lpInput) lpBlock = padBytesBlock(lpInput, 8, 0) Debug.Print "Padded data = 0x" & cnvHexStrFromBytes(lpBlock) ' Unpad lpUnpadded = padUnpadBytes(lpBlock, 8, 0) Debug.Print "Unpadded data = 0x" & cnvHexStrFromBytes(lpUnpadded) ' Special corner case - output is the empty string lpBlock = cnvBytesFromHexStr("0808080808080808") Debug.Print "Padded data = 0x" & cnvHexStrFromBytes(lpBlock) lpUnpadded = padUnpadBytes(lpBlock, 8, 0) Debug.Print "Unpadded data = 0x" & cnvHexStrFromBytes(lpUnpadded)
PAD_UnpadBytes
PAD_HexBlock
PAD_UnpadHex