F.25. pgcrypto

F.25.1. 일반 해시 함수
F.25.2. 비밀번호 해시 함수
F.25.3. PGP 암호 함수
F.25.4. 저수준 암복호화 함수
F.25.5. 난수 생성 함수
F.25.6. 참고
F.25.7. 만든이

pgcrypto 모듈은 PostgreSQL에서 사용할 수 있는 암호화 관련 함수를 제공한다.

이 묘듈은 trusted, 신뢰할 수 있는 모듈이다. 그래서, 해당 데이터베이스를 대상으로 CREATE 권한이 있는 일반 사용자도 설치할 수 있다.

F.25.1. 일반 해시 함수

F.25.1.1. digest()

digest(data text, type text) returns bytea
digest(data bytea, type text) returns bytea

입력한 data의 해시 이진값을 구한다. type 인자는 해시 알고리즘이다. 표준 알고리즘은 md5, sha1, sha224, sha256, sha384, sha512 이다. pgcrypto 모듈이 OpenSSL 라이브러리를 이용해서 빌드 되었다면, 표 F.19에서 제공하는 것보다 많은 알고리즘을 사용할 수 있다.

함수 반환값의 자료형이 bytea 형이다. 이것을 사용자가 읽을 수 있는 16진수 문자열로 변환하려면, encode() 함수를 사용한다. 사용 예:

CREATE OR REPLACE FUNCTION sha1(bytea) returns text AS $$
    SELECT encode(digest($1, 'sha1'), 'hex')
$$ LANGUAGE SQL STRICT IMMUTABLE;

F.25.1.2. hmac()

hmac(data text, key text, type text) returns bytea
hmac(data bytea, key bytea, type text) returns bytea

입력한 data 값을 입력한 key 값으로 MAC 해시 값을 구한다. type 인자는 digest() 함수에서 사용하는 것과 같다.

digest() 함수와 같으나, 키 값으로 한 번 더 계산한다. 이 기능은 누군가가 자료를 변경하고 그에 대응하는 해시 값도 바꾸는 문제점을 막는다.

키 값이 해시 블록 크기보다 크다면, 먼저 그것의 해시 값을 구한 뒤 그 값을 키로 사용한다.

F.25.2. 비밀번호 해시 함수

비밀번호 해시 작업은 crypt() 함수와 gen_salt() 함수로 구현한다. crypt() 함수는 해시 작업을 하고, gen_salt() 함수는 해시 작업 알고리즘을 지정하는데 사용된다.

crypt() 함수는 보통 MD5나 SHA1 알고리즘을 이용한 해시 작업과 달리, 다음의 장점이 있다:

  1. 이 함수들은 느리다. 입력 값의 크기가 아주 작을 때, 강제로 비밀번호를 만들 수 있는 유일한 방법이다.

  2. 이 함수들은 소금 salt라고 하는 값을 이용해서, 사용자의 같은 입력값에 대해서 다른 암호화된 비밀번호를 만든다. 그래서 복호화가 불가능하게 한다.

  3. 이 함수들은 결과 값에 알고리즘 종류를 포함시킨다. 그래서, 각기 다른 알고리즘으로 처리된 값이 공존할 수 있다.

  4. 이 함수에서 사용하는 알고리즘 가운데 몇몇은 적응력이 좋다 — 이 말은 사용하는 컴퓨터가 보다 빨라졌을 때, 기존 비밀번호를 모두 초기화 하지 않고, 보다 복잡하게 암호화를 할 수 있음을 뜻 한다.

crypt() 함수에서 지원하는 알고리즘은 표 F.16에서 나열하고 있다.

표 F.16. crypt() 함수에서 지원하는 알고리즘

알고리즘평문 비밀번호 최대 길이적응력소금 비트출력 길이설명
bf72있음12860Blowfish 기반, variant 2a
md5제한없음없음4834MD5 기반 암호화
xdes8있음2420확장 DES
des8없음1213전통적인 UNIX crypt

F.25.2.1. crypt()

crypt(password text, salt text) returns text

