Chapter 42
Encryption

[p]Lasso’s built-in encryption tags allow data to be stored or transmitted securely. [/p]

Overview

[p]Lasso provides a set of data encryption tags which support the most commonly used encryption and hash functions used on the Internet today. These encryption tags make it possible to interoperate with other systems that require encryption and to store data in a secure fashion in data sources or files. [/p]

[p]Lasso has built-in tags for the BlowFish encryption algorithm and for the SHA1 and MD5 hash algorithms. The new BlowFish2 algorithm is implemented in an industry standard fashion in order to allow values encrypted with Lasso to be decrypted by other BlowFish implementation or vice versa. (The original BlowFish algorithm is also provided for backward compatibility.) [/p]

[p]Lasso’s cipher tags provide access to a wide range of industry standard encryption algorithms. The [code][Cipher_List][/code] tag lists what algorithms are available and the [code][Cipher_Encrypt][/code], [code][Cipher_Decrypt][/code], and [code][Cipher_Digest][/code] tags allow values to be encrypted or decrypted or digest values to be generated. [/p]

[p]Finally, Lasso provides a set of tags to compress or decompress data for more efficient data transmission. [/p]

Encryption Tags

[p]LassoScript provides a number of tags which allow data to be encrypted for secure storage or transmission. Three different types of encryption are supplied. [/p]

  1. [note][b]Note: [/b]Lasso Professional 8 includes a new implementation of BlowFish which should be interoperable with most other products that support BlowFish. The new algorithm is implemented as [code][Encrypt_BlowFish2[/code]]. The older algorithm is still supported as [code][Encrypt_BlowFish] [/code]for backward compatibility. [/note]

Table 1: Encryption Tags

[table][tr][th]Tag[/th][th]Description[/th][th] [/th][/tr]

[tr][td][Encrypt_BlowFish2][/td][td]Encrypts a string using an industry standard BlowFish algorithm. Accepts two parameters, a string to be encrypted and a -Seed keyword with the key or password for the encryption. [/td][/tr]

[tr][td][Decrypt_BlowFish2][/td][td]Decrypts a string encrypted using the industry standard BlowFish algorithm. Accepts two parameters, a string to be decrypted and a -Seed keyword with the key or password for the decryption. [/td][/tr]

[tr][td][Encrypt_BlowFish][/td][td]Encrypts a string using the BlowFish implementation from earlier versions of Lasso. Accepts two parameters, a string to be encrypted and a -Seed keyword with the key or password for the encryption. [/td][/tr]

[tr][td][Decrypt_BlowFish][/td][td]Decrypts a string encrypted by the BlowFish implementation from earlier versions of Lasso. Accepts two parameters, a string to be decrypted and a -Seed keyword with the key or password for the decryption. [/td][/tr]

[tr][td][Encrypt_MD5][/td][td]Encrypts a string using the one-way MD5 hash algorithm. Accepts one parameter, a string to be encrypted. Returns a fixed size hash value in hexadecimal for the string which cannot be decrypted. [/td][/tr]

[tr][td][Encrypt_HMAC][/td][td]Generates a keyed hash message authentication code for a given input and password. The tag requires a -Password parameter which specifies the key for the hash and a -Token parameter which specifies the text message which is to be hashed. These parameters should be specified as a string or as a byte stream. The digest algorithm used for the hash can be specified using an optional -Digest parameter. The digest algorithm defaults to MD5. SHA1 is another common option. However, any of the digest algorithms returned by [Cipher_List: -Digest] can be used. The output is a byte stream by default. -Base64 specifies the output should be a Base64 encoded string. -Hex specifies the output should be a hex format string like 0x0123456789abcdef. -Cram specifies the output should be in a cram hex format like 0123456789ABCDEF. [/td][/tr]

[/table]

