From: Tom Lane Date: Mon, 18 Jul 2005 17:17:12 +0000 (+0000) Subject: pgcrypto documentation update. Marko Kreen X-Git-Tag: REL8_1_0BETA1~290 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=24ce1438c092d77db095b934ce5b038f5cec58d1;p=postgresql pgcrypto documentation update. Marko Kreen --- diff --git a/contrib/pgcrypto/README.pgcrypto b/contrib/pgcrypto/README.pgcrypto index 5446c19a3b..a6ef003f21 100644 --- a/contrib/pgcrypto/README.pgcrypto +++ b/contrib/pgcrypto/README.pgcrypto @@ -1,362 +1,675 @@ +$PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.12 2005/07/18 17:17:12 tgl Exp $ -pgcrypto 0.4 - cryptographic functions for PostgreSQL. -====================================================== -by Marko Kreen +pgcrypto - cryptographic functions for PostgreSQL +================================================= +Marko Kreen -INSTALLATION -============ +1. Installation +----------------- -Edit makefile, if you want to use any external library. +Run following commands: -NB! Default randomness source is libc random() function. This -is so only to get pgcrypto build everywhere. Randomness is -needed for gen_salt() and pgp_encrypt() functions. So if you plan -using those, you should definitely change that by editing Makefile. -You can should use urandom device if your OS supports it, otherwise -link pgcrypto against OpenSSL library and use its PRNG. + make + make install + make installcheck -After editing Makefile: +The `make installcheck` command is important. It runs regression tests +for the module. They make sure the functions here produce correct +results. -make -make install -To run regression tests, install both PostgreSQL and pgcrypto -and then run +2. Notes +---------- -make installcheck +2.1. Configuration +~~~~~~~~~~~~~~~~~~~~ -SQL FUNCTIONS -============= +pgcrypto configures itself according to the findings of main PostgreSQL +`configure` script. The options that affect it are `--with-zlib` and +`--with-openssl`. - If any of arguments are NULL they return NULL. +Without zlib, the PGP functions will not support compressed data inside +PGP encrypted packets. -digest(data::bytea, type::text)::bytea +Without OpenSSL, public-key encryption does not work, as pgcrypto does +not yet contain math functions for large integers. - Type is here the algorithm to use. E.g. 'md5', 'sha1', ... - Returns binary hash. +There are some other differences with and without OpenSSL: -digest_exists(type::text)::bool +`----------------------------`---------`------------ + Functionality built-in OpenSSL +---------------------------------------------------- + MD5 yes yes + SHA1 yes yes + SHA256/384/512 yes since 0.9.8 + Any other digest algo no yes (1) + Blowfish yes yes + AES yes yes (2) + DES/3DES/CAST5 no yes + Raw encryption yes yes + PGP Symmetric encryption yes yes + PGP Public-Key encryption no yes +---------------------------------------------------- - Returns BOOL whether given hash exists. +1. Any digest algorithm OpenSSL supports is automatically picked up. + This is not possible with ciphers, which need to be supported + explicitly. -hmac(data::bytea, key::bytea, type::text)::bytea +2. AES is included in OpenSSL since version 0.9.7. If pgcrypto is + compiled against older version, it will use built-in AES code, + so it has AES always available. - Calculates Hashed MAC over data. type is the same as - in digest(). Returns binary hash. Similar to digest() - but noone can alter data and re-calculate hash without - knowing key. If the key is larger than hash blocksize - it will first hashed and the hash will be used as key. - - [ HMAC is described in RFC2104. ] -hmac_exists(type::text)::bool - Returns BOOL. It is separate function because all hashes - cannot be used in HMAC. +2.2. NULL handling +~~~~~~~~~~~~~~~~~~~~ -crypt(password::text, salt::text)::text +As standard in SQL, all functions return NULL, if any of the arguments +are NULL. This may create security risks on careless usage. - Calculates UN*X crypt(3) style hash. Useful for storing - passwords. For generating salt you should use the - gen_salt() function. Usage: - New password: - - UPDATE .. SET pswhash = crypt(new_psw, gen_salt('md5')); - - Authentication: +2.3. Deprecated functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~ - SELECT pswhash = crypt(given_psw, pswhash) WHERE .. ; - - returns BOOL whether the given_psw is correct. DES crypt - has max key of 8 bytes, MD5 has max key at least 2^32-1 - bytes but may be larger on some platforms... +The `digest_exists()`, `hmac_exists()` and `cipher_exists()` functions +are deprecated. The plan is to remove those in PostgreSQL 8.2. - Builtin crypt() supports DES, Extended DES, MD5 and Blowfish - (variant 2a) algorithms. -gen_salt(type::text)::text +2.4. Security +~~~~~~~~~~~~~~~ - Generates a new random salt for usage in crypt(). Type - - 'des' - Old UNIX, not recommended - 'md5' - md5-based crypt() - 'xdes' - 'Extended DES' - 'bf' - Blowfish-based, variant 2a - - When you use --enable-system-crypt then note that system - libcrypt may not support them all. - -gen_salt(type::text, rounds::int4)::text - - same as above, but lets user specify iteration count - for algorithm. Number is algorithm specific: - - type default min max - --------------------------------- - xdes 725 1 16777215 - bf 6 4 31 - - In case of xdes there is a additional limitation that the - count must be a odd number. - - The higher the count, the more time it takes to calculate - crypt and therefore the more time to break it. But beware! - With too high count it takes a _very_long_ time to - calculate it. - - For maximum security, you should choose the 'bf' crypt - and use maximum number of rounds you can still tolerate. - -armor(bytea)::text -dearmor(text)::bytea - - Those wrap/unwrap data into PGP Ascii Armor which - is basically Base64 with CRC and additional formatting. - -pgp_sym_encrypt(data::text, key::text)::bytea -pgp_sym_encrypt(data::text, key::text, arg::text)::bytea -pgp_sym_encrypt_bytea(data::bytea, key::text)::bytea -pgp_sym_encrypt_bytea(data::bytea, key::text, arg::text)::bytea - -pgp_sym_decrypt(data::bytea, key::text)::text -pgp_sym_decrypt(data::bytea, key::text, arg::text)::text -pgp_sym_decrypt_bytea(data::text, key::text)::bytea -pgp_sym_decrypt_bytea(data::text, key::text, arg::text)::bytea - - Encrypt data into OpenPGP Symmetrically Encrypted Data - message. And decrypt it from it. - - Note that the pgp_sym_encrypt_bytea functions tag the data - as binary, as the pgp_sym_encrypt will tag the data as text. - You can not decrypt the binary data as text. But you can - decrypt text data as binary. This rule avoids having - broken textual data in PostgreSQL. - - Both encrypt and decrypt accept also third argument, which - is parameters to the function in following format: - - parm=val[,parm=val]... - - Example: - - select pgp_sym_encrypt('data', 'psw', - 'compress-algo=2, unicode-mode=1'); - - Accepted parameters are: - - cipher-algo: bf, aes, aes128, aes192, aes256 - Cipher algorithm to use. OpenSSL gives additional algorithms: - 3des, cast5 - Default: aes128 - - compress-algo: 0, 1, 2 - Which compression algorithm to use. - 0 - no compression - 1 - ZIP compression - 2 - ZLIB compression [=ZIP plus meta-data and block-CRC's] - Default: 0 - - compress-level: 0, 1-9 - How much to compress. Bigger level compresses smaller - but also slower. 0 disables compression. - Default: 6 - - convert-crlf: 0, 1 - Whether to convert \n into \r\n when encrypting and - \r\n to \n when decrypting. RFC2440 specifies that - text packets should use "\r\n" line-feeds. - Use this to get fully RFC-compliant behaviour. - Default: 0 - - disable-mdc: 0, 1 - Do not protect data with SHA-1. Note that SHA-1 protected - packet is from upcoming update to RFC2440. (Currently at - version RFC2440bis-13.) You need to disable it if you need - compatibility with ancient PGP products. Recent gnupg.org - and pgp.com software supports it fine. - Default: 0 - - enable-session-key: 0, 1 - Use separate session key. - Default: 0 - - s2k-mode: 0, 1, 3 - Which S2K algorithm to use. 0 is dangerous - without salt. - Default: 3 - - s2k-digest-algo: md5, sha1 - Which digest algorithm to use in S2K calculation. - Default: SHA-1 - - s2k-cipher-algo: bf, aes, aes128, aes192, aes256 - Which cipher to use for encrypting separate session key. - Default: same as cipher-algo. - - unicode-mode: 0, 1 - Whether to convert textual data from database internal - encoding to UTF-8 and back. - Default: 0 - - Only 'convert-crlf' applies to both encrypt and decrypt, - all others apply only to encrypt - decrypt gets the - settings from PGP data. - - -pgp_pub_encrypt(data::text, key::bytea)::bytea -pgp_pub_encrypt(data::text, key::bytea, arg::text)::bytea -pgp_pub_encrypt_bytea(data::bytea, bytea::text)::bytea -pgp_pub_encrypt_bytea(data::bytea, bytea::text, arg::text)::bytea - -pgp_pub_decrypt(data::bytea, key::bytea)::text -pgp_pub_decrypt(data::bytea, key::bytea, psw::text)::text -pgp_pub_decrypt(data::bytea, key::bytea, psw::text, arg::text)::text -pgp_pub_decrypt_bytea(data::text, key::bytea)::bytea -pgp_pub_decrypt_bytea(data::text, key::bytea, psw::text)::bytea -pgp_pub_decrypt_bytea(data::text, key::bytea, psw::text, arg::bytea)::bytea - - Encrypt data into OpenPGP Public-Key Encrypted Data - message. And decrypt it from it. The arg parameter is - described in pgp_sym_* section. - - The key must be a public-key packet for pgp_pub_encrypt - functions and a secret key packet for pgp_pub_decrypt - functions. Trying to encrypt with secret key gives a error. - While being technically possible, it is probably a sign of - user error and leaking secret keys. - - Here is a example how to generate them: - - Generate a new key: - - gpg --gen-key - - You need to pick "DSA and Elgamal" key type, others - are sign-only. - - List keys: - - gpg --list-secret-keys - - Export ascii-armored public key: +All the functions here run inside database server. That means that all +the data and passwords move between pgcrypto and client application in +clear-text. Thus you must: - gpg -a --export KEYID > public.key - - Export ascii-armored secret key: +1. Connect locally or use SSL connections. +2. Trust both system and database administrator. - gpg -a --export-secret-keys KEYID > secret.key +If you cannot, then better do crypto inside client application. - You need to use dearmor() on them before giving giving - them to pgp_pub_* functions. Ofcourse, if you can handle - binary data, you can drop "-a" from gpg. +3. General hashing +-------------------- -pgp_key_id(key / data) +3.1. digest(data, type) +~~~~~~~~~~~~~~~~~~~~~~~~~ - It shows you either key ID if given PGP public or secret - key. Or it gives the key ID what was used for encrypting - the data, if given encrypted data. + digest(data text, type text) RETURNS bytea + digest(data bytea, type text) RETURNS bytea - It can return 2 special key ID's: +Type is here the algorithm to use. Standard algorithms are `md5` and +`sha1`, although there may be more supported, depending on build +options. - SYMKEY - it got symmetrically encrypted data. - ANYKEY - the data packet key ID is clear. That means - you should try all you secret keys on it. +Returns binary hash. -encrypt(data::bytea, key::bytea, type::text)::bytea -decrypt(data::bytea, key::bytea, type::text)::bytea -encrypt_iv(data::bytea, key::bytea, iv::bytea, type::text)::bytea -decrypt_iv(data::bytea, key::bytea, iv::bytea, type::text)::bytea +If you want hexadecimal string, use `encode()` on result. Example: - Encrypt/decrypt data with cipher, padding data if needed. + CREATE OR REPLACE FUNCTION sha1(bytea) RETURNS text AS $$ + SELECT encode(digest($1, 'sha1'), 'hex') + $$ LANGUAGE SQL STRICT IMMUTABLE; - Pseudo-noteup: - algo ['-' mode] ['/pad:' padding] +3.2. hmac(data, key, type) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Supported algorithms: - - bf - Blowfish - aes, rijndael - Rijndael-128 + hmac(data text, key text, type text) RETURNS bytea + hmac(data bytea, key text, type text) RETURNS bytea - Others depend on library and are not tested enough, so - play on your own risk. +Calculates Hashed MAC over data. `type` is the same as in `digest()`. +If the key is larger than hash block size it will first hashed and the +hash will be used as key. - Modes: 'cbc' (default), 'ecb'. Again, library may support - more. +It is similar to digest() but the hash can be recalculated only knowing +the key. This avoids the scenario of someone altering data and also +changing the hash. - Padding is 'pkcs' (default), 'none'. 'none' is mostly for - testing ciphers, you should not need it. +Returns binary hash. - So, example: - encrypt(data, 'fooz', 'bf') - - is equal to - encrypt(data, 'fooz', 'bf-cbc/pad:pkcs') +4. Password hashing +--------------------- - IV is initial value for mode, defaults to all zeroes. - It is ignored for ECB. It is clipped or padded with zeroes - if not exactly block size. +The functions `crypt()` and `gen_salt()` are specifically designed +for hashing passwords. `crypt()` does the hashing and `gen_salt()` +prepares algorithm parameters for it. +The algorithms in `crypt()` differ from usual hashing algorithms like +MD5 or SHA1 in following respects: -ALGORITHMS -========== +1. They are slow. As the amount of data is so small, this is only + way to make brute-forcing passwords hard. +2. Include random 'salt' with result, so that users having same + password would have different crypted passwords. This also + additional defense against reversing the algorithm. +3. Include algorithm type in the result, so passwords hashed with + different algorithms can co-exist. +4. Some of them are adaptive - that means after computers get + faster, you can tune the algorithm to be slower, without + introducing incompatibility with existing passwords. -The standard functionality at the moment consists of +Supported algorithms: +`------`-------------`---------`----------`--------------------------- + Type Max password Adaptive Salt bits Description +---------------------------------------------------------------------- +`bf` 72 yes 128 Blowfish-based, variant 2a +`md5` unlimited no 48 md5-based crypt() +`xdes` 8 yes 24 Extended DES +`des` 8 no 12 Original UNIX crypt +---------------------------------------------------------------------- -Hashes: md5, sha1 -Ciphers: bf, aes -Modes: cbc, ecb -TODO: write standard names for optional ciphers too. +4.1. crypt(password, salt) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LIBRARIES -========= + crypt(password text, salt text) RETURNS text -* crypt() +Calculates UN*X crypt(3) style hash of password. When storing new +password, you need to use function `gen_salt()` to generate new salt. +When checking password you should use existing hash as salt. - internal: des, xdes, md5, bf +Example - setting new password: - -lcrypt: ??? (whatever you have) + UPDATE .. SET pswhash = crypt('new password', gen_salt('md5')); -* other: +Example - authentication: -[ This only lists stuff that the libraries claim to support. So - pgcrypto may work with all of them. But ATM tested are only the - standard ciphers. On others pgcrypto and library may mess something - up. You have been warned. ] + SELECT pswhash = crypt('entered password', pswhash) WHERE .. ; -internal (default): - Hashes: MD5, SHA1 - Ciphers: Blowfish, Rijndael-128 +returns true or false whether the entered password is correct. +It also can return NULL if `pswhash` field is NULL. -OpenSSL (0.9.7): - Hashes: MD5, SHA1, RIPEMD160, MD2 - Ciphers: Blowfish, AES, CAST5, DES, 3DES - License: BSD-like with strong advertisement - Url: http://www.openssl.org/ +4.2. gen_salt(type) +~~~~~~~~~~~~~~~~~~~~~ + gen_salt(type text) RETURNS text -CREDITS -======= +Generates a new random salt for usage in `crypt()`. For adaptible +algorithms, it uses the default iteration count. + +Accepted types are: `des`, `xdes`, `md5` and `bf`. + + +4.3. gen_salt(type, rounds) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + gen_salt(type text, rounds integer) RETURNS text + +Same as above, but lets user specify iteration count for some +algorithms. The higher the count, the more time it takes to hash +ti password and therefore the more time to break it. Although with +too high count the time to calculate a hash may be several years +- which is somewhat impractical. + +Number is algorithm specific: + +`-----'---------'-----'---------- + type default min max +--------------------------------- + `xdes` 725 1 16777215 + `bf` 6 4 31 +--------------------------------- + +In case of xdes there is a additional limitation that the count must be +a odd number. + +Notes: + +- Original DES crypt was designed to have the speed of 4 hashes per + second on the hardware that time. +- Slower that 4 hashes per second would probably damper usability. +- Faster that 100 hashes per second is probably too fast. +- See next section about possible values for `crypt-bf`. + + +4.4. Comparison of crypt and regular hashes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here is a table that should give overview of relative slowness +of different hashing algorithms. + +* The goal is to crack a 8-character password, which consists: + 1. Only from lowercase letters + 2. Numbers, lower- and uppercase letters. +* The table below shows how much time it would take to try all + combinations of characters. +* The `crypt-bf` is featured in several settings - the number + after slash is the `rounds` parameter of `gen_salt()`. + +`------------'----------'--------------'-------------------- +Algorithm Hashes/sec Chars: [a-z] Chars: [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 +password 143781000 25 mins 18 days +------------------------------------------------------------ + +* The machine used is 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. +* MySQL password() numbers are from my own tests. + (http://grue.l-t.ee/~marko/src/mypass/) +* `crypt-bf` numbers are taken using simple program that loops + over 1000 8-character passwords. That way I can show the speed with + different number of rounds. For reference: `john -test` shows 213 + loops/sec for crypt-bf/5. (The small difference in results is in + accordance to the fact that the `crypt-bf` implementation in pgcrypto + is same one that is used in John the Ripper.) + +Note that the "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 will be cracked much faster than the above +numbers suggest, and a 6-character non-word like password may escape +cracking. Or may not. + + +5. PGP encryption +------------------- + +The functions here implement the encryption part of OpenPGP (RFC2440) +standard. + + +5.1. Overview +~~~~~~~~~~~~~~~ + +Encrypted PGP message consists of 2 packets: + +- Packet for session key - either symmetric- or public-key encrypted. +- Packet for session-key encrypted data. + +When encrypting with password: + +1. Given password is hashed using String2Key (S2K) algorithm. This + is rather similar to `crypt()` algorithm - purposefully slow + and with random salt - but is produces a full-length binary key. +2. If separate session key is requested, new random key will be + generated. Otherwise S2K key will be used directly as session key. +3. If S2K key is to be used directly, then only S2K settings will be put + into session key packet. Otherwise session key will be encrypted with + S2K key and put into session key packet. + +When encrypting with public key: + +1. New random session key is generated. +2. It is encrypted using public key and put into session key packet. + +Now common part, the session-key encrypted data packet: + +1. Optional data-manipulation: compression, conversion to UTF-8, + conversion of line-endings. +2. Data is prefixed with block of random bytes. This is equal + to using random IV. +3. A SHA1 hash of random prefix and data is appended. +4. All this is encrypted with session key. + + +5.2. pgp_sym_encrypt(data, psw) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + pgp_sym_encrypt(data text, psw text [, options text] ) RETURNS bytea + pgp_sym_encrypt_bytea(data bytea, psw text [, options text] ) RETURNS bytea + +Return a symmetric-key encrypted PGP message. + +Options are described in section 5.7. + + +5.3. pgp_sym_decrypt(msg, psw) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + pgp_sym_decrypt(msg bytea, psw text [, options text] ) RETURNS text + pgp_sym_decrypt_bytea(msg bytea, psw text [, options text] ) RETURNS bytea + +Decrypt a symmetric-key encrypted PGP message. + +Options are described in section 5.7. + + +5.4. pgp_pub_encrypt(data, pub_key) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + pgp_pub_encrypt(data text, key bytea [, options text] ) RETURNS bytea + pgp_pub_encrypt_bytea(data bytea, key bytea [, options text] ) RETURNS bytea + +Encrypt data with a public key. Giving this function a secret key will +produce a error. + +Options are described in section 5.7. + + +5.5. pgp_pub_decrypt(msg, sec_key [, psw]) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + pgp_pub_decrypt(msg bytea, key bytea [, psw text [, options text]] ) \ + RETURNS text + pgp_pub_decrypt_bytea(msg bytea, key bytea [,psw text [, options text]] ) \ + RETURNS bytea + +Decrypt a public-key encrypted message with secret key. If the secret +key is password-protected, you must give the password in `psw`. If +there is no password, but you want to specify option for function, you +need to give empty password. + +Options are described in section 5.7. + + +5.6. pgp_key_id(key / msg) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + pgp_key_id(key or msg bytea) RETURNS text + +It shows you either key ID if given PGP public or secret key. Or it +gives the key ID what was used for encrypting the data, if given +encrypted message. + +It can return 2 special key ID's: + +SYMKEY:: + The data is encrypted with symmetric key. + +ANYKEY:: + The data is public-key encrypted, but the key ID is cleared. + That means you 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 same ID. This is rare but normal +event. Client application should then try to decrypt with each one, +to see which fits - like handling ANYKEY. + + +5.7. armor / dearmor +~~~~~~~~~~~~~~~~~~~~~~ + + armor(data bytea) RETURNS text + dearmor(data text) RETURNS bytea + +Those wrap/unwrap data into PGP Ascii Armor which is basically Base64 +with CRC and additional formatting. + + +5.8. Options for PGP functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Option are named to be similar to GnuPG. Values should be given after +equal sign, different options from each other with commas. Example: + + pgp_sym_encrypt(data, psw, 'compress-also=1, cipher-algo=aes256') + +All of the options except `convert-crlf` apply only to encrypt +functions. Decrypt functions get the parameters from PGP data. + +Most interesting options are probably `compression-algo` and +`unicode-mode`. The rest should have reasonable defaults. + + +cipher-algo:: + What cipher algorithm to use. + + Values: bf, aes128, aes192, aes256 (OpenSSL-only: `3des`, `cast5`) + Default: aes128 + Applies: pgp_sym_encrypt, pgp_pub_encrypt + + +compress-algo:: + Which compression algorithm to use. Needs building with zlib. + + Values: + 0 - no compression + 1 - ZIP compression + 2 - ZLIB compression [=ZIP plus meta-data and block-CRC's] + Default: 0 + Applies: pgp_sym_encrypt, pgp_pub_encrypt + +compress-level:: + How much to compress. Bigger level compresses smaller but is slower. + 0 disables compression. + + Values: 0, 1-9 + Default: 6 + Applies: pgp_sym_encrypt, pgp_pub_encrypt + +convert-crlf:: + Whether to convert `\n` into `\r\n` when encrypting and `\r\n` to `\n` + when decrypting. RFC2440 specifies that text data should be stored + using `\r\n` line-feeds. Use this to get fully RFC-compliant + behavior. + + Values: 0, 1 + Default: 0 + Applies: pgp_sym_encrypt, pgp_pub_encrypt, pgp_sym_decrypt, pgp_pub_decrypt + +disable-mdc:: + Do not protect data with SHA-1. Only good reason to use is this + option is to achieve compatibility with ancient PGP products, as the + SHA-1 protected packet is from upcoming update to RFC2440. (Currently + at version RFC2440bis-14.) Recent gnupg.org and pgp.com software + supports it fine. + + Values: 0, 1 + Default: 0 + Applies: pgp_sym_encrypt, pgp_pub_encrypt + +enable-session-key:: + Use separate session key. Public-key encryption always uses separate + session key, this is for symmetric-key encryption, which by default + uses S2K directly. + + Values: 0, 1 + Default: 0 + Applies: pgp_sym_encrypt + +s2k-mode:: + Which S2K algorithm to use. + + Values: + 0 - Dangerous! Without salt. + 1 - With salt but with fixed iteration count. + 3 - Variable iteration count. + Default: 3 + Applies: pgp_sym_encrypt + +s2k-digest-algo:: + Which digest algorithm to use in S2K calculation. + + Values: md5, sha1 + Default: sha1 + Applies: pgp_sym_encrypt + +s2k-cipher-algo:: + Which cipher to use for encrypting separate session key. + + Values: bf, aes, aes128, aes192, aes256 + Default: same as cipher-algo. + Applies: pgp_sym_encrypt + +unicode-mode:: + 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, only the data will be tagged as UTF-8. Without this option + it will not be. + + Values: 0, 1 + Default: 0 + Applies: pgp_sym_encrypt, pgp_pub_encrypt + + +5.9. Generating keys with GnuPG +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Generate a new key: + + gpg --gen-key + +You need to pick "DSA and Elgamal" key type, others are sign-only. + +List keys: + + gpg --list-secret-keys + +Export ascii-armored public key: + + gpg -a --export KEYID > public.key + +Export ascii-armored secret key: + + gpg -a --export-secret-keys KEYID > secret.key + +You need to use `dearmor()` on them before giving giving them to +pgp_pub_* functions. Or if you can handle binary data, you can drop +"-a" from gpg. + + +5.10. Limitations of PGP code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- No support for signing. That also means that it is not checked + whether the encryption subkey belongs to master key. + +- No support for RSA keys. Only Elgamal encryption keys are supported + +- No support for several encryption subkeys. + + +6. Raw encryption +------------------- + +Those functions only run a cipher over data, they don't have any advanced +features of PGP encryption. In addition, they have some major problems: + +1. They use user key directly as cipher key. +2. They don't provide any integrity checking, to see + if the encrypted data was modified. +3. They expect that users manage all encryption parameters + themselves, even IV. +4. They don't handle text. + +So, with the introduction of PGP encryption, usage of raw +encryption functions is discouraged. + + + encrypt(data bytea, key bytea, type text) RETURNS bytea + decrypt(data bytea, key bytea, type text) RETURNS bytea + + encrypt_iv(data bytea, key bytea, iv bytea, type text) RETURNS bytea + decrypt_iv(data bytea, key bytea, iv bytea, type text) RETURNS bytea + +Encrypt/decrypt data with cipher, padding data if needed. + +`type` parameter description in pseudo-noteup: + + algo ['-' mode] ['/pad:' padding] + +Supported algorithms: + +* `bf` - Blowfish +* `aes` - AES (Rijndael-128) + +Modes: + +* `cbc` - next block depends on previous. (default) +* `ecb` - each block in encrypted separately. + (for testing only) + +Padding: + +* `pkcs` - data may be any length (default) +* `none` - data must be multiple of cipher block size. + +IV is initial value for mode, defaults to all zeroes. It is ignored for +ECB. It is clipped or padded with zeroes if not exactly block size. + +So, example: + + encrypt(data, 'fooz', 'bf') + +is equal to + + encrypt(data, 'fooz', 'bf-cbc/pad:pkcs') + + +7. Credits +------------ I have used code from following sources: -DES crypt() by David Burren and others FreeBSD libcrypt -MD5 crypt() by Poul-Henning Kamp FreeBSD libcrypt -Blowfish crypt() by Solar Designer www.openwall.com -Blowfish cipher by Niels Provos OpenBSD sys/crypto -Rijndael cipher by Brian Gladman OpenBSD sys/crypto -MD5 and SHA1 by WIDE Project KAME kame/sys/crypto +`--------------------`-------------------------`---------------------- + Algorithm Author Source origin +---------------------------------------------------------------------- + DES crypt() David Burren and others FreeBSD libcrypt + MD5 crypt() Poul-Henning Kamp FreeBSD libcrypt + Blowfish crypt() Solar Designer www.openwall.com + Blowfish cipher Niels Provos OpenBSD sys/crypto + Rijndael cipher Brian Gladman OpenBSD sys/crypto + MD5 and SHA1 WIDE Project KAME kame/sys/crypto + SHA256/384/512 Aaron D. Gifford OpenBSD sys/crypto +---------------------------------------------------------------------- -LEGALESE -======== -* I owe a beer to Poul-Henning. +8. Legalese +------------- +* I owe a beer to Poul-Henning. * This product includes software developed by Niels Provos. +9. References/Links +--------------------- + +9.1. Useful reading +~~~~~~~~~~~~~~~~~~~~~ + +http://www.openwall.com/crypt/[]:: + Describes the crypt-blowfish algorithm. + +http://www.stack.nl/~galactus/remailers/passphrase-faq.html[]:: + How to choose good password. + +http://world.std.com/~reinhold/diceware.html[]:: + Interesting idea for picking passwords. + +http://www.interhack.net/people/cmcurtin/snake-oil-faq.html[]:: + Describes good and bad cryptography. + + +9.2. Technical references +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +http://www.ietf.org/rfc/rfc2440.txt[]:: + OpenPGP message format + +http://www.imc.org/draft-ietf-openpgp-rfc2440bis[]:: + New version of RFC2440. + +http://www.ietf.org/rfc/rfc1321.txt[]:: + The MD5 Message-Digest Algorithm + +http://www.ietf.org/rfc/rfc2104.txt[]:: + HMAC: Keyed-Hashing for Message Authentication + +http://www.usenix.org/events/usenix99/provos.html[]:: + Comparison of crypt-des, crypt-md5 and bcrypt algorithms. + +http://csrc.nist.gov/cryptval/des.htm[]:: + Standards for DES, 3DES and AES. + +http://en.wikipedia.org/wiki/Fortuna_(PRNG)[]:: + Description of Fortuna CSPRNG. + +http://jlcooke.ca/random/[]:: + Jean-Luc Cooke Fortuna-based /dev/random driver for Linux. + +http://www.cs.ut.ee/~helger/crypto/[]:: + Collection of cryptology pointers.