[Page Banner Image]

DESCrypt.lib

DES encryption for your Clipper applications. Will only be delivered to US addresses. The most secure encryption available for your Clipper application. Works with Summer 87 through 5.2E. Please read the following before ordering. DEScrypt works exactly as described, which may be far from what you need.  It is not generally suitable for encrypting databases. DES requires that you keep the whole encrypted string returned by it's encryption functions.  That string will ALWAYS be a multiple of 8 characters long which means if you encrypt a 27 character field in a database and store the result back into that 27 character field you will have lost your data. In order to successfully encrypt and then decrypt that field you will have to make it 32 characters long.

Introduction

DESCRYPT is a data encryption library that uses the Federal Information
Processing Standard Data Encryption Algorithm (FIPS DEA), more commonly
known as DES.

DES is an extremely secure encryption algorithm. Its design is such
that knowing the algorithm does not help in 'breaking' an encrypted
message. Only knowing or finding the key will make that possible. The
algorithm itself is public information.


DES Operations

The fundamental DES algorithm works on blocks of 64 bits, using a
56-bit key. The key is contained in another 64-bit block, with one bit
out of every eight being ignored (viz. for a parity bit in a seven-bit
ASCII character). In this implementation, it is the high-order bit of
each byte that is ignored.

Since DES works on eight-byte blocks, any variable-length data
encrypted with DESCRYPT will be padded to a multiple of eight bytes
with zero (NUL) characters. If you need to retrieve the exact length,
store some extra data. One approach is to add the length onto the
beginning of a string with i2bin(), and retrieve it with bin2w().
Another is to add a non-NUL character on the end of the string. Since
the padding at the end will always be NULs, the last non-NUL will be
the end mark. Of course, if the data cannot contain NULs, you can just
strip the NULs off of the end.

Although eight characters of key are enough for DES to provide security,
there is some risk that a password may be guessed if it is too short.
Longer passwords can be allowed by making multiple encryption passes,
using a different substring of the password for the key on each pass.

DESCRYPT supports two methods of operation for encrypting strings:
Electronic Code Book (ECB), and Cipher Block Chaining (CBC). In ECB,
each eight-byte block of the string is encrypted separately using the
same key. With this method, large blocks of repeated data (like spaces
or zeros) will produce repeated eight-byte patterns in the output, with
some risk that the patterns will give an 'enemy' a clue as to the
nature of the data. CBC reduces this risk. It requires an eight-byte
initialization vector which is exclusive-ored with the first data block
before encryption. The encrypted first block is exclusive-ored with
the second data block before encryption, and so on for subsequent
blocks. CBC output shows no large-scale patterns.


Function Reference

EncryptBlk()

ciphertext := EncryptBlk(plaintext, key)

Encrypts a single eight-byte data block. The plaintext is
truncated to eight bytes, or padded with 0 (NUL) bytes if it is
shorter. The key is also truncated or padded to eight bytes. The
result is always exactly eight bytes in length.

DecryptBlk()

plaintext := DecryptBlk(ciphertext, key)

Decrypts a single eight-byte block. This is the complement of
EncryptBlk(). Both ciphertext and key are truncated or padded as
decribed above, though if the ciphertext is not exactly eight
bytes you have probably done something wrong and will not get the
desired result.

EncryptStr()

ciphertext := EncryptStr(plaintext, key, [iv])

Encrypts a string of any length. The key is truncated or padded
to eight bytes, and the plaintext is padded with 0 bytes to a
multiple of eight bytes. The result is always a multiple of eight
bytes in length.

If the initialization vector 'iv' is supplied, it should be a
string of up to eight characters which will be used for Cipher
Block Chaining. If 'iv' is omitted, EncryptStr() works in
Electronic Code Book mode.

DecryptStr()

plaintext := DecryptStr(ciphertext, key, [iv])

Decrypt a string. This is the complement of EncryptStr(). The
key and ciphertext are padded as described above, though as for
DecryptBlk(), if the ciphertext was not a multiple of eight bytes
to start with, you've probably done something wrong. The result
may have up to seven 0 bytes on the end which were added by
EncryptStr().

As with EncryptStr(), 'iv' is the initialization vector for Cipher
Block Chaining. Without 'iv', DecryptStr() works in Electronic
Code Book mode.

Password()

ciphertext := Password(key)

This is a one-way encryption function. It truncates or pads the
key to eight bytes, then uses the result to encrypt a block of
eight 0 bytes, then encrypt the result again and again, for a
total of 16 passes. Given the ciphertext, there is no known way
to reconstruct the key.

This function is useful for password validation. Rather than
storing a plaintext password, store only the encrypted version.
To check a password later, encrypt it and see if the result is the
same as the stored version. Also useful for checking whether a
key is correct before decrypting text: store the one-way encrypted
key along with the text, then use this method to check the key for
validity.

Encode224()

codestring := Encode224(string)

DES encrypted data may contain data with any byte values from 0 to
255. Such data cannot be stored in Clipper memo fields. This
function converts a data string into one containing only values
from 32 to 255, expanding it by about 15% in the process. The
result can be passed through Decode224() to retrieve the original
data.

Decode224()

string := Decode224(codestring)

Reverses the conversion performed by Encode224().


Notes on Security
----- -- --------

In theory, a DES-encrypted message is safe as long as the key is
secure. In practice, there are usually easier ways to break encrypted
data than by attacking the algorithm itself.

In many cases, passwords can be guessed. This can be done by computer,
with the aid of an on-line dictionary, or simply by trying likely
words. When computer users are allowed to choose their own passwords,
many will pick their own names, or a spouse' or child's, or other
obvious alternatives. To avoid this, some systems require passwords to
be of some minimum length, and contain a number of non-alphanumeric
characters. (Although DES works with eight-byte keys, you can make
several passes to allow longer keys.)

The most secure kind of password is one generated at random by the
computer (as long as the generator is random enough and not flawed).
However, random passwords are hard to remember and users have to write
them down, giving another opportunity for them to be discovered.

A clever hacker may be able to avoid your encryption altogether if he
can locate the original, unencrypted data. This might exist in memory
before or after an encryption run and be available to a debugger, or in
files on disk, or in erased but recoverable space on disk. Plaintext
moved over networks or modems is at least theoretically susceptible to
interception or eavesdropping, as are passwords.

A typical and unfortunately common mistake along these lines is to
write code like this:

accept "Password: " to password
if password == decrypt(encryptedPassword)
// Password is okay...
endif

The correct password has been stored encrypted, which is correct, but
at the point where it is decrypted for comparison with the input, it
exists in memory as plaintext. Anybody reasonably handy with a
debugger can then find it. A better approach is:

if encrypt(password) == encryptedPassword

This is why DESCRYPT's Password() function works one way only.

Finally, for completeness, I'll mention a persistent rumor in the UNIX
network community that the National Security Agency intentionally
'weakened' DES before it was published, to make it possible for NSA
computers to break.


References

Cryptography: A Guide for the Design and Implementation of Secure
Systems. Carl H. Meyer and Stephen M. Mattas. John Wiley & Sons,
1982. ISBN 0-471-04892-5.

Federal Information Processing Standard Publication 46 (FIPS PUB 46),
Data Encryption Algorithm. National Technical Information Service,
U.S. Department of Commerce.

ANSI X3.92, Data Encryption Algorithm. American National Standards
Institute. This is FIPS PUB 46 recast as an ANSI standard.

ANSI X3.105, Data Link Encryption. American National Standards
Institute. Describes modes for the use of the DEA over communication
links.

ANSI X3.106, Data Encryption Algorithm - Modes of Operation. American
National Standards Institute. Describes modes for enhancing the
security of the DEA when encrypting large blocks of data.