입력한 password 문자열에 대한 crypt(3) 형태의 해시 값을 계산하는 함수. 첫 비밀번호를 만들 때는 gen_salt() 함수를 이용해 새로운 salt 값을 만들어 사용하면 편하다. 사용자가 입력한 비밀번호가 올바른지를 확인하는 방법은 저장된 값에서 salt 값을 구해서, 그 값으로 같은 함수의 소금 인자로 사용하고, 그 반환 값이 저장된 값과 같은가를 확인한다.

새 비밀번호 지정하는 예제:

UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));

인증 예제:

SELECT (pswhash = crypt('entered password', pswhash)) AS pswmatch FROM ... ;

이 쿼리의 결과가 true면 입력한 비밀번호가 맞다.

F.25.2.2. gen_salt()

gen_salt(type text [, iter_count integer ]) returns text

crypt() 함수에서 사용할 임의의 소금 salt 문자열을 만든다. crypt() 함수는 이 문자열을 보고 사용할 알고리즘을 정한다.

type 인자 값은 해시 알고리즘이다. 사용할 수 있는 알고리즘: des, xdes, md5, bf.

iter_count 인자 값으로 지정한 알고리즘에서 그 처리 반복 횟수를 사용자가 지정할 수 있다. 이 값이 커지면, 비밀번호 해시 작업에 시간이 더 걸린다. 즉, 암호를 깨는데도 시간이 더 걸린다. 이론상으로는 이 값이 크면 해시 작업을 하는데 시간이 몇 년이 걸릴 수도 있다 — 실무에서 쓰지는 않겠지만. iter_count 값을 지정하지 않으면, 그 기본값이 사용된다. iter_count 값으로 허용되는 값은 사용하는 알고리즘에 따라 다르며, 구체적인 값은 아래 표 F.17에 있다.

표 F.17. crypt() 반복 횟수

알고리즘기본값최소최대
xdes725116777215
bf6431

xdes 알고리즘에서는 이 값이 반드시 홀수값이어야 한다.

적당한 반복 횟수를 지정하려면, 전통적으로 사용했던 DES 알고리즘은 crypt 작업에서 그 당시 하드웨어로 초당 4회 해시 작업을 할 수 있도록 설계되었음을 알아야 한다. 즉, 요즘의 하드웨어 장비로 초당 4회 정도의 해시 작업을 할 수 있으면 초기 설계 정신과 맞다는 것이다. 초당 100회 해시 작업을 한다면, 너무 빠르다. (해시 작업 반복 회수를 늘리는 것이 좋다.)

여러 해시 알고리즘의 상대적 속도 비교는 표 F.18에서 소개하고 있다. 평문 비밀번호가 8글자인 경우(소문자만으로 구성된 경우, 숫자, 대문자가 포함된 경우) 모든 조합을 만드는데 걸리는 시간을 소개하고 있다. crypt-bf 에서는 그 뒤에 iter_count 값을 지정해서 gen_salt 함수로 만든 소금을 쓴 경우를 각각 구분했다.

표 F.18. 해시 알고리즘 속도

알고리즘해시/초[a-z] 문자열[A-Za-z0-9] 문자열md5 해시와 비교한 속도
crypt-bf/817924 년3927 년10만배
crypt-bf/736482 년1929 년5만배
crypt-bf/671681 년982 년2만5천배
crypt-bf/513504188 일521 년12,500배
crypt-md517158415 일41 년1,000배
crypt-des23221568157.5 분108 일7 배
sha13777427290 분68 일4배
md5 (hash)15008550422.5 분17 일1

참고 사항:

  • CPU는 Intel Mobile Core i3.

  • crypt-descrypt-md5 알고리즘에 대한 수치는 John the Ripper v1.6.38 -test 결과를 수집함.

  • md5 hash 수치는 mdcrack 1.2 결과를 수집함.

  • sha1 수치는 lcrack-20031130-beta 결과를 수집함.

  • crypt-bf 수치는 반복 횟수를 달리 지정할 수 있도록 1000개의 8문자 임의 비밀번호를 반복하는 프로그램을 만들어서 수집함. 참고: john -test 에서는 crypt-bf/5 설정에서 초당 13506번 반복했다. (pgcrypto 모듈에서 구현한 crypt-bf 해시 기능은 John the Ripper에서 사용한 것과 그 결과의 차이가 미미했다.)

