mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-29 22:49:41 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			710 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			710 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| pgcrypto - cryptographic functions for PostgreSQL
 | |
| =================================================
 | |
| Marko Kreen <markokr@gmail.com>
 | |
| 
 | |
| // Note: this document is in asciidoc format.
 | |
| 
 | |
| 
 | |
| 1.  Installation
 | |
| -----------------
 | |
| 
 | |
| Run following commands:
 | |
| 
 | |
|     make
 | |
|     make install
 | |
|     make installcheck
 | |
| 
 | |
| The `make installcheck` command is important.  It runs regression tests
 | |
| for the module.  They make sure the functions here produce correct
 | |
| results.
 | |
| 
 | |
| Next, to put the functions into a particular database, run the commands in
 | |
| file pgcrypto.sql, which has been installed into the shared files directory.
 | |
| 
 | |
| Example using psql:
 | |
| 
 | |
|     psql -d DBNAME -f pgcrypto.sql
 | |
| 
 | |
| 
 | |
| 2.  Notes
 | |
| ----------
 | |
| 
 | |
| 2.1.  Configuration
 | |
| ~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| pgcrypto configures itself according to the findings of main PostgreSQL
 | |
| `configure` script.  The options that affect it are `--with-zlib` and
 | |
| `--with-openssl`.
 | |
| 
 | |
| When compiled with zlib, PGP encryption functions are able to
 | |
| compress data before encrypting.
 | |
| 
 | |
| When compiled with OpenSSL there will be more algorithms available.
 | |
| Also public-key encryption functions will be faster as OpenSSL
 | |
| has more optimized BIGNUM functions.
 | |
| 
 | |
| Summary of functionality with and without OpenSSL:
 | |
| 
 | |
| `----------------------------`---------`------------
 | |
|  Functionality                built-in   OpenSSL
 | |
| ----------------------------------------------------
 | |
|  MD5                          yes       yes
 | |
|  SHA1                         yes       yes
 | |
|  SHA224/256/384/512           yes       yes (3)
 | |
|  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    yes       yes
 | |
| ----------------------------------------------------
 | |
| 
 | |
| 1. Any digest algorithm OpenSSL supports is automatically picked up.
 | |
|    This is not possible with ciphers, which need to be supported
 | |
|    explicitly.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 3. SHA2 algorithms were added to OpenSSL in version 0.9.8.  For
 | |
|    older versions, pgcrypto will use built-in code.
 | |
| 
 | |
| 
 | |
| 2.2.  NULL handling
 | |
| ~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| As standard in SQL, all functions return NULL, if any of the arguments
 | |
| are NULL.  This may create security risks on careless usage.
 | |
| 
 | |
| 
 | |
| 2.3.  Security
 | |
| ~~~~~~~~~~~~~~~
 | |
| 
 | |
| 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:
 | |
| 
 | |
| 1.  Connect locally or use SSL connections.
 | |
| 2.  Trust both system and database administrator.
 | |
| 
 | |
| If you cannot, then better do crypto inside client application.
 | |
| 
 | |
| 
 | |
| 3.  General hashing
 | |
| --------------------
 | |
| 
 | |
| 3.1.  digest(data, type)
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
|   digest(data text, type text) RETURNS bytea
 | |
|   digest(data bytea, type text) RETURNS bytea
 | |
| 
 | |
| Type is here the algorithm to use.  Standard algorithms are `md5` and
 | |
| `sha1`, although there may be more supported, depending on build
 | |
| options.
 | |
| 
 | |
| Returns binary hash.
 | |
| 
 | |
| If you want hexadecimal string, use `encode()` on result.  Example:
 | |
| 
 | |
|     CREATE OR REPLACE FUNCTION sha1(bytea) RETURNS text AS $$
 | |
|       SELECT encode(digest($1, 'sha1'), 'hex')
 | |
|     $$ LANGUAGE SQL STRICT IMMUTABLE;
 | |
| 
 | |
| 
 | |
| 3.2.  hmac(data, key, type)
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
|   hmac(data text, key text, type text) RETURNS bytea
 | |
|   hmac(data bytea, key text, type text) RETURNS bytea
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| Returns binary hash.
 | |
| 
 | |
| 
 | |
| 
 | |
| 4.  Password hashing
 | |
| ---------------------
 | |
| 
 | |
| 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:
 | |
| 
 | |
| 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 is 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.
 | |
| 
 | |
| 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
 | |
| ----------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| 4.1.  crypt(password, salt)
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
|   crypt(password text, salt text) RETURNS text
 | |
| 
 | |
| 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.
 | |
| 
 | |
| Example - setting new password:
 | |
| 
 | |
|     UPDATE .. SET pswhash = crypt('new password', gen_salt('md5'));
 | |
| 
 | |
| Example - authentication:
 | |
| 
 | |
|     SELECT pswhash = crypt('entered password', pswhash) WHERE .. ;
 | |
| 
 | |
| returns true or false whether the entered password is correct.
 | |
| It also can return NULL if `pswhash` field is NULL.
 | |
| 
 | |
| 
 | |
| 4.2.  gen_salt(type)
 | |
| ~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
|   gen_salt(type text) RETURNS text
 | |
| 
 | |
| 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
 | |
| the 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 of that time.
 | |
| - Slower than 4 hashes per second would probably dampen usability.
 | |
| - Faster than 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 of 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
 | |
| ------------------------------------------------------------
 | |
| 
 | |
| * 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.
 | |
| * `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 "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, and a 6-character non-word like password may escape
 | |
