CryptoSys API Library Manual

CIPHER_EncryptBytes

Encrypts data in a byte array using the specified block cipher algorithm, mode and padding. The key and initialization vector are passed as byte arrays.

VBA/VB6 Syntax

Public Declare Function CIPHER_EncryptBytes Lib "diCryptoSys.dll" (ByRef lpOutput As Byte, ByVal nOutBytes As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByRef lpKey As Byte, ByVal nKeyLen As Long, ByRef lpIV As Byte, ByVal nIvLen As Long, ByVal strAlgModePad As String, ByVal nOptions As Long) As Long

nRet = CIPHER_EncryptBytes(lpOutput(0), nOutBytes, abInput(0), nInputLen, abKey(0), nKeylen abIV(0), nIvLen, strAlgModePad, nOptions)

C/C++ Syntax

long __stdcall CIPHER_EncryptBytes(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, const unsigned char *lpKey, long nKeyLen, const unsigned char *lpIV, long nIvLen, const char *szAlgModePad, long nOptions);

Parameters

lpOutput
[out] array of sufficient length to receive the output.
nOutBytes
[in] specifying the length of the output buffer in bytes.
lpInput
[in] array containing the input data.
nInputLen
[in] specifying the length of the input data in bytes.
lpKey
[in] array containing the key.
nKeyLen
[in] the length of the key in bytes.
lpIV
[in] containing the initialization vector (IV), or zero (0) or NULL for ECB mode.
nIvLen
[in] the length of the IV in bytes.
szAlgModePad
[in] containing the block cipher algorithm, mode and padding (see Specifying the algorithm, mode and padding for generic block cipher functions).
nOptions
[in] option flags:
Zero (0) for default options. Optionally add:
API_IV_PREFIX to prepend the IV before the ciphertext in the output (ignored for ECB mode).

Returns (VBA/C)

If successful, the return value is the number of bytes required in the output; otherwise it returns a negative error code.

VBA Wrapper Syntax

Public Function cipherEncryptBytes(lpInput() As Byte, lpKey() As Byte, lpIV() As Byte, szAlgModePad As String, Optional nOptions As Long = 0) As Byte()

.NET Equivalent

Cipher.Encrypt Method (Byte[], Byte[], Byte[], CipherAlgorithm, Mode, Padding, Cipher.Opts)

Python Equivalent

static Cipher.encrypt(data, key, iv=None, algmodepad='', alg=None, mode=Mode.ECB, pad=Pad.DEFAULT, opts=Opts.DEFAULT)
static Cipher.encrypt_block(data, key, iv=None, alg=Alg.TDEA, mode=Mode.ECB)

Remarks

Padding is added as specified to the input before encryption. The user must allocate an output buffer of the required length, which will always be at least as long as the input, or longer if padding is to be added.

The algorithm/mode/padding must be specified using either the szAlgModePad string or nOptions parameter, but not both (see Specifying the algorithm, mode and padding for generic block cipher functions). The length of key lpKey must be exactly the required key size, and the length of the IV, if required, exactly the block size. See Valid key and block sizes.

If nOutBytes is set to zero or lpOutput set to 0 (or NULL in C or ByVal 0& in VBA), the required number of bytes will be returned. If the NoPadding option is specified, the required output length will be the same as the input.

Defaults: If padding is not specified then the default padding method depends on the cipher mode: pkcs5padding will be used for ECB and CBC mode and nopadding for all other modes. The default cipher mode is ECB. Thus "aes128" is the same as "aes128/ecb/pkcs5padding".

Note that padding is only needed for ECB or CBC mode where the input length is not a multiple of the block size. It is an error (BAD_LENGTH_ERROR) to specify NoPadding with ECB or CBC mode if the length of the input is not an exact multiple of the block size.

The padding option is ignored for CTR, OFB and CFB modes, which do not need padding. The default nopadding is always used for these modes regardless of what is specified (so just use the default, e.g. "aes128/ctr").

[New in v5.4] Use the API_IV_PREFIX to prepend the IV before the ciphertext in the output. This will add the IV before the ciphertext in the form IV||CT. This is the scheme used with block ciphers in XML encryption (see section 5.2 of [XMLENC]) where they use the phrase "The resulting cipher text is prefixed by the IV." It is the responsibility of the receiver to parse this data to recover the IV.