모든 조합에 대한 해시 기간은 실재로 실험해 본 기간이 아니다. 비밀번호를 알아내는 일반적인 방법은 사전에 있는 단어나, 그 단어와 유사하게 생긴 문자열을 사용해서 해시를 해보고, 그것이 해시된 자료와 같은가를 확인하는 방식으로 진행된다. 그래서, 일반 단어와 비슷한 비밀번호를 사용한다면, 보다 알아내기가 쉽다. 그래서, 6개의 문자가 일반 단어와 그 모습이 전혀 다르다면 비밀번호를 찾아내는 시간이 훨씬 오래 걸린다.

F.25.3. PGP 암호 함수

여기서 소개하는 함수들은 OpenPGP (RFC 4880) 표준에서 암복화 부분을 구현한 것이다. 대칭키와 공개키 암호화를 모두 지원한다.

암호화된 PGP 메시지는 두 부분 또는 두 패킷 packets 으로 구성된다:

  • 세션 키를 포함하고 있는 패킷 — 대칭키나 공개키로 암호화 됨.

  • 그 세션 키로 암호화 된 자료 패킷.

대칭키(예, 비밀번호)로 암호화 하는 방법:

  1. 지정한 비밀번호는 String2Key (S2K) 알고리즘을 이용해 해시 값으로 바꾼다. 이 알고리즘은 crypt() 알고리즘 — 느리고, 임의의 소금용 문자열 사용하는 — 과 비슷하지만 좀 더 단순하다. 하지만 이 알고리즘은 비밀번호 전체를 이진 키로 만든다. (crypt() 함수에서 사용하는 비밀번호의 길이에 대한 것은 윗 부분 참조 - 옮긴이)

  2. 세션 키를 분리하고자 한다면, 새 임의의 키가 생성 된다. 한편, S2K 형식의 키를 지정하면, 그것을 바로 세션 키로 사용한다.

  3. S2K 키가 바로 사용되면, S2K 설정만 세션 키 패킷에 포함 된다. 그 밖의 경우는 S2K 키와 세션 키를 암호화해서 세션 키 패킷에 포함 된다.

공개키로 암호화 하는 방법:

  1. 임의의 세션 키를 만든다.

  2. 그 세션 키를 공개 키로 암호화 해서 세션 키 패킷에 넣는다.

자료 암호화는 다음 작업으로 진행 된다:

  1. 선택적 자료 변환 작업: 압축, UTF-8 인코딩으로 변환, 줄바꿈 문자 변환

  2. 자료에 임의의 바이트가 추가됨. 이것은 임의 IV 값을 사용하는 것과 같다.

  3. 임의의 SHA1 해시 값이 자료 앞에 붙고,

  4. 이런 모든 처리가 끝난 다음 세션 키로 암호화 해서 자료 패킷으로 사용한다.

F.25.3.1. pgp_sym_encrypt()

pgp_sym_encrypt(data text, psw text [, options text ]) returns bytea
pgp_sym_encrypt_bytea(data bytea, psw text [, options text ]) returns bytea

대칭 PGP 키인 psw 값으로 data 값을 암호화 한다. options 값은 아래에서 자세히 설명한다.

F.25.3.2. pgp_sym_decrypt()

pgp_sym_decrypt(msg bytea, psw text [, options text ]) returns text
pgp_sym_decrypt_bytea(msg bytea, psw text [, options text ]) returns bytea

PGP 메시지(msg)를 지정한 대칭 키(psw)로 복호화 한다.

복호화 되는 자료가 이진 자료라면, pgp_sym_decrypt 함수로는 복호화 할 수 없다. 이는 자료에 잘못된 문자가 있어 출력이 안되는 경우를 피하기 위함이다. 반대로 복호화 되는 자료가 문자열이다면, pgp_sym_decrypt_bytea 함수로도 복호화 할 수 있다.

options 값은 아래에서 자세히 설명한다.

F.25.3.3. pgp_pub_encrypt()