| cracking.  Or not.
 | |
| 
 | |
| 
 | |
| 5.  PGP encryption
 | |
| -------------------
 | |
| 
 | |
| The functions here implement the encryption part of OpenPGP (RFC2440)
 | |
| standard.   Supported are both symmetric-key and public-key encryption.
 | |
| 
 | |
| 
 | |
| 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 it 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.8.
 | |
| 
 | |
| 
 | |
| 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.
 | |
| 
 | |
| Decrypting bytea data with `pgp_sym_decrypt` is disallowed.
 | |
| This is to avoid outputting invalid character data.  Decrypting
 | |
| originally textual data with `pgp_sym_decrypt_bytea` is fine.
 | |
| 
 | |
| Options are described in section 5.8.
 | |
| 
 | |
| 
 | |
| 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.8.
 | |
| 
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| Options are described in section 5.8.
 | |
| 
 | |
| 
 | |
| 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 that was used for encrypting the data, if given
 | |
| encrypted message.
 | |
| 
 | |
| It can return 2 special key IDs:
 | |
| 
 | |
| 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
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Options are named to be similar to GnuPG.  Values should be given after
 | |
| an equal sign; separate options from each other with commas.  Example:
 | |
| 
 | |
|   pgp_sym_encrypt(data, psw, 'compress-algo=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 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 - Without salt.  Dangerous!
 | |
|     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: use 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
 | |
| 
 | |
| The preferred key type is "DSA and Elgamal".
 | |
| 
 | |
| For RSA encryption you must create either DSA or RSA sign-only key
 | |
| as master and then add RSA encryption subkey with `gpg --edit-key`.
 | |
| 
 | |
| 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 them to
 | |
| pgp_pub_* functions.  Or if you can handle binary data, you can drop
 | |
| "-a" from gpg.
 | |
| 
 | |
| For more details see `man gpg`, http://www.gnupg.org/gph/en/manual.html[
 | |
| The GNU Privacy Handbook] and other docs on http://www.gnupg.org[] site.
 | |
| 
 | |
| 
 | |
| 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 encryption key as master key.  As such practice
 | |
|   is generally discouraged, it 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.
 | |
| 
 | |
| 
 | |
| 6.  Raw encryption
 | |
| -------------------
 | |
| 
 | |
| Those functions only run a cipher over data, they don't have any advanced
 | |
| features of PGP encryption.  Therefore 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 is 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.  Random bytes
 | |
| -----------------
 | |
| 
 | |
|     gen_random_bytes(count integer)
 | |
| 
 | |
| Returns `count` cryptographically strong random bytes as bytea value.
 | |
| There can be maximally 1024 bytes extracted at a time.  This is to avoid
 | |
| draining the randomness generator pool.
 | |
| 
 | |
| 
 | |
| 8.  Credits
 | |
| ------------
 | |
| 
 | |
| I have used code from following sources:
 | |
| 
 | |
| `--------------------`-------------------------`-------------------------------
 | |
|   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      Simon Tatham              PuTTY
 | |
|   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
 | |
|   BIGNUM math          Michael J. Fromberger     dartmouth.edu/~sting/sw/imath
 | |
| -------------------------------------------------------------------------------
 | |
| 
 | |
| 
 | |
| 9.  Legalese
 | |
| -------------
 | |
| 
 | |
| * I owe a beer to Poul-Henning.
 | |
| 
 | |
| 
 | |
| 10.  References/Links
 | |
| ----------------------
 | |
| 
 | |
| 10.1.  Useful reading
 | |
| ~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| http://www.gnupg.org/gph/en/manual.html[]::
 | |
| 	The GNU Privacy Handbook
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 
 | |
| 10.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.
 | |
| 
 | |
| 
 | |
| // $PostgreSQL: pgsql/contrib/pgcrypto/README.pgcrypto,v 1.19 2007/03/28 22:48:58 neilc Exp $
 |