Home > Language Reference > Classes
StreamCipher Class
+ Object
+ Stream
+ StreamCipher
Description
The StreamCipher class allows on-the-fly data encoding and decoding. It is typically used to encrypt data being sent over a TCP/IP connection, or to decode mail attachments. This class is instantiable but neither derivable nor cloneable.
This class acts as a filter. To use its features, you simply have to initialize it with a source stream and an encoding/decoding scheme. Then, any data written to the StreamCipher object is encoded before being written to the source stream. Similarly, any data read from the StreamCipher object is read from the source stream and decoded before being returned:

The source stream should be specified before any input/output operation can take place, by affecting a reference to any valid data stream (including another StreamCipher object) to the Source property. Once the source stream is attached to the StreamCipher object, you should not read, write, or seek it directly. Apart from special cases, all operations must be issued through the StreamCipher object.
The encoding/decoding scheme should also be specified before any input/output operation can take place, by calling one of the initialization routines. The StreamCipher object currently supports five encoding formats, namely AES, Base64, RC4®, Deflate, and Inflate, which are respectively initialized by calling InitAES, InitBase64, InitRC4, InitZip and InitUnzip. It also supports fours schemes that does not perform any data transformation, but rather on-the-fly checksum computation. Adler32, CRC-16, CRC-32, and MD5 are currently available, through the InitAdler32, InitCrc16, InitCrc32 and InitMD5 methods.
The following example shows how to backup the Address database on an expansion card in an encrypted form using a StreamCipher object:
Private Sub Button1_Click() Dim v as New VFSVolume Dim f as New StreamFile Dim c as New StreamCipher Dim di as New DatabaseInfo v.FindFirstVolume f.Open v.Reference, "/AddressDB.dat", hbModeCreateAlways+hbModeReadWrite Set c.Source=f c.InitRC4 "My Private Key" di.FindByName "AddressDB" c.Write di c.Flush f.Close End Sub
The following example shows how to read the previously written file to restore the Address database:
Private Sub Button2_Click() Dim v as New VFSVolume Dim f as New StreamFile Dim c as New StreamCipher Dim di as New DatabaseInfo v.FindFirstVolume f.Open v.Reference, "/AddressDB.dat", hbModeOpenExisting+hbModeReadOnly Set c.Source=f c.InitRC4 "My Private Key" c.Read di f.Close End Sub
This class only uses one internal buffer, both for reading and writing. Therefore, it is not possible to use the same instance of a StreamCipher object to perform read and write operations simultaneously. Calling the Read function after a Write call was already issued on the same StreamCipher object (and conversely) raises a runtime error. Instead, you can create two instances and affect their respective Source properties the same source stream, or you can use the Flush method as described below.
Most encoding algorithms operates on blocks, since there is no one-to-one correspondance between raw and encoded data. For example, the Base64 algorithm needs 4 characters to be read before being able to decode 3 bytes. In this implementation, it also needs 54 bytes to be written before sending the encoded data to the source stream. Thus, the StreamCipher class provides the Flush method to synchronize these block operations.
When reading, it signals the beginning of a new block by resetting the decoding algorithm. You won't need to call this method unless you have to read raw data directly from the source stream, and then again read encoded data from the StreamCipher object. For example, you might have a TCP/IP client application where some parts of the communication protocol are encrypted and some others not:
Private sSock As New StreamSocket Private sCipher As New StreamCipher Private Sub Init() sSock.Connect "MyUrl", MyPort Set sCipher.Source = sSock sCipher.InitRC4 "My Private Key" End Sub Private Sub ReadCommand() Dim cmd As Long Dim param As String sSock.Read cmd ' Read a command code directly from the socket sCipher.Flush ' Re-synchronize after direct reading sCipher.Read param ' Read an encrypted string from the socket ' Use cmd and param ... End Sub
When writing, it indicates that no more data will be written, and flushes any pending encoded bytes to the source stream. For some encoding schemes, this method also writes any necessary termination character. For example, Base64 uses an equal sign (=) to signal the end of the stream. Not all encoding schemes need this method to be called for proper operation, however it is a good programming practice to always call it when you are done with a stream.
After the Flush method was called, the object is restored to its initial state: all internal buffers are empty, and the encoding/decoding algorithm is reset. Therefore, you can again indifferently perform either read or write operations.
Also due to block operation, the StreamCipher object does not support seeking. Calling one of the Seek, SeekToBegin, SeekToEnd, Position, or Size methods and properties raises a runtime error.
Important note
When using encryption algorithms, you must always keep in mind that the Palm OS® platform is not secure. There is no way to safely encrypt and store databases, for example. Unlike desktop computer operating systems, Palm OS® does not provide any way to protect neither your application nor its data against other applications. This results in a serious lack of security. The following examples illustrates this.
On the other hand, data encryption is secure as long as a third party cannot access both your data and your application. Typically, this applies to most communication channels, or to removable storage units. For example, one could easily intercept a file on the internet, but decrypting it without any knowledge of the application that wrote it would be extremely difficult, provided that the encryption algorithm is robust enough.
Thus, the StreamCipher object should only be used to encrypt data before they are sent to an external media, such as the Internet or an expansion card, and not to protect data on the device itself.
Members
| Members | Description |
| Digest | Returns a checksum or a message digest. |
| Flush | Flushes all internal buffers and resets the encoding/decoding algorithm. |
| InitAdler32 | Sets the encoding/decoding scheme to Adler32. |
| InitAES | Sets the encoding/decoding scheme to AES. |
| InitBase64 | Sets the encoding/decoding scheme to Base64. |
| InitCrc16 | Sets the encoding/decoding scheme to CRC-16. |
| InitCrc32 | Sets the encoding/decoding scheme to CRC-32. |
| InitMD5 | Sets the encoding/decoding scheme to MD5. |
| InitRC4 | Sets the encoding/decoding scheme to RC4. |
| InitUnzip | Sets the encoding/decoding scheme to Inflate. |
| InitZip | Sets the encoding/decoding scheme to Deflate. |
| Source | Source stream. |
| Inherited from Stream | Description |
| Position | Stream pointer position. |
| Read | Reads data from a stream. |
| Seek | Moves the stream pointer. |
| SeekToBegin | Moves the pointer to the beginning of the stream. |
| SeekToEnd | Moves the pointer to the end of the stream. |
| Size | Total size of the data in a stream. |
| Write | Writes data to a stream. |
| Inherited from Object | Description |
| ClassID | Returns the type identifier corresponding to the actual class of the object. |
| Implements | Determines whether the object implements the features of a given class. |
| Iterate | Event raised to iterate over the elements of a container object. |
| Recipient | Recipient of events sent by the object. |
| Serialize | Event raised to serialize the object content into a stream. |
System requirements
| System | Minimal version | Remarks |
| Palm OS | Palm OS 3.0 | N/A |