pgp_pub_encrypt(data text, key bytea [, options text ]) returns bytea
pgp_pub_encrypt_bytea(data bytea, key bytea [, options text ]) returns bytea

data 값을 PGP 공개 키인 key 값으로 암호화 한다. 이 함수에 비밀 키를 지정하면 오류를 낸다.

options 값은 아래에서 자세히 설명 한다.

F.25.3.4. pgp_pub_decrypt()

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

공개 키로 암호화 된 내용을 복호화 한다. key 값은 암호화 할 때 사용한 공개 키와 쌍이 되는 비밀 키를 사용한다. 그 비밀 키에 비밀번호를 지정했다면, psw 인자 값으로 그 비밀번호를 지정해야 한다. 비밀번호는 없는데, options 인자 값을 지정해야 한다면, 비밀번호로 빈 문자열을 지정한다.

복호화 되는 자료가 이진 자료라면, pgp_pub_decrypt 함수로는 복호화 할 수 없다. 이는 자료에 잘못된 문자가 있어 출력이 안되는 경우를 피하기 위함이다. 반대로 복호화 되는 자료가 문자열이다면, pgp_pub_decrypt_bytea 함수로도 복호화 할 수 있다.

options 값은 아래에서 자세히 설명 한다.

F.25.3.5. pgp_key_id()

pgp_key_id(bytea) returns text

pgp_key_id 함수는 PGP 공개 키나 비밀 키에서 키 ID를 추출한다. 인자가 암호화 된 메시지라면 그 암호화에 사용된 키 ID를 구한다.

반환 값으로 두 개의 특수 ID가 있다:

  • SYMKEY

    대칭 키로 암호화 되었음을 뜻한다.

  • ANYKEY

    공개 키로 암호화를 했지만, 키 ID를 빼버린 경우를 뜻한다. 이 경우라면, 가지고 있는 모든 비밀 키로 풀릴 때까지 복호화를 시도해 보아야 한다. pgcrypto 모듈을 이용해서 암호화를 하는 경우는 그 자료를 뽑아서 임의로 키 ID를 빼지 않는 이상 임의로 빼지는 않는다.

전혀 다른 키의 ID가 같은 경우가 있을 수도 있음을 기억해야 한다. 이 경우는 드문 경우이나, 절대로 일어나지 않는 일은 아니다. 클라이언트 응용 프로그램에서는 이 경우를 감안 해서, ANYKEY ID인 경우에 대한 적당한 작업을 염두해 두어야 한다.

F.25.3.6. armor(), dearmor()

armor(data bytea [ , keys text[], values text[] ]) returns text
dearmor(data text) returns bytea

PGP ASCII-armor 형식 자료(CRC 값을 가지는 Base64 인코딩 자료나, 그 외 다른 형태)와 이진 자료간의 자료형식 변환 함수들.

keys, values 인자 값으로 사용되는 문자형 배열은 armor 헤더에 key/value 쌍으로 각각 추가 된다. 두 배열 모두 일차원 배열이어야 하며, 배열의 요수 개수는 같아야 한다. key/value 모두 ASCII 문자로만 구성되어야 한다.

F.25.3.7. pgp_armor_headers

pgp_armor_headers(data text, key out text, value out text) returns setof record

pgp_armor_headers() 함수는 입력한 data에서 armor 헤더를 추출하는 함수다. 리턴 자료형은 집합형으로 key, value 두개의 칼럼으로 구성된다. key 또는 value 값으로 ASCII 문자들이 아닌 것이 있다면, UTF-8 인코딩 문자로 간주한다.

F.25.3.8. PGP 함수에서 사용하는 옵션 설명

옵션 인자에 사용하는 문자열은 GnuPG에서 사용하는 것과 비슷하다. 하나의 옵션은 옵션 이름과 그 값으로 등호(=) 문자를 이용해서 지정하며, 각각의 옵션은 쉼표(,) 문자로 구분한다. 사용 예:

pgp_sym_encrypt(data, psw, 'compress-algo=1, cipher-algo=aes256')

convert-crlf 옵션을 제외한 모든 옵션은 암호화 함수에서만 적용된다. 복호화 함수에서는 PGP 자료에 포함 되어 있는 옵션 값을 사용한다.