[note][b]Note: [/b]The BlowFish tags are not binary safe. The output of the tag will be truncated after the first null character. It is necessary to use [code][Encode_Base64][/code] or[code] [Encode_UTF8][/code] prior to encrypting data that might contain binary characters using these tags. [/note]

BlowFish Seeds

[p]BlowFish requires a seed in order to encrypt or decrypt a string. The same seed which was used to encrypt data using the [code][Encrypt_BlowFish2][/code] tag must be passed to the [code][Decrypt_BlowFish2][/code] tag to decrypt that data. If you lose the key used to encrypt data then the data will be essentially unrecoverable. [/p]

[p]Seeds can be any string between 4 characters and 112 characters long. Pick the longest string possible to ensure a secure encryption. Ideal seeds contain a mix of letters, digits, and punctuation. [/p]

[p]The security considerations of storing, transmitting, and hard coding seed values is beyond the scope of this manual. In the examples that follow, we present methodologies which are easy to use, but may not provide the highest level of security possible. You should consult a security expert if security is very important for your Web site. [/p]

[note][b]Note: [/b]The BlowFish algorithm will return random results if you attempt to decrypt data which was not actually encrypted using the same algorithm. [/note]

To store data securely in a database:

[p]Use the [code][Encrypt_BlowFish2][/code] and [code][Decrypt_BlowFish2][/code] tags to encrypt data which will be stored in a database and then to decrypt the data when it is retrieved from the database. [/p]

  1. Store the data to be encrypted into a string variable, [code]PlainText[/code].

[pre][Variable: 'PlainText' = 'The data to be encrypted.'] [/pre]

  1. Encrypt the data using the[code] [Encrypt_BlowFish2][/code] tag with a hard-coded [code]-Seed [/code]value. Store the result in the variable [code]CipherText[/code].

[pre][Variable: 'CipherText' = (Encrypt_BlowFish2: (Variable: 'PlainText'),
-Seed='This is the blowfish seed')] [/pre]

  1. Store the data in [code]CipherText [/code]in the database. The data will not be viewable without the seed. The following [code][Inline] … [/Inline] [/code]creates a new record in an [code]Contacts [/code]database for [code]John Doe [/code]with the [code]CipherText[/code].

[pre][Inline: -Add,
-Database='Contacts',
-Table='People',
-KeyField='ID',
'First_Name'='John',
'Last_Name'='Doe',
'CipherText'=(Variable: 'CipherText')]
[/Inline] [/pre]

  1. Retrieve the data from the database. The following [code][Inline] … [/Inline][/code] fetches the record from the database for [code]John Doe [/code]and places the [code]CipherText [/code]into a variable named [code]CipherText[/code].

[pre][Inline: -Search,
-Database='Contacts',
-Table='People',
-KeyField='ID',
'First_Name'='John',
'Last_Name'='Doe']
[Variable: 'CipherText' = (Field: 'CipherText')]
[/Inline] [/pre]

  1. Decrypt the data using the[code] [Decrypt_BlowFish2][/code] tag with the same hard-coded [code]-Seed [/code]value. Store the result in the variable [code]PlainText[/code].

[pre][Variable: 'PlainText' = (Decrypt_BlowFish2: (Variable: 'CipherText'),
-Seed='This is the blowfish seed')] [/pre]

  1. Display the new value stored in [code]PlainText[/code].

[pre][Variable: 'PlainText'] [/pre]

[pre] The data to be encrypted. [/pre]

[note][b]Note: [/b]This example uses the [code][Encrypt_BlowFish2][/code] and [code][Decrypt_BlowFish2][/code] tags. These are the preferred BlowFish implementation to use with Lasso. The [code][Encrypt_BlowFish][/code] and [code][Decrypt_BlowFish][/code] tags should only be used for interoperability with older versions of Lasso. [/note]

To store and check encrypted passwords:

