Encrypts a file using specified block cipher algorithm, mode and padding. The IV may be prepended to the file, if required.
Public Declare Function CIPHER_FileEncrypt Lib "diCryptoSys.dll"
(ByVal strFileOut As String, ByVal strFileIn As String,
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_FileEncrypt(strFileOut, strFileIn, abKey(0), nKeyLen,
abIV(0), nIvLen, strAlgModePad, nOptions)
long __stdcall CIPHER_FileEncrypt(const char *szFileOut, const char *szFileIn, const unsigned char *lpKey, long nKeyLen, const unsigned char *lpIV, long nIvLen, const char *szAlgModePad, long nOptions);
If successful, the return value is zero; otherwise it returns a nonzero error code.
static Cipher.file_encrypt(fileout, filein, key, iv, algmodepad='', alg=None, mode=Mode.ECB, pad=Pad.DEFAULT, opts=Opts.DEFAULT)
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 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. The output file szFileOut will be overwritten without warning. If there is an error, the output file will not exist. The input and output files must not be the same.
Prepended IV: If the API_IV_PREFIX option flag is set in nOptions then the IV will be
prepended (i.e. added) at the start of the output file.
That is, the output file will be of the form IV||ciphertext
.
The API_IV_PREFIX flag is ignored in ECB mode where an IV is not needed.
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"
.
Padding: In normal circumstances you should leave the padding unspecified and use the default padding when encrypting.
The only time it should be required is if you want to use an exotic padding like OneAndZeroesPadding
instead of pkcs5padding with ECB or CBC mode.
Note that, unlike the behaviour with CIPHER_EncryptBytes
,
it is an error (BAD_PARAM_ERROR
) to specify NoPadding when encrypting a file with ECB or CBC mode
under any circumstances.
The padding option is ignored for CTR, OFB and CFB modes; that is,
the default NoPadding is always used for these modes regardless of what is specified (so just use the default,
e.g. "aes128/ctr"
).
Dim abKey() As Byte Dim abIV() As Byte Dim nKeyLen As Long Dim nIvLen As Long Dim strFileEnc As String Dim strFileIn As String Dim strFileChk As String Dim strAlgModePad As String Dim nRet As Long ' Construct full path names to files strFileIn = "hello.txt" strFileEnc = "hello.aes192.enc.dat" strFileChk = "hello.aes192.chk.txt" ' Check input file Debug.Print "FileLen('" & strFileIn & "')=" & FileLen(strFileIn) ' Create the AES-192 key as an array of 24 bytes abKey = cnvBytesFromHexStr("fedcba9876543210fedcba98765432101122334455667788") nKeyLen = UBound(abKey) + 1 Debug.Print "KY=" & cnvHexStrFromBytes(abKey) Debug.Print "LEN(KY)=" & nKeyLen ' Create the IV at random ReDim abIV(API_BLK_AES_BYTES - 1) Call RNG_NonceData(abIV(0), API_BLK_AES_BYTES) ' Display the IV (this will be prepended to the ciphertext in the output file) Debug.Print "IV=" & cnvHexStrFromBytes(abIV) nIvLen = UBound(abIV) + 1 Debug.Print "LEN(IV)=" & nIvLen ' Specify cipher alg/mode/padding strAlgModePad = "aes192/CBC/ANSIX923" Debug.Print strAlgModePad ' Encrypt the plaintext file, prefixing the IV nRet = CIPHER_FileEncrypt(strFileEnc, strFileIn, abKey(0), nKeyLen, abIV(0), nIvLen, strAlgModePad, API_IV_PREFIX) Debug.Print "CIPHER_FileEncrypt() returns " & nRet & " (expected 0)" Debug.Assert (0 = nRet) ' Check output file Debug.Print "FileLen('" & strFileEnc & "')=" & FileLen(strFileEnc) ' Now decipher using the IV already prefixed to the ciphertext nRet = CIPHER_FileDecrypt(strFileChk, strFileEnc, abKey(0), nKeyLen, 0, 0, strAlgModePad, API_IV_PREFIX) Debug.Print "CIPHER_FileDecrypt() returns " & nRet & " (expected 0)" Debug.Assert (0 = nRet) ' Check decrypted file - it should match the original plaintext Debug.Print "FileLen('" & strFileChk & "')=" & FileLen(strFileChk) Debug.Assert (FileLen(strFileChk) = FileLen(strFileIn))
The input file is 13 bytes long ("hello world\r\n"
). This is padded to 16 bytes when encrypted in CBC mode.
The output file contains 16 bytes of ciphertext plus the prepended IV of 16 bytes,
so it is 32 bytes long.
FileLen('hello.txt')=13 KY=FEDCBA9876543210FEDCBA98765432101122334455667788 LEN(KY)=24 IV=ECD982FF61DDC6506828690D20B55BBE LEN(IV)=16 aes192/CBC/ANSIX923 CIPHER_FileEncrypt() returns 0 (expected 0) FileLen('hello.aes192.enc.dat')=32 CIPHER_FileDecrypt() returns 0 (expected 0) FileLen('hello.aes192.chk.txt')=13