The Blowfish Encryption Object

Index

Disclaimer

This object uses the Blowfish encryption algorithm. Please check with your local laws concerning encryption and exportation before offering, or selling, any encryption tools for public or for private use. The laws concerning the strength and type of encryption used vary, and you may be subject to restrictions and even criminal penalties for failure to comply.

The author of this extension makes no claims concerning the fitness of this extension for any purpose whatsoever, and makes no guarantees, written or implied, of its level of security and safety to authors or to end users in any respect. You agree to use this extension at your own risk and to hold the author harmless in any event.

Upgrading to Version 1.06

Version 1.06 has some new functionality that may slightly alter applications made with older versions.

Reverse Bytes Mode is used as the default setting for NEW Blowfish objects added to a frame. Old objects will continue to use the old mode. Reverse Bytes Mode reverses the bytes of data before and after encryption or decryption. This should make the Blowfish object compatible with other implementations of Blowfish. If a file is encrypted with Reverse Bytes Mode enabled, it must be decrypted with it enabled. If it was encrypted with the mode disabled, it must be decrypted with the mode disabled.

The file handling routines have been rewritten. In older versions, the whole file was loaded into memory, processed, and then written back to file. This meant that there was some lag right when the action was called on bigger files. In version 1.06, files are loaded in chunks, so there is no more lag for bigger files. It also means that if your application terminates before work is done (and if you were overwriting a file), the file will be left in an intermediate state, which is not good. The new file handling routines can now support larger files. The old "Get File Size" expression will not work on these larger files and should be avoided if possible. Use "Get File Size as Float" or "Get File Size as String" instead.

Checks on the length of a key are now only performed when a new key is added or when a random key is being created.

New cipher block modes have been added to the object. The old versions implicitly used the electronic codebook (ECB) cipher block mode.

The Basics

The Blowfish Encryption Object serves basically one purpose: data encryption. Given this object's nature, all of its data is global. That means that any encryption keys you add on one frame will be available on all subsequent frames and sub-applications. To use this object, simply add a key (you must add a key before using it!). Then use that key to encrypt a string, an integer, or a floating point number*. You can then send this data to a web server or to another application and decrypt it there.
*You cannot directly encrypt floats. You must first convert them to integers. Then encrypt them, decrypt them, and then convert them back to floats. You must do this because MMF will sometimes round floats, causing huge problems when encrypting and decrypting floats directly.

Because Blowfish is a binary encryption algorithm, if you encrypt a string using it, often times the algorithm will create characters that cannot be displayed. To handle this, the object allows for strings to inputted or outputted in different formats (discussed below). After encryption, you can safely display or send the string (that has been filtered or converted to hex) to another application that can decrypt the string. NOTE: In order to decrypt a string, you DO NOT need to have the same filter characters as the application that encrypted the string.

Block cipher modes tell the object how to encrypt strings and files and are not used when encrypting integers. If you encrypt data using a block cipher mode with a particular IV, the data must be decrypted using that some mode and IV.

Formats

Some expressions or actions allow you to specify the format of some arguments or of the output of an expression. These formats are specified by number:
0) Raw string: The string is to be used as-is. No formatting is used.
1) Filtered string: The string is normal except that certain characters are converted to %xx, where xx is the code of the character in hexadecimal. When used as input, a filtered string may have any character written as %xx or it may have only the two mandatory characters written as %xx (the % character and the NULL character must always be filtered). When used as output, the characters specified in your filter settings will be converted to %xx. NOTE: While you can remove the % and NULL characters from your filter list, you probably shouldn't do that.
3) Hex string: The string is written as a series of hexadecimal digits (0-9 and A-F). These strings should always contain an even number of characters as two hex digits equates to one byte of data. If an odd number of characters is used, the last character will be treated as if a 0 were in front of it.

NOTE: In previous version of the Blowfish object, padding never manifested in strings as decrypting strings was always done to a raw string where extra NULL characters were ignored. When decrypting to filtered or hex strings, padding becomes visible as either %00s or 00s added to the end of the decrypted string.