사용자가 관심 가질만한 옵션은 compress-algounicode-mode 정도다. 나머지 옵션들은 대부분 기본값을 사용한다.

F.25.3.8.1. cipher-algo

암복호화에 사용할 알고리즘


사용할 수 있는 값: bf, aes128, aes192, aes256 (OpenSSL 전용: 3descast5)
기본값: aes128
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt

F.25.3.8.2. compress-algo

자료 압축용 알고리즘. PostgreSQL 서버가 zlib 라이브러리를 사용하도록 만들어졌을 때만 사용 할 수 있다.


사용할 수 있는 값:
  0 - 압축 안함
  1 - ZIP 압축
  2 - ZLIB 압축 (= ZIP + 메타데이터 + 블록 CRC)
기본값: 0
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt

F.25.3.8.3. compress-level

압축 강도. 값이 크면 압축을 많이 해서 그 크기가 더 줄고, 0 이면 압축하지 않는다.


사용할 수 있는 값: 0, 1-9
기본값: 6
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt

F.25.3.8.4. convert-crlf

암호화 할 때 \n 문자를 \r\n 문자로 바꿀 것인지, 복호화 할 때 다시 \r\n 문자를 \n 문자로 바꿀 것인지를 지정한다. RFC 4880 규약에서는 줄바꿈 문자는 \r\n 문자를 사용하도록 명시하고 있다. (유닉스 계열 환경에서는) 이 규약을 지키려면, 이 옵션을 사용해야 한다.


사용할 수 있는 값: 0, 1
기본값: 0
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt, pgp_sym_decrypt, pgp_pub_decrypt

F.25.3.8.5. disable-mdc

SHA-1 해시 작업으로 자료를 보호하는 작업을 안한다. 사용하는 PGP 응용 프로그램이 아주 오래된 경우에 그곳에서도 사용할 수 있도록 하려면, 이 옵션 값을 1로 한다. 하지만, 패킷 보호를 위해 SHA-1 해시 값을 추가 하는 것은 RFC 4880 규약이다. gnupg.org, pgp.com 사이트에서 소개하는 요즘 대부분 소프트웨어는 SHA-1 해시 값이 포함되어 있는 것으로 간주하고 처리한다.


사용할 수 있는 값: 0, 1
기본값: 0
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt

F.25.3.8.6. sess-key

Use separate session key. Public-key encryption always uses a separate session key; this option is for symmetric-key encryption, which by default uses the S2K key directly.


사용할 수 있는 값: 0, 1
기본값: 0
사용 가능한 함수: pgp_sym_encrypt

F.25.3.8.7. s2k-count

The number of iterations of the S2K algorithm to use. It must be a value between 1024 and 65011712, inclusive.


Default: A random value between 65536 and 253952
Applies to: pgp_sym_encrypt, only with s2k-mode=3

F.25.3.8.8. s2k-mode

사용할 S2K 알고리즘


사용할 수 있는 값:
  0 - 소금 안침.  위험함!
  1 - 소금을 치나, 반복 횟수가 고정 됨.
  3 - 다양한 반복 횟수.
기본값: 3
사용 가능한 함수: pgp_sym_encrypt

F.25.3.8.9. s2k-digest-algo

S2K 계산에서 사용할 다이제스트 알고리즘.


사용할 수 있는 값: md5, sha1
기본값: sha1
사용 가능한 함수: pgp_sym_encrypt

F.25.3.8.10. s2k-cipher-algo

세션 키 분리 암복호화 알고리즘.


사용할 수 있는 값: bf, aes, aes128, aes192, aes256
기본값: use cipher-algo
사용 가능한 함수: pgp_sym_encrypt

F.25.3.8.11. unicode-mode

데이터베이스 인코딩이 UTF-8이 아닌 경우, 그 인코딩을 변환을 자동으로 할 것인지 지정한다. 이 옵션 값으로 0을 지정하면 자동 변환을 하지 않는다.


사용할 수 있는 값: 0, 1
기본값: 0
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt

F.25.3.9. GnuPG를 이용한 PGP 키 만들기

