Index of /code/PostgreSQL/y_cryptolib

[ICO]NameLast modifiedSizeDescription

[DIR]Parent Directory  -  
[   ]y_pgcrypto.sql19-Nov-2007 20:11 4.1K 
[TXT]y_pgcrypto.c19-Nov-2007 20:11 16K 
[TXT]y_clib.h19-Nov-2007 20:10 10K 
[TXT]y_clib.c19-Nov-2007 20:11 48K 
[TXT]agpl-3.0.txt19-Nov-2007 20:11 34K 
[TXT]README.html23-Nov-2009 10:23 8.8K 
[   ]Makefile19-Nov-2007 20:11 3.2K 

Yellowbank PGCrypto

OBSOLETE

This code has been superceded by y_crypto.


PostgreSQL Implementation of PKCS #1 v2.1: RSA Cryptography Standard

This is a partial implementation of the cryptographic algorithms described by by PKCS #1 v2.1. Although cryptographic primitives such as RSAEP, RSADP, RSASP1, and RSAVP1 are implemented internally, they are not exposed as PostgreSQL functions. Neither does this project implement any of the v1_5 encryption or signature algorithms; it only implements their more secure successors.

A couple of things motivated me to write this code.

This module links against the GNU MP Library, as well as the MHash Library (see below).

This module extends PostgreSQL with the following functions (see y_pgcrypto.sql for description of arguments):