Files

When you use an Encrypt or Decrypt a file action, this is what happens:

  1. The object makes sure the specified key exists. If not, an error is generated. The action is finished.
  2. The object makes sure no files are currently being worked with (being encrypted or decrypted). If there is, an error is generated. The action is finished.
  3. If there was no error, the object begins loading the file into memory. If the object is unable to open the file(s), an error is generated. The action is finished.
  4. If there is a File Work Time and/or File Work Percentage Interval that is enabled, the action is finished. The file will start being encrypted or decrypted at the end of current program loop. If there is only a File Work Time interval enabled, the file will be worked with for the specified amount of time each program loop. If there is only a File Work Percentage Interval enabled, the file will be worked with until the specified percentage of its total size is completed per loop. For example, if the File Work Percentage Interval is 25, 25% of the file is loaded per loop. If both are enabled, the file is worked with until the first one occurs. If the file is worked with for either the specified amount of time or for the specified percentage, whichever happens first.
  5. If there is no File Work Time nor File Work Percentage Interval that is enabled, the entire file is completed.
  6. When the file is finished, a "File is Done" event is generated (this occurs whether or not the file is completed during the action).
  7. The action is finished.

NOTE: If your application terminates before a file is finished being encrypted/decrypted (and if you were overwriting a file), it will be left in an intermediate state, which is not good. You should not exit your application before work on a file is complete.

Conditions

Is Filtering of Characters with Codes 0 to 31 Enabled?
This condition returns true if "Filtering of Characters with Codes 0 to 31" is enabled.

Is Set to Pad End of Files with Zeros?
This condition returns true if the object is "Set to Pad End of Files with Zeros".

Is Reverse Bytes Mode Enabled?
This condition returns true if the object is set to "Reverse Bytes Mode" is enabled.

Does a Specific Key Exist?
This condition returns true if the specified key exists.

Is File Being Encrypted/Decrypted?
This condition returns true if a file is currently being encrypted or decrypted.

Has File Finished Being Encrypted/Decrypted?
This condition is a true event condition. That means that events having this condition will be executed as soon as a file is done being encrypted or decrypted.

Is a Specific Character Being Filtered?
This condition returns true if the specified character is set to be filtered.

Is a Specific Character (by Code) Being Filtered?
This condition returns true if the specified character (specified by its ASCII code) is set to be filtered.

Has an Error Occurred?
This condition is a true event condition. That means that events having this condition will be executed as soon as an error is encountered in an ACTION or CONDITION by the Blowfish Object (and only when an error is encountered). It will return true when the Error Number is greater than 0, which will always be the case when an error is encountered.

Actions

Enable Filtering of Characters with Codes 0 to 31
This action enables "Filtering of Characters with Codes 0 to 31". When enabled, you will not be able to add or remove characters in this range.

Disable Filtering of Characters with Codes 0 to 31
This action disables "Filtering of Characters with Codes 0 to 31". This action automatically adds the NULL character (code 0) to your filter list.

Pad End of Files with Zeros
If a cipher block mode requires a file size to be a multiple of 8, this action sets the object to pad the ends of files with zeros if the file size is not a multiple of 8. This is harmless to text files, but might cause problems for binary files.

Do not Pad End of Files with Zeros
If a cipher block mode requires a file size to be a multiple of 8, this action sets the object to not pad the ends of files with zeros if the file size is not a multiple of 8. Instead, the tail end of the file (no more than 7 bytes) is left alone. That is, it is not encrypted or decrypted.

Enable Reverse Bytes Mode
This enables Reverse Bytes Mode. Reverse Bytes Mode reverses the bytes of data before and after encryption or decryption. This should make the Blowfish object compatible with other implementations of Blowfish. If a file is encrypted with Reverse Bytes Mode enabled, it must be decrypted with it enabled. If it was encrypted with the mode disabled, it must be decrypted with the mode disabled.

Disable Reverse Bytes Mode
This disables Reverse Bytes Mode.