새로운 키를 만드는 방법:

gpg --gen-key

선호하는 키 종류는 DSA와 Elgamal이다.

RSA 암호화를 사용하려면, 먼저 서명 전용 DSA 또는 RSA 키를 마스터로 만들고, 그것에 RSA 암호화 하위키를 gpg --edit-key 명령을 이용해서 추가 한다.

키 목록을 보려면:

gpg --list-secret-keys

ASCII-armor 형식 자료에서 공개 키를 추출하려면:

gpg -a --export KEYID > public.key

ASCII-armor 형식 자료에서 비밀 키를 추출하려면:

gpg -a --export-secret-keys KEYID > secret.key

ASCII-armor 형식 자료를 PGP 함수에서 사용하려면, 먼저 dearmor() 함수를 이용해서 이진 자료로 변환해야 한다. 또는 그 자료가 이진 자료였다면, gpg 명령에서 -a 옵션을 빼고 사용해야 한다.

자세한 도움말은 man gpg 명령을 이용하거나, The GNU Privacy Handbook 웹 페이지를 살펴 보거나, https://www.gnupg.org 사이트에 있는 문서를 살펴 보면 된다.

F.25.3.10. PGP 코드의 한계

  • 전자 서명을 지원하지 않는다. 이것은 암호화된 하위 키가 마스터 키에 종속적인지를 확인할 방법이 없음을 뜻한다.

  • 마스터 키의 암호화를 지원하지 않는다. 이것은 별로 문제 되지 않는다.

  • 여러 개의 하위 키를 사용할 수 없다. 일반적인 상황에서는 문제가 될 것 같지만, 한편으로 생각하면, pgcrypto 모듈에서 제공하는 함수를 이용해서 일반적인 GPG/PGP 키 조작 처리는 하지 않는다. 각각의 상황에 맞게 키를 제공하는 응용 프로그램을 통해서 만든다면, 별로 문제 될 것도 없다.

F.25.4. 저수준 암복호화 함수

자료를 암호화 하거나 복호화 하는 가장 기반 함수들이다. PGP 암호화에서 소개한 확장된 기능들이 전혀 없다. 그래서 다음과 같은 문제점을 고려해야 한다:

  1. 암복호화 하는 키는 사용자가 직접 지정한다.

  2. 이 함수들은 지능적인 확인 작업을 제공하지 않는다. 그래서, 암호화된 자료가 조작되었는지 알 수 없다. (복호화가 된 자료가 원본가 같은지 확인할 길이 없다. - 옮긴이)

  3. 이 함수들은 암복호화 과정에 필요한 모든 옵션을 사용자가 모두 관리해야 한다. IV 까지도!

  4. 이 함수들은 text 자료형으로 처리하지 않는다.

그래서, 이런 저런 것을 신경 쓰기 싫다면, 앞에서 소개한 PGP 암복호화 함수를 이용하는 것이 편하다. (여기서 소개하는 함수는 암호화 솔루션을 직접 개발하고자 할 때 유용하게 사용될 것이다. - 옮긴이)

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

type 값으로 지정한 암호화 기법으로 자료를 암복호화한다. type 값은 다음 형식이다:

알고리즘 [ - 모드 ] [ /pad: 패딩 ]

알고리즘은 다음 중 하나다:

  • bf — Blowfish

  • aes — AES (Rijndael-128, -192, -256)

모드는 다음 중 하나다:

  • cbc — 이전 블록에 따라 다음 블록이 정해짐 (기본값)

  • ecb — 각 블록이 각각 암호화 됨 (실험용)

패딩은 다음 중 하나다:

  • pkcs — 가변 길이 자료 (기본값)

  • none — 자료는 암호 블록의 배수 크기여야 함

윗 설명이 조합 된 사용 예:

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

encrypt_iv 함수와 decrypt_iv 함수에서는 CBC 모드에서 사용할 초기 백터(initial vector) 값을 사용자가 직접 지정할 수 있다. ECB 모드에서는 무시된다. 초기 백터란 원본의 길이가 이 백터 길이의 배수보다 모자랄 때, 나머지를 채우는 값으로 사용된다. 이 인자를 사용하지 않는 함수의 IV 값은 모두 0x00 값으로 채워진다.

