| Name | Last modified | Size | Description | |
|---|---|---|---|---|
| Parent Directory | - | |||
| Makefile | 19-Nov-2007 20:11 | 3.2K | ||
| README.html | 23-Nov-2009 10:23 | 8.8K | ||
| agpl-3.0.txt | 19-Nov-2007 20:11 | 34K | ||
| y_clib.c | 19-Nov-2007 20:11 | 48K | ||
| y_clib.h | 19-Nov-2007 20:10 | 10K | ||
| y_pgcrypto.c | 19-Nov-2007 20:11 | 16K | ||
| y_pgcrypto.sql | 19-Nov-2007 20:11 | 4.1K | ||
This code has been superceded by y_crypto.
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;
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