Set Block Cipher Mode to ECB
This sets the block cipher mode to electronic codebook (ECB) mode. In ECB, each block of 8 bytes of data is encrypted or decrypted in isolation. ECB requires that the size of data being encrypted is a multiple of 8.

Set Block Cipher Mode to CBC
This sets the block cipher mode to cipher-block chaining (CBC) mode. In CBC, an initialization vector (IV) of 8 bytes is required. If the specified IV is too long it is truncated. If it is too short, it is padded with NULL bytes. In either case, an error is generated. If the IV is specified as "", the IV is not changed. When encrypting in CBC, each block of data is XORed with the encrypted data of the previous block (or with the IV if this is the first block of data). CBC requires that the size of data being encrypted is a multiple of 8.

Set Block Cipher Mode to CFB
This sets the block cipher mode to cipher feedback (CFB) mode. In CFB, an initialization vector (IV) of 8 bytes is required. If the specified IV is too long it is truncated. If it is too short, it is padded with NULL bytes. In either case, an error is generated. If the IV is specified as "", the IV is not changed. When encrypting in CFB, the encrypted data of the previous block (or the IV if this is the first block) is encrypted and XORed with the current block of data. CFB does NOT require the size of data being encrypted to be a multiple of 8. Padding is never done in this mode.

Set Block Cipher Mode to OFB
This sets the block cipher mode to output feedback (OFB) mode. In OFB, an initialization vector (IV) of 8 bytes is required. If the specified IV is too long it is truncated. If it is too short, it is padded with NULL bytes. In either case, an error is generated. If the IV is specified as "", the IV is not changed. When encrypting in OFB, the IV is encrypted over and over. Each block of data is XORed with the corresponding encryption of the IV. OFB does NOT require the size of data being encrypted to be a multiple of 8. Padding is never done in this mode. Interestingly, OFB encryption and decryption are identical.

Add an Encryption Key
This action adds the specified encryption key to the list of keys. It prepares the key for use in encryption. If this key is longer than 56 characters, it is truncated and an error is generated. You can access this key by name (case-sensitive) when you wish to encrypt something. You must add a key before attempting to use it!

Add an Encryption Key (Advanced)
This action adds the specified encryption key to the list of keys. It prepares the key for use in encryption. If this key is longer than 56 characters, it is truncated and an error is generated. You must add a key before attempting to use it! The advanced action allows you to specify a format for the key. It also allows the use of an alias. If left blank (""), no alias is used. When an alias is specified, they key MUST be referred to be its alias in all actions and expressions that require keys.

Remove an Encryption Key
This action removes the specified encryption key from the list of keys.

Encrypt a File
This action encrypts the specified file using the specified key (the key must be added before it can be used here). If the file size is not a multiple of 8 (and if the current block cipher mode requires it), zeros are appended to make it that way if the object is set to pad with zeros (if this will cause problems with your file, take measures to ensure its size is a multiple of 8). Otherwise, the tail end of the file (no more than 7 bytes) are left unencrypted. NOTE: Files are not filtered.

Encrypt a File to a New File
This action encrypts the specified file using the specified key (the key must be added before it can be used here) and writes it to a new file. You should not specify the same file for input and output as this will destroy the file. The object does a simple string comparison of the files and generates an error if they are the same, but, given the complexity of file paths, this check will not catch all instances of identical files. If the file size is not a multiple of 8 (and if the current block cipher mode requires it), zeros are appended to make it that way if the object is set to pad with zeros (if this will cause problems with your file, take measures to ensure its size is a multiple of 8). Otherwise, the tail end of the file (no more than 7 bytes) are left unencrypted. NOTE: Files are not filtered.

Decrypt a File
This action decrypts the specified file using the specified key (the key must be added before it can be used here). If the file size is not a multiple of 8 (and if the current block cipher mode requires it), zeros are appended to make it that way if the object is set to pad with zeros. Otherwise, the tail end of the file (no more than 7 bytes) are left undecrypted. NOTE: Files are not filtered.