[p]The [code][Encrypt_MD5][/code] tag can be used to store a secure version of a password for a site visitor. On every subsequent visit, the password given by the visitor is encrypted using the same tag and compared to the stored value. If they match, then the visitor has supplied the same password they initially supplied. [/p]

  1. When the visitor creates an account use [code][Encrypt_MD5][/code] to create an encrypted version—a fixed size hash value—of the password they supply. In the following example, the password they supply is stored in the variable [code]VisitorPassword [/code]and the encrypted version is stored in [code]SecurePassword[/code].

[pre][Variable: 'SecurePassword' = (Encrypt_MD5: (Variable: 'VisitorPassword'))] [/pre]

  1. Store this MD5 hash value for the password in a database along with the visitor’s username.
  1. On the next visit, prompt the visitor for their username and password. Fetch the record identified by the visitor’s specified username and retrieve the MD5 hash value stored in the field [code]SecurePassword[/code].
  1. Use [code][Encrypt_MD5][/code] to encrypt the password that the visitor has supplied and compare the result to the stored, encrypted MD5 hash value that was generated from the password they supplied when they created their account.

[pre][If: (Encrypt_MD5: (Variable: 'VisitorPassword')) == (Field: 'SecurePassword')]
Log in successful.
[Else]
Password does not match.
[/If] [/pre]

[note][b]Note: [/b]For more security, most log-in solutions require both a username and a password. The password is not checked unless the username matches first. This prevents site visitors from guessing passwords unless they know a valid username. Also, many log-in solutions restrict the number of login attempts that they will accept from a client’s IP address. [/note]

Cipher Tags

[p]Lasso includes a set of tags that allow access to a wide variety of encryption algorithms. These cipher tags provide implementations of many industry standard encryption methods and can be very useful when communicating using Internet protocols or communicating with legacy systems. [/p]

[p]The table below lists the [code][Cipher_…][/code] tags in Lasso. The following tables list several of the cipher algorithms and digest algorithms that can be used with the [code][Cipher_…] [/code]tags. The [code][Cipher_List][/code] tag can be used to list what algorithms are supported in a particular Lasso installation. [/p]

[note][b]Note: [/b]The actual list of supported algorithms may vary from Lasso installation to Lasso installation depending on platform and system version. The algorithms listed in this manual should be available on all systems, but other more esoteric algorithms may be available on some systems and not on others. [/note]

Table 2: Cipher Tags

[table][tr][th]Tag[/th][th]Description[/th][th] [/th][/tr]

[tr][td][Cipher_Encrypt][/td][td]Encrypts a string using a specified algorithm. Requires three parameters. The data to be encrypted, a -Cipher parameter specifying what algorithm to use, and a -Key parameter specifying the key for the algorithm. An optional -Seed parameter can be used to seed algorithms with a random component. [/td][/tr]

[tr][td][Cipher_Decypt][/td][td]Decrypts a string using a specified algorithm. Requires three parameters. The data to be decrypted, a -Cipher parameter specifying what algorithm to use, and a -Key parameter specifying the key for the algorithm. [/td][/tr]

[tr][td][Cipher_Digest][/td][td]Encrypts a string using a specified digest algorithm. Requires two parameters. The data to be encrypted and a -Digest parameter that specifies the algorithm to be used. Optional -Hex parameter encodes the result as a hexadecimal string. [/td][/tr]

[tr][td][Cipher_List][/td][td]Lists the algorithms that the cipher tags support. With a -Digest parameter returns only digest algorithms. With -SSL2 or -SSL3 returns only algorithms for that protocol. [/td][/tr]

[/table]

[p]The following two tables list some of the cipher algorithms that can be used with [code][Cipher_Encrypt][/code] and some of the digest algorithms that can be used with [code][Cipher_Digest][/code]. Use [code][Cipher_List][/code] for a full list of supported algorithms. [/p]

Table 3: Cipher Algorithms

[table][tr][th]Algorithm[/th][th]Description[/th][th] [/th][/tr]

