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

MembersDescription
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 StreamDescription
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 ObjectDescription
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

SystemMinimal versionRemarks
Palm OSPalm OS 3.0N/A