Decrypt a File to a New File
This action decrypts the specified file using the specified key (the key must be added before it can be used here) and writes it to a new file. You should not specify the same file for input and output as this will destroy the file. The object does a simple string comparison of the files and generates an error if they are the same, but, given the complexity of file paths, this check will not catch all instances of identical files. If the file size is not a multiple of 8 (and if the current block cipher mode requires it), zeros are appended to make it that way if the object is set to pad with zeros (if this will cause problems with your file, take measures to ensure its size is a multiple of 8). Otherwise, the tail end of the file (no more than 7 bytes) are left undecrypted. NOTE: Files are not filtered.

Set File Work Time Interval
This action sets the file work time interval to the specified time in milliseconds. If this value is less than or equal to 0, this option is disabled.

Set File Work Percentage Interval
This action sets the file work percentage interval to the specified percentage (0-100). If this value is less than or equal to 0 or if it is greater than or equal to 100, this option is disabled.

Add Characters to Filter
This action adds all specified characters to the list of characters to be filtered. Filtered characters are converted to %xx, where xx is the code of the character in hexadecimal, when a string is encrypted. They are converted back when decrypted.

Add a Character to Filter by Code
This action adds a character specified by its ASCII code to the list of characters to be filtered. Filtered characters are converted to %xx, where xx is the code of the character in hexadecimal, when a string is encrypted. They are converted back when decrypted.

Remove Characters from Filter
This action removes all specified characters from the list of characters to be filtered.

Remove a Character from Filter by Code
This action removes a character specified by its ASCII code from the list of characters to be filtered.

Clear Expression Error Code
This action sets the expression error code to 0.

Expressions

Get Block Cipher Mode
CipherBlockMode$(ObjectName)
This expression returns the current block cipher mode. The possible results are "ECB", "CBC", "CFB", and "OFB".

Get Initialization Vector
IV$(ObjectName, Format)
This expressions returns the current initialization vector in the specified Format.

Create a Random Key
RandomKey$(ObjectName, Length)
This expression creates a random key of the specified length. If the length is greater than 56, it is truncated and an error is generated. This key is NOT filtered and may contain line breaks and unreadable characters. Do not store it in an editbox. Store it in a string object so that it can be used later to decrypt. If you need to send it to another application, make sure you filter it before sending.

Convert a Float to an Integer
ConvertToInteger(ObjectName, Float)
This expression converts the specified float into an integer so that it can be encrypted in the "Encrypt an Integer" expression.

Convert an Integer Back to a Float
ConvertToFloat(ObjectName, Integer)
This expression converts the specified integer back into a float. You should use this if you used "Convert a Float to an Integer" to encrypt a float.

Encrypt an Integer
EncryptInteger(ObjectName, Key, Integer1, Integer2, Select)
This expression returns the encrypted integer based on Select. It encrypts using Key (the key must be added before it can be used here). If Key does not exist an error is generated and the un-encrypted version is returned. If Select is 2, the encrypted form of Integer2 is returned. Otherwise, the encrypted form of Integer1 is returned. You need both encrypted integers to decrypt either of these. The reason you need two integers at all is because Blowfish encrypts in chunks of 8 bytes. Two integers are exactly 8 bytes.

Encrypt a String
EncryptString$(ObjectName, Key, String)
This expression returns the encrypted string. It encrypts using Key (the key must be added before it can be used here). If Key does not exist an error is generated and the un-encrypted version is returned. If the current cipher block mode requires it, the string is harmlessly padded with NULL characters to ensure that it is a multiple of 8 characters long. If any filter characters appear in the encrypted string, they are replaced by %xx, where xx is the ASCII code of the character in hexadecimal.

Encrypt a String (Advanced)
EncryptStringAdv$(ObjectName, Key, String, InputFormat, OutputFormat)
This expression returns the encrypted string. It encrypts using Key (the key must be added before it can be used here). If Key does not exist an error is generated and the un-encrypted version is returned. If the current cipher block mode requires it, the string is padded with NULL characters to ensure that it is a multiple of 8 characters long. InputFormat specifies the format of String. OutputFormat specifies how the encrypted data should be formatted (raw string is not recommended as NULL characters can prematurely truncate the output).