[tr][td]AES[/td][td]Advanced Encryption Standard. A symmetric key encryption algorithm which is slated to be the replacement for DES. An implementation of the Rijndael algorithm. [/td][/tr]

[tr][td]DES[/td][td]Data Encryption Standard. A block cipher developed by IBM in 1977 and used as the government standard encryption algorithm for years. [/td][/tr]

[tr][td]3DES[/td][td]Triple DES. This algorithm uses the DES algorithm three times in succession with different keys. [/td][/tr]

[tr][td]RSA[/td][td]A public key algorithm named after Rivest, Shamir, and Adelmen. One of the most commonly used encyrption algorithsm. Note: Lasso does not generate public/private key pairs. [/td][/tr]

[/table]

Table 4: Digest Algorithms

[table][tr][th]Algorithm[/th][th]Description[/th][th] [/th][/tr]

[tr][td]DSA[/td][td]Digital Signature Algorithm. Part of the Digital Signature Standard. Can be used to sign messages, but not for general encryption. [/td][/tr]

[tr][td]SHA1[/td][td]Secure Hash Algorithm. Produces a 160-bit hash value. Used by DSA. [/td][/tr]

[tr][td]MD5[/td][td]Message Digest. A hash function that generates a 128-bit message digest. Replaces the MD4 and MD2 algorithms (which are also supported). Also implemented in Lasso as [code][Encrypt_MD5][/code]. [/td][/tr]

[/table]

To list all supported algorithms:

[p]Use the [code][Cipher_List][/code] tag. The following tag will return a list of all the cipher algorithms supported by Lasso [/p]

[pre][Cipher_List] [/pre]

[p]With a [code]-Digest[/code] parameter the tag will return a list of all the digest algorithms supported by Lasso. [/p]

[pre][Cipher_List: -Digest] [/pre]

To calculate a digest value:

[p]Use the [code][Cipher_Digest][/code] tag. The following tag will return the DSA signature for the value of a database field [code]Message[/code]. [/p]

[pre][Cipher_Digest: (Field: 'Message'), -Digest='DSA'] [/pre]

To encrypt a value using 3DES:

[p]Use the [code][Cipher_Encrypt][/code] tag. The following tag will return the 3DES encryption for the value of a database field [code]Message[/code]. [/p]

[pre][Cipher_Encrypt: (Field: 'Message'), -Cipher='3DES', -Key='My Secret Key'] [/pre]

Serialization Tags

[p]LassoScript provides several tags which allow Lasso’s native data types to be transformed into an XML data stream that can be stored in a database field, transmitted to a remote machine, or otherwise manipulated. The [code][Serialize][/code] and [code][Deserialize][/code] tags are equivalent to the [code][Null->Serialize][/code] and [code][Null->Deserialize][/code] tags which are documented in another chapter. [/p]

[note][b]Important: [/b]Built-in data types can be serialized and deserialized at any time. In order to deserialize a custom data type the data type must be defined in the current context. Custom data types defined in the Lasso startup folder or earlier on the page than the [code][Deserialize][/code] tag will work propery. [/note]

Table 5: Serialization Tags

[table][tr][th]Tag[/th][th]Description[/th][th] [/th][/tr]

[tr][td][Serialize][/td][td]Accepts a single parameter. Converts the parameter to a byte stream representation. The returned string can be stored in a database. [/td][/tr]

[tr][td][Deserialize][/td][td]Accepts a single parameter which is a byte stream that represents a Lasso value. Returns the value represented by the parameter. [/td][/tr]

[/table]

To store a complex data type:

[p]Use the [code][Serialize][/code] to transform the data type into a byte stream string representation that can be stored in a database field. Then use [code][Deserialize][/code] to transform the byte stream string representation back into the original data type. The following example shows how to convert an array into a string and then back again. [/p]

  1. Store the array in a variable [code]ArrayVariable[/code].