Example (VBA core function)

Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim ok() As Byte
Dim ptlen As Long
Dim ctlen As Long
Dim keylen As Long
Dim ivlen As Long
Dim algstr As String

algstr = "Aes128/CBC/OneAndZeroes"
Debug.Print algstr
key = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
iv = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210")
keylen = UBound(key) + 1
ivlen = UBound(iv) + 1
Debug.Print "KY=" & cnvHexStrFromBytes(key)
Debug.Print "IV=" & cnvHexStrFromBytes(iv)
' "Now is the time for all good men to"
pt = cnvBytesFromHexStr("4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F")
ptlen = UBound(pt) + 1
' Correct result
ok = cnvBytesFromHexStr("C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B")
Debug.Print ("PT=" & cnvHexStrFromBytes(pt))
Debug.Print ("PT='" & StrConv(pt, vbUnicode) + "'")
' 1. Find out how long an output buffer we need
ctlen = CIPHER_EncryptBytes(0, 0, pt(0), ptlen, key(0), keylen, iv(0), ivlen, algstr, 0)
Debug.Print "CIPHER_EncryptBytes returns " & ctlen
' 2. Allocate the buffer
ReDim ct(ctlen - 1)
' 3. Encrypt to output buffer
ctlen = CIPHER_EncryptBytes(ct(0), ctlen, pt(0), ptlen, key(0), keylen, iv(0), ivlen, algstr, 0)

Debug.Print "CT=" & cnvHexStrFromBytes(ct)
Debug.Print "OK=" & cnvHexStrFromBytes(ok)

' PART 2 - prefix the IV in the output
ctlen = CIPHER_EncryptBytes(0, 0, pt(0), ptlen, key(0), keylen, iv(0), ivlen, algstr, API_IV_PREFIX)
Debug.Print "CIPHER_EncryptBytes(API_IV_PREFIX) returns " & ctlen
ReDim ct(ctlen - 1)
ctlen = CIPHER_EncryptBytes(ct(0), ctlen, pt(0), ptlen, key(0), keylen, iv(0), ivlen, algstr, API_IV_PREFIX)

Debug.Print "IV||CT=" & cnvHexStrFromBytes(ct)

This should result in output as follows:

Aes128/CBC/OneAndZeroes
KY=0123456789ABCDEFF0E1D2C3B4A59687
IV=FEDCBA9876543210FEDCBA9876543210
PT=4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F
PT='Now is the time for all good men to'
CIPHER_EncryptBytes returns 48
CT=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B
OK=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B

[New in v12.3] Use the API_IV_PREFIX option to prepend the IV to the ciphertext in the output.

CIPHER_EncryptBytes(API_IV_PREFIX) returns 64
IV||CT=FEDCBA9876543210FEDCBA9876543210C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B
       <------IV (16 bytes)-----------><--------CT (48 bytes)------------------------------------------------------------------------->

For another example of using API_IV_PREFIX see the second example in CIPHER_DecryptBytes.

Example (VBA wrapper function)

Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim dt() As Byte
Dim algstr As String

' PART 1
algstr = "Aes128/CBC/OneAndZeroes"
Debug.Print algstr
key = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
iv = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210")
' "Now is the time for all good men to"
pt = cnvBytesFromHexStr("4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F")

ct = cipherEncryptBytes(pt, key, iv, algstr)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
Debug.Print "OK=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B"

dt = cipherDecryptBytes(ct, key, iv, algstr)
Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'"

' PART 2 - Use CTR mode and prefix the IV in the output
algstr = "Aes128/CTR"
Debug.Print algstr & " + PREFIX"
ct = cipherEncryptBytes(pt, key, iv, algstr, API_IV_PREFIX)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
dt = cipherDecryptBytes(ct, key, iv, algstr, API_IV_PREFIX)
Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'"

' PART 3 - Use ECB mode and pass an empty byte array for the IV
algstr = "Aes128/ECB"
Debug.Print algstr
iv = vbNullString     ' Set IV as empty array
ct = cipherEncryptBytes(pt, key, iv, algstr)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
dt = cipherDecryptBytes(ct, key, iv, algstr)
Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'"

See Also

CIPHER_DecryptBytes

[Contents] [Index]

[PREV: CIPHER_DecryptHex...]   [Contents]   [Index]   
   [NEXT: CIPHER_EncryptBytes2...]

Copyright © 2001-24 D.I. Management Services Pty Ltd. All rights reserved. Generated 2024-01-07T07:42:00Z.