Decrypt an Integer
DecryptInteger(ObjectName, Key, Integer1, Integer2, Select)
This expression returns the decrypted integer based on Select. It decrypts using Key (the key must be added before it can be used here). If Key does not exist an error is generated and the un-decrypted version is returned. If Select is 2, the decrypted form of Integer2 is returned. Otherwise, the decrypted form of Integer1 is returned. The integers need to be in the same order as when they were encrypted. The reason you need two integers at all is because Blowfish decrypts in chunks of 8 bytes. Two integers are exactly 8 bytes.

Decrypt a String
DecryptString$(ObjectName, Key, String)
This expression returns the decrypted string. It decrypts using Key (the key must be added before it can be used here). If Key does not exist an error is generated and the un-decrypted version is returned. If the current cipher block mode requires it, the string is padded with NULL characters to ensure that it is a multiple of 8 characters long. If any %xx appear in the encrypted string, they are replaced by the proper characters before the string is decrypted.

Decrypt a String (Advanced)
DecryptStringAdv$(ObjectName, Key, String, InputFormat, OutputFormat)
This expression returns the decrypted string. It decrypts using Key (the key must be added before it can be used here). If Key does not exist an error is generated and the un-encrypted version is returned. If the current cipher block mode requires it, the string is padded with NULL characters to ensure that it is a multiple of 8 characters long. InputFormat specifies the format of String. OutputFormat specifies how the decrypted data should be formatted.

Get File Work Time Interval
FileTimeInterval(ObjectName)
This expression returns the current file work time interval.

Get File Work Percentage Interval
FilePercentageInterval(ObjectName)
This expression returns the current file work percentage interval.

Get File Size
FileSize(ObjectName)
This expression returns the file size of the last file successfully loaded. If the file size is too large, this will return an invalid file size. As such, this expression should be avoided.

Get File Size as Float
FileSizeF(ObjectName)
This expression returns the file size of the last file successfully loaded as a floating point number. This loses some accuracy in the size but allows for the support of larger file sizes.

Get File Size as String
FileSize$(ObjectName)
This expression returns the file size of the last file successfully loaded as a string..

Get File Work Progress
FileProgress(ObjectName)
This expression returns the current progress of encrypting or decrypting a file. It returns this as a percentage.

Filter a String
FilterString$(ObjectName, String)
This expression returns the string with any filter characters replaced by %xx, where xx is the ASCII code of the character in hexadecimal.

Defilter a String
DefilterString$(ObjectName, String)
This expression returns the string with any %xx replaced by the proper characters.

Convert String to Hex
StringToHex$(ObjectName, String)
This expression converts String into a string of hexadecimal digits (0-9 and A-F).

Convert Hex to String
HexToString$(ObjectName, String)
This expression converts a string of hexadecimal digits into a raw string. If the number of hexadecimal digits is not even, the final digit is treated as if it comes after a 0.

Convert from One String Format to Another
ConvertString$(ObjectName, String, InputFormat, OutputFormat)
This expression converts a string given in InputFormat to OutputFormat. See the section on formats.

Get Current Error Code
ErrorCode(ObjectName)
This expression returns the current error code. This is only useful when used with an "Has an Error Occurred?" condition.
Error Codes:
1) Key exceeds 56 characters and has been truncated.
2) Key not found
3) Key already exists
4) Character not found in filter list
5) Invalid character code
6) Error opening or reading from file
7) Error saving or writing to file
8) Cannot encrypt/decrypt file while already working with a file
9) Cannot remove key while working with a file
10) Cannot work with files in Vitalize
11) Initialization Vector must be 8 bytes long. Shorter IVs are padded with 0s. Longer IVs are truncated.

Get Current Expression Error Code
ExpressionErrorCode(ObjectName)
This expression returns the current expression error code. See "Get Current Error Code" for list of error codes.