[pre][Variable: 'ArrayVariable'=(Array: 'one', 'two', 'three', 'four', 'five')] [/pre]

  1. Use the [code][Null->Serialize][/code] tag to change the array into a string stored in [code]TempVariable[/code].

[pre][Variable: 'TempVariable'=(Serialize: $ArrayVariable)] [/pre]

  1. The string representation of the array can now be changed back into the array by calling the [code][Deserialize][/code] tag with [code]TempVariable [/code]as a parameter.

[pre][Variable: 'ArrayVariable'=(Deserialize: $TempVariable)] [/pre]

  1. Finally, the original array is output.

[pre][Variable: 'ArrayVariable'] [/pre]

[pre] (Array: (one), (two), (three), (four), (five)) [/pre]

Compression Tags

[p]LassoScript provides two tags which allow data to be stored or transmitted more efficiently. The [code][Compress][/code] tag can be used to compress any text string into an efficient byte stream that can be stored in a text field in a database or transmitted to another server. The [code][Decompress][/code] tag can then be used to restore a compressed byte stream into the original string. [/p]

[p]The compression algorithm should only be used on large string values. For strings of less than one hundred characters the algorithm may actually result in a larger string than the source. [/p]

[p]These tags can be used in concert with the [code][Null->Serialize][/code] tag that creates a string representation of any data type in LassoScript and the [code][Null->Deserialize][/code] tag that returns the original value based on a string representation. An example below shows how to compress and decompress an array variable. [/p]

Table 6: Compression Tags

[table][tr][th]Tag[/th][th]Description[/th][th] [/th][/tr]

[tr][td][Compress][/td][td]Compresses a string parameter. [/td][/tr]

[tr][td][Decompress][/td][td]Decompresses a byte stream. [/td][/tr]

[/table]

To compress and decompress a string:

  1. Use the [code][Compress][/code] tag on the variable [code]InputVariable [/code]holding the string value you want to compress. The result is a byte stream that represents the string which is stored in [code]CompressedVariable[/code].

[pre][Variable: 'InputVariable'='This is the string to be compressed.']
[Variable: 'CompressedVariable'=(Compress: $InputVariable)] [/pre]

  1. The [code]CompressedVariable [/code]can now be decompressed using the[code] [Decompress][/code] tag. The result is stored in [code]OutputVariable [/code]and finally displayed.

[pre][Variable: 'OutputVariable'=(Decompress: $CompressedVariable)]
[Variable: 'OutputVariable'] [/pre]

[pre] This is the string to be compressed. [/pre]

To compress and decompress an array:

  1. Store the array in a variable [code]ArrayVariable[/code].

[pre][Variable: 'ArrayVariable'=(Array: 'one', 'two', 'three', 'four', 'five')] [/pre]

  1. Use the [code][Serialize][/code] tag to change the array into a string stored in [code]InputVariable[/code].

[pre][Variable: 'InputVariable'=(Serialize: $ArrayVariable)] [/pre]

  1. Use the [code][Compress][/code] tag on the variable [code]InputVariable [/code]holding the string representation for the array. The result is a byte stream which is stored in [code]CompressedVariable[/code].

[pre][Variable: 'CompressedVariable'=(Compress: $InputVariable)] [/pre]

  1. The [code]CompressedVariable [/code]can now be decompressed using the[code] [Decompress][/code] tag. The result is a string stored in [code]OutputVariable[/code].

[pre][Variable: 'OutputVariable'=(Decompress: $CompressedVariable)] [/pre]

  1. The string representation of the array can now be changed back into the array by calling the [code][Deserialize][/code] tag with [code]OutputVariable [/code]as a parameter.

[pre][Variable: 'ArrayVariable'=(Deserialize: $OutputVariable)] [/pre]

  1. Finally, the original array can be output.

[pre][Variable: 'ArrayVariable'] [/pre]

[pre] (Array: (one), (two), (three), (four), (five)) [/pre]