Creating and storing both the public and private halves of a keypair on the server presumes, of course, that the server (and it's administrator) is completely trusted. This would not generally hold true. The better approach would be to generate the key client-side, and then save the public keypair to the server. I plan to add such client code to this project soon. This should not prove too difficult, as I created y_cryptolib independantly of the PostgreSQL server code.

The overall security of this implementation currently depends on the robustness of the operating system random device. Edit the Makefile to indicate whether you are using /dev/random (BSD - untested), or /dev/urandom (Linux). The basic attack vector here is that if the seed length of a pseudo random generator is short enough, then an attacker may be able to replay a random number sequence, and thereby recreate the keys. If time permits, I may try to include a robust CSPRNG such as Fortuna.

The implementation of the RSA PKCS standard requires the use of hashing primitives. Rather than maintain two seperate codebases, I've therefor rolled my previous work on exposing the mhash library in PostgreSQL into this project.

Usage examples follow. All input and output is in the form of hexidecimal integers.

CREATE TABLE full_keys (
  key_id
    CHAR(64)
    PRIMARY KEY,
  key_type
    VARCHAR(7)
    NOT NULL
    CHECK ( key_type in ('sign', 'encrypt') ),
  n
    VARCHAR(512)
    NOT NULL,
  e
    VARCHAR(512)
    NOT NULL,
  d
    VARCHAR(512)
    NOT NULL
);
COMMENT ON COLUMN full_keys.n IS 'modulus';
COMMENT ON COLUMN full_keys.e IS 'public exponent';
COMMENT ON COLUMN full_keys.d IS 'private exponent';


CREATE TABLE encrypted (
  key_id
    CHAR(64)
    NOT NULL,
  cipherText
    TEXT
    NOT NULL        
);
CREATE INDEX encrypted__key_id_idx ON encrypted( key_id );


CREATE TABLE signed (
  key_id
    CHAR(64)
    NOT NULL,
  message
    TEXT
    NOT NULL,
  signature
    TEXT
    NOT NULL        
);
CREATE INDEX signed__key_id_idx ON signed( key_id );

CREATE OR REPLACE FUNCTION
  encrypt_basic( IN message TEXT,
                 IN keyid TEXT,
                 OUT ciphertext TEXT )
AS $$
   SELECT y_rsaes_oaep_encrypt( $1,
                                ROW( n, e ),
                                'SHA1',
                                '' )
   FROM
     full_keys
   WHERE
     key_id = $2;
$$ LANGUAGE SQL;


CREATE OR REPLACE FUNCTION
  sign_basic( IN message TEXT,
              IN keyid TEXT,
              OUT signature TEXT )
AS $$
   SELECT y_rsassa_pss_sign( $1,
                             ROW( n, d ),
                             'SHA1',
                             32 )
   FROM
     full_keys
   WHERE
     key_id = $2;
$$ LANGUAGE SQL;


INSERT INTO
  full_keys
SELECT
  encode( y_mhash( decode( n || e, 'hex' ), 'SHA256' ), 'hex' ) AS key_id,
  'encrypt' AS key_type,
  n,
  e,
  d
FROM
  y_generate_rsa_keys( '1024' );


INSERT INTO
  encrypted( key_id, ciphertext )
SELECT
  key_id,
  encrypt_basic( '123abc456def7890', key_id )
FROM
  full_keys;


PREPARE sign_p( TEXT ) AS
INSERT INTO
  signed( key_id, message, signature )
SELECT
  key_id,
  $1,
  sign_basic( $1, key_id )
FROM
  full_keys;


EXECUTE sign_p( '123abc456def7890' );
EXECUTE sign_p( 'deadbeaf' );


SELECT
  ciphertext,
  y_rsaes_oaep_decrypt( ciphertext,
                        ROW( n, d ),
                        'SHA1',
                        '' ) AS message
FROM
  encrypted, full_keys
WHERE
  encrypted.key_id = full_keys.key_id;


SELECT
  message,
  signature,
  y_rsassa_pss_verify( message,
                       signature,
                       ROW( n, e ),
                       'SHA1',
                       32 ) AS verify
FROM
  signed, full_keys
WHERE
  signed.key_id = full_keys.key_id;


MHASH Functions

This library also links to Mhash library by Nikos Mavroyanopoulos and Sascha Schumann to provide PostgreSQL with an extended set of cryptographic hash primitives.

The repertoire of available algorithms currently includes:

  WHIRLPOOL
  TIGER, TIGER160, TIGER128
  RIPEMD320, RIPEMD256, RIPEMD128
  SHA512, SHA384, SHA256, SHA224, SHA1
  HAVAL256, HAVAL224, HAVAL192, HAVAL160, HAVAL128
  GOST
  SNEFRU256, SNEFRU128
  MD5, MD4
  CRC32
  ADLER32

Examples:

> select encode( y_mhash( 'hashme'::bytea, 'TIGER' ), 'hex' );
                      encode                      
--------------------------------------------------
 ba94cfdd5713a9877cdfd0aa2c43dc1b6f68edc176716878


> select encode( y_mhash( 'hashme'::bytea, 'WHIRLPOOL' ), 'hex' );
                                                              encode                                                              
----------------------------------------------------------------------------------------------------------------------------------
 1bb04629b053cc15634eeb703fd76223d576c5a20e79432f9af6e7608bfb4c2a5ea805fe79879b1b0704159ac45052cd0404ee2c2095b413dafab0785cd0120a


> select encode( y_mhash( 'hashme'::bytea, 'SHA256' ), 'hex' );
                              encode                              
------------------------------------------------------------------
 02208b9403a87df9f4ed6b2ee2657efaa589026b4cce9accc8e8a5bf3d693c86


> select encode( y_mhash( 'hashme'::bytea, 'SHA1' ), 'hex' );
                  encode                  
------------------------------------------
 fb78992e561929a6967d5328f49413fa99048d06


> select encode( y_mhash( 'hashme'::bytea, 'GOST' ), 'hex' );
                              encode                              
------------------------------------------------------------------
 be59a8bb3460996abb374865c71b62c641a7a05ca503f1bed04c2fac09a6f5f0


> select encode( y_mhash( 'hashme'::bytea, 'MD5' ), 'hex' );
              encode              
----------------------------------
 533f6357e0210e67d91f651bc49e1278


> select encode( y_mhash( 'hashme'::bytea, 'MD4' ), 'hex' );
              encode              
----------------------------------
 dd03964b85359e0be5259e2dc4f1a271


> select encode( y_mhash( 'hashme'::bytea, 'CRC32' ), 'hex' );
  encode  
----------
 9a1f32c0


> select encode( y_mhash( 'hashme'::bytea, 'ADLER32' ), 'hex' );
  encode  
----------
 77029e08

Copyright (c) 2007
Ronald Peterson
(Y) Yellowbank
There are no restrictions on the copying of this README file.
Last modified: Mon Nov 23 10:23:20 EST 2009