F.25.5. 난수 생성 함수

gen_random_bytes(count integer) returns bytea

지정한 count 값만큼의 이진값 난수를 만든다. 최대 1024 바이트의 난수를 만든다. 이것은 난수 생성기 자원을 모두 다 써버리는 사태를 막기 위함이다.

gen_random_uuid() returns uuid

버전 4 (임의) UUID 만드는 함수. (구식임, 이 함수는 PostgreSQL 기본 내장 함수로 제공한다.)

F.25.6. 참고

F.25.6.1. 환경설정

pgcrypto 모듈의 빌드 환경은 PostgreSQL configure 스크립트에서 옵션을 어떻게 지정했느냐에 따라 결정된다. 관련 옵션은 --with-zlib 옵션과 --with-openssl 옵션이다.

zlib 라이브러리를 이용해서 컴파일 하면, PGP 암복호화 함수에서 자료 압축을 할 수 있다.

OpenSSL 라이브러리를 이용해서 컴파일 하면, 보다 다양한 암호 알고리즘을 사용할 수 있다. 또한 공개 키를 사용하는 암호화는 큰 숫자를 처리하는데 최적화된 OpenSSL 라이브러리를 이용하는 것이 더 빠르다.

표 F.19. OpenSSL 라이브러리가 제공하거나 안하는 알고리즘 요약

알고리즘모듈 내장 코드OpenSSL에서 제공
MD5yesyes
SHA1yesyes
SHA224/256/384/512yesyes
Other digest algorithmsnoyes (참고 1)
Blowfishyesyes
AESyesyes
DES/3DES/CAST5noyes
Raw encryptionyesyes
PGP Symmetric encryptionyesyes
PGP Public-Key encryptionyesyes

참고:

  1. 사용하는 OpenSSL 라이브러리가 제공하는 기타 제반 다이제스트 알고리즘. 이것들은 암복호화로 사용할 수 없다.

F.25.6.2. NULL 처리

표준 SQL에서는 모든 함수에서 그 인자가 NULL이면, NULL 값을 반환할 수 있다. 그런데, 암복호화 함수가 이것을 허용하면 보안 취약점이 발생한다.

F.25.6.3. 보안 한계점

모든 pgcrypto 함수는 그 데이터베이스 서버 안에서 처리된다. 이 말은 원본 자료와 비밀번호가 pgcrypto 함수와 응용 프로그램 사이에서는 일반 문자열로 처리됨을 의미한다. 즉, 보다 철저한 보안을 위해서는 다음 작업이 함께 되어야 한다:

  1. 데이터베이스와 응용 프로그램이 한 호스트 안에 같이 있든지, 아니면, SSL 통신 구간 암호화를 이용해야 한다.

  2. 시스템 관리자와 데이터베이스 관리자 사이 서로 믿어야 함

이게 안된다면, 암복호화 작업은 응용 프로그램에서 맡는 것이 낫다.

여기서 구현한 함수로는 부 채널 공격을 막을 수는 없다. 예를 들어, pgcrypto에서 제공하는 복호화 함수의 처리 시간은 곧 암호화 되기전 원문의 길이와 비례한다. (이것으로 암호화 기법을 유추해 낸다. - 옮긴이)

F.25.6.4. 유익한 읽을 거리

F.25.6.5. 기술 참고

F.25.7. 만든이

Marko Kreen

pgcrypto 모듈은 다음 소스 코드를 이용했다:

알고리즘만든이원래 소스 코드
DES cryptDavid Burren과 그 외FreeBSD libcrypt
MD5 cryptPoul-Henning KampFreeBSD libcrypt
Blowfish cryptSolar Designerwww.openwall.com
Blowfish cipherSimon TathamPuTTY
Rijndael cipherBrian GladmanOpenBSD sys/crypto
MD5 hash 및 SHA1WIDE ProjectKAME kame/sys/crypto
SHA256/384/512 Aaron D. GiffordOpenBSD sys/crypto
BIGNUM mathMichael J. Frombergerdartmouth.edu/~sting/sw/imath