Computes a binary hash of the given data. type is the
algorithm to use. Standard algorithms are md5, sha1, sha224, sha256,
sha384 and sha512. If pgcrypto
was built with OpenSSL, more algorithms are available, as
detailed in Table
F-18.

If you want the digest as a hexadecimal string, use
encode() on the result. For
example:

Calculates a crypt(3)-style hash of password. When storing a new password, you
need to use gen_salt() to
generate a new salt value. To
check a password, pass the stored hash value as salt, and test whether the result matches
the stored value.

The iter_count parameter lets
the user specify the iteration count, for algorithms that
have one. The higher the count, the more time it takes to
hash the password and therefore the more time to break it.
Although with too high a count the time to calculate a hash
may be several years — which is somewhat impractical. If the
iter_count parameter is omitted,
the default iteration count is used. Allowed values for
iter_count depend on the algorithm
and are shown in Table F-16.

Table F-16. Iteration Counts for crypt()

Algorithm

Default

Min

Max

xdes

725

1

16777215

bf

6

4

31

For xdes there is an additional
limitation that the iteration count must be an odd
number.

To pick an appropriate iteration count, consider that the
original DES crypt was designed to have the speed of 4 hashes
per second on the hardware of that time. Slower than 4 hashes
per second would probably dampen usability. Faster than 100
hashes per second is probably too fast.

Table
F-17 gives an overview of the relative slowness of
different hashing algorithms. The table shows how much time
it would take to try all combinations of characters in an
8-character password, assuming that the password contains
either only lower case letters, or upper- and lower-case
letters and numbers. In the crypt-bf
entries, the number after a slash is the iter_count parameter of gen_salt.

Table F-17. Hash Algorithm Speeds

Algorithm

Hashes/sec

For [a-z]

For [A-Za-z0-9]

crypt-bf/8

28

246 years

251322 years

crypt-bf/7

57

121 years

123457 years

crypt-bf/6

112

62 years

62831 years

crypt-bf/5

211

33 years

33351 years

crypt-md5

2681

2.6 years

2625 years

crypt-des

362837

7 days

19 years

sha1

590223

4 days

12 years

md5

2345086

1 day

3 years

Notes:

The machine used is a 1.5GHz Pentium 4.

crypt-des and crypt-md5 algorithm numbers are taken from
John the Ripper v1.6.38 -test
output.

md5 numbers are from mdcrack
1.2.

sha1 numbers are from
lcrack-20031130-beta.

crypt-bf numbers are taken
using a simple program that loops over 1000 8-character
passwords. That way I can show the speed with different
numbers of iterations. For reference: john -test shows 213 loops/sec for
crypt-bf/5. (The very small
difference in results is in accordance with the fact that
the crypt-bf implementation in
pgcrypto is the same one used
in John the Ripper.)

Note that "try all
combinations" is not a realistic exercise. Usually
password cracking is done with the help of dictionaries,
which contain both regular words and various mutations of
them. So, even somewhat word-like passwords could be cracked
much faster than the above numbers suggest, while a
6-character non-word-like password may escape cracking. Or
not.

Decrypt a public-key-encrypted message. key must be the secret key corresponding to
the public key that was used to encrypt. If the secret key is
password-protected, you must give the password in psw. If there is no password, but you want
to specify options, you need to give an empty password.

Decrypting bytea data with
pgp_pub_decrypt is disallowed.
This is to avoid outputting invalid character data.
Decrypting originally textual data with pgp_pub_decrypt_bytea is fine.

The options parameter can
contain option settings, as described below.

pgp_key_id extracts the key
ID of a PGP public or secret key. Or it gives the key ID that
was used for encrypting the data, if given an encrypted
message.

It can return 2 special key IDs:

SYMKEY

The message is encrypted with a symmetric key.

ANYKEY

The message is public-key encrypted, but the key ID
has been removed. That means you will need to try all
your secret keys on it to see which one decrypts it.
pgcrypto itself does not
produce such messages.

Note that different keys may have the same ID. This is
rare but a normal event. The client application should then
try to decrypt with each one, to see which fits — like
handling ANYKEY.

Do not protect data with SHA-1. The only good reason to
use this option is to achieve compatibility with ancient
PGP products, predating the addition of SHA-1 protected
packets to RFC 4880. Recent gnupg.org and pgp.com software
supports it fine.

Whether to convert textual data from database internal
encoding to UTF-8 and back. If your database already is
UTF-8, no conversion will be done, but the message will be
tagged as UTF-8. Without this option it will not be.

No support for signing. That also means that it is not
checked whether the encryption subkey belongs to the
master key.

No support for encryption key as master key. As such
practice is generally discouraged, this should not be a
problem.

No support for several subkeys. This may seem like a
problem, as this is common practice. On the other hand,
you should not use your regular GPG/PGP keys with
pgcrypto, but create new ones,
as the usage scenario is rather different.

Encrypt/decrypt data using the cipher method specified by
type. The syntax of the type string is:

algorithm [-mode] [/pad:padding]

where algorithm is one
of:

bf — Blowfish

aes — AES (Rijndael-128)

and mode is one of:

cbc — next block depends on
previous (default)

ecb — each block is encrypted
separately (for testing only)

and padding is one of:

pkcs — data may be any length
(default)

none — data must be multiple of
cipher block size

So, for example, these are equivalent:

encrypt(data, 'fooz', 'bf')
encrypt(data, 'fooz', 'bf-cbc/pad:pkcs')

In encrypt_iv and decrypt_iv, the iv
parameter is the initial value for the CBC mode; it is ignored
for ECB. It is clipped or padded with zeroes if not exactly
block size. It defaults to all zeroes in the functions without
this parameter.