pgcrypto
모듈은 PostgreSQL에서
사용할 수 있는 암호화 관련 함수를 제공한다.
이 묘듈은 “trusted”, 신뢰할 수 있는 모듈이다. 그래서,
해당 데이터베이스를 대상으로
CREATE
권한이 있는 일반 사용자도 설치할 수
있다.
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;
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()
함수와 같으나, 키 값으로 한 번 더 계산한다.
이 기능은 누군가가 자료를 변경하고 그에 대응하는 해시 값도
바꾸는 문제점을 막는다.
키 값이 해시 블록 크기보다 크다면, 먼저 그것의 해시 값을 구한 뒤 그 값을 키로 사용한다.
비밀번호 해시 작업은 crypt()
함수와
gen_salt()
함수로 구현한다.
crypt()
함수는 해시 작업을 하고,
gen_salt()
함수는 해시 작업 알고리즘을
지정하는데 사용된다.
crypt()
함수는 보통 MD5나 SHA1 알고리즘을
이용한 해시 작업과 달리, 다음의 장점이 있다:
이 함수들은 느리다. 입력 값의 크기가 아주 작을 때, 강제로 비밀번호를 만들 수 있는 유일한 방법이다.
이 함수들은 소금 salt라고 하는 값을 이용해서, 사용자의 같은 입력값에 대해서 다른 암호화된 비밀번호를 만든다. 그래서 복호화가 불가능하게 한다.
이 함수들은 결과 값에 알고리즘 종류를 포함시킨다. 그래서, 각기 다른 알고리즘으로 처리된 값이 공존할 수 있다.
이 함수에서 사용하는 알고리즘 가운데 몇몇은 적응력이 좋다 — 이 말은 사용하는 컴퓨터가 보다 빨라졌을 때, 기존 비밀번호를 모두 초기화 하지 않고, 보다 복잡하게 암호화를 할 수 있음을 뜻 한다.
crypt()
함수에서 지원하는 알고리즘은
표 F.16에서 나열하고 있다.
표 F.16. crypt()
함수에서 지원하는 알고리즘
알고리즘 | 평문 비밀번호 최대 길이 | 적응력 | 소금 비트 | 출력 길이 | 설명 |
---|---|---|---|---|---|
bf | 72 | 있음 | 128 | 60 | Blowfish 기반, variant 2a |
md5 | 제한없음 | 없음 | 48 | 34 | MD5 기반 암호화 |
xdes | 8 | 있음 | 24 | 20 | 확장 DES |
des | 8 | 없음 | 12 | 13 | 전통적인 UNIX crypt |
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
면 입력한 비밀번호가 맞다.
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() 반복 횟수
알고리즘 | 기본값 | 최소 | 최대 |
---|---|---|---|
xdes | 725 | 1 | 16777215 |
bf | 6 | 4 | 31 |
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/8 | 1792 | 4 년 | 3927 년 | 10만배 |
crypt-bf/7 | 3648 | 2 년 | 1929 년 | 5만배 |
crypt-bf/6 | 7168 | 1 년 | 982 년 | 2만5천배 |
crypt-bf/5 | 13504 | 188 일 | 521 년 | 12,500배 |
crypt-md5 | 171584 | 15 일 | 41 년 | 1,000배 |
crypt-des | 23221568 | 157.5 분 | 108 일 | 7 배 |
sha1 | 37774272 | 90 분 | 68 일 | 4배 |
md5 (hash) | 150085504 | 22.5 분 | 17 일 | 1 |
참고 사항:
CPU는 Intel Mobile Core i3.
crypt-des
와 crypt-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개의 문자가 일반 단어와 그 모습이 전혀 다르다면 비밀번호를 찾아내는 시간이 훨씬 오래 걸린다.
여기서 소개하는 함수들은 OpenPGP (RFC 4880) 표준에서 암복화 부분을 구현한 것이다. 대칭키와 공개키 암호화를 모두 지원한다.
암호화된 PGP 메시지는 두 부분 또는 두 패킷 packets 으로 구성된다:
세션 키를 포함하고 있는 패킷 — 대칭키나 공개키로 암호화 됨.
그 세션 키로 암호화 된 자료 패킷.
대칭키(예, 비밀번호)로 암호화 하는 방법:
지정한 비밀번호는 String2Key (S2K) 알고리즘을 이용해 해시 값으로 바꾼다.
이 알고리즘은 crypt()
알고리즘 —
느리고, 임의의 소금용 문자열 사용하는 — 과 비슷하지만 좀 더 단순하다.
하지만 이 알고리즘은 비밀번호 전체를 이진 키로 만든다. (crypt() 함수에서
사용하는 비밀번호의 길이에 대한 것은 윗 부분 참조 - 옮긴이)
세션 키를 분리하고자 한다면, 새 임의의 키가 생성 된다. 한편, S2K 형식의 키를 지정하면, 그것을 바로 세션 키로 사용한다.
S2K 키가 바로 사용되면, S2K 설정만 세션 키 패킷에 포함 된다. 그 밖의 경우는 S2K 키와 세션 키를 암호화해서 세션 키 패킷에 포함 된다.
공개키로 암호화 하는 방법:
임의의 세션 키를 만든다.
그 세션 키를 공개 키로 암호화 해서 세션 키 패킷에 넣는다.
자료 암호화는 다음 작업으로 진행 된다:
선택적 자료 변환 작업: 압축, UTF-8 인코딩으로 변환, 줄바꿈 문자 변환
자료에 임의의 바이트가 추가됨. 이것은 임의 IV 값을 사용하는 것과 같다.
임의의 SHA1 해시 값이 자료 앞에 붙고,
이런 모든 처리가 끝난 다음 세션 키로 암호화 해서 자료 패킷으로 사용한다.
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
값은 아래에서 자세히 설명한다.
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
값은 아래에서 자세히 설명한다.
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
값은 아래에서 자세히 설명 한다.
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
값은 아래에서 자세히 설명 한다.
pgp_key_id()
pgp_key_id(bytea) returns text
pgp_key_id
함수는 PGP 공개 키나 비밀 키에서 키 ID를 추출한다.
인자가 암호화 된 메시지라면 그 암호화에 사용된 키 ID를 구한다.
반환 값으로 두 개의 특수 ID가 있다:
SYMKEY
대칭 키로 암호화 되었음을 뜻한다.
ANYKEY
공개 키로 암호화를 했지만, 키 ID를 빼버린 경우를 뜻한다.
이 경우라면, 가지고 있는 모든 비밀 키로 풀릴 때까지
복호화를 시도해 보아야 한다.
pgcrypto
모듈을 이용해서 암호화를 하는 경우는
그 자료를 뽑아서 임의로 키 ID를 빼지 않는 이상 임의로 빼지는
않는다.
전혀 다른 키의 ID가 같은 경우가 있을 수도 있음을 기억해야 한다.
이 경우는 드문 경우이나, 절대로 일어나지 않는 일은 아니다.
클라이언트 응용 프로그램에서는 이 경우를 감안 해서, ANYKEY
ID인 경우에 대한 적당한 작업을 염두해 두어야 한다.
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 문자로만 구성되어야 한다.
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 인코딩 문자로 간주한다.
옵션 인자에 사용하는 문자열은 GnuPG에서 사용하는 것과 비슷하다. 하나의 옵션은 옵션 이름과 그 값으로 등호(=) 문자를 이용해서 지정하며, 각각의 옵션은 쉼표(,) 문자로 구분한다. 사용 예:
pgp_sym_encrypt(data, psw, 'compress-algo=1, cipher-algo=aes256')
convert-crlf
옵션을 제외한 모든 옵션은
암호화 함수에서만 적용된다. 복호화 함수에서는 PGP 자료에 포함 되어 있는
옵션 값을 사용한다.
사용자가 관심 가질만한 옵션은 compress-algo
과
unicode-mode
정도다. 나머지 옵션들은
대부분 기본값을 사용한다.
암복호화에 사용할 알고리즘
사용할 수 있는 값: bf, aes128, aes192, aes256 (OpenSSL 전용: 3des
, cast5
)
기본값: aes128
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt
자료 압축용 알고리즘. PostgreSQL 서버가 zlib 라이브러리를 사용하도록 만들어졌을 때만 사용 할 수 있다.
사용할 수 있는 값:
0 - 압축 안함
1 - ZIP 압축
2 - ZLIB 압축 (= ZIP + 메타데이터 + 블록 CRC)
기본값: 0
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt
압축 강도. 값이 크면 압축을 많이 해서 그 크기가 더 줄고, 0 이면 압축하지 않는다.
사용할 수 있는 값: 0, 1-9
기본값: 6
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt
암호화 할 때 \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
SHA-1 해시 작업으로 자료를 보호하는 작업을 안한다. 사용하는 PGP 응용 프로그램이 아주 오래된 경우에 그곳에서도 사용할 수 있도록 하려면, 이 옵션 값을 1로 한다. 하지만, 패킷 보호를 위해 SHA-1 해시 값을 추가 하는 것은 RFC 4880 규약이다. gnupg.org, pgp.com 사이트에서 소개하는 요즘 대부분 소프트웨어는 SHA-1 해시 값이 포함되어 있는 것으로 간주하고 처리한다.
사용할 수 있는 값: 0, 1
기본값: 0
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt
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
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
사용할 S2K 알고리즘
사용할 수 있는 값:
0 - 소금 안침. 위험함!
1 - 소금을 치나, 반복 횟수가 고정 됨.
3 - 다양한 반복 횟수.
기본값: 3
사용 가능한 함수: pgp_sym_encrypt
S2K 계산에서 사용할 다이제스트 알고리즘.
사용할 수 있는 값: md5, sha1
기본값: sha1
사용 가능한 함수: pgp_sym_encrypt
세션 키 분리 암복호화 알고리즘.
사용할 수 있는 값: bf, aes, aes128, aes192, aes256
기본값: use cipher-algo
사용 가능한 함수: pgp_sym_encrypt
데이터베이스 인코딩이 UTF-8이 아닌 경우, 그 인코딩을 변환을 자동으로 할 것인지 지정한다. 이 옵션 값으로 0을 지정하면 자동 변환을 하지 않는다.
사용할 수 있는 값: 0, 1
기본값: 0
사용 가능한 함수: pgp_sym_encrypt, pgp_pub_encrypt
새로운 키를 만드는 방법:
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 사이트에 있는 문서를 살펴 보면 된다.
전자 서명을 지원하지 않는다. 이것은 암호화된 하위 키가 마스터 키에 종속적인지를 확인할 방법이 없음을 뜻한다.
마스터 키의 암호화를 지원하지 않는다. 이것은 별로 문제 되지 않는다.
여러 개의 하위 키를 사용할 수 없다. 일반적인 상황에서는 문제가
될 것 같지만, 한편으로 생각하면, pgcrypto
모듈에서
제공하는 함수를 이용해서 일반적인 GPG/PGP 키 조작 처리는 하지 않는다.
각각의 상황에 맞게 키를 제공하는 응용 프로그램을 통해서 만든다면,
별로 문제 될 것도 없다.
자료를 암호화 하거나 복호화 하는 가장 기반 함수들이다. PGP 암호화에서 소개한 확장된 기능들이 전혀 없다. 그래서 다음과 같은 문제점을 고려해야 한다:
암복호화 하는 키는 사용자가 직접 지정한다.
이 함수들은 지능적인 확인 작업을 제공하지 않는다. 그래서, 암호화된 자료가 조작되었는지 알 수 없다. (복호화가 된 자료가 원본가 같은지 확인할 길이 없다. - 옮긴이)
이 함수들은 암복호화 과정에 필요한 모든 옵션을 사용자가 모두 관리해야 한다. IV 까지도!
이 함수들은 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 값으로 채워진다.
gen_random_bytes(count integer) returns bytea
지정한 count
값만큼의 이진값 난수를 만든다.
최대 1024 바이트의 난수를 만든다.
이것은 난수 생성기 자원을 모두 다 써버리는 사태를 막기 위함이다.
gen_random_uuid() returns uuid
버전 4 (임의) UUID 만드는 함수. (구식임, 이 함수는 PostgreSQL 기본 내장 함수로 제공한다.)
pgcrypto
모듈의 빌드 환경은 PostgreSQL configure
스크립트에서 옵션을 어떻게 지정했느냐에 따라 결정된다.
관련 옵션은 --with-zlib
옵션과
--with-openssl
옵션이다.
zlib 라이브러리를 이용해서 컴파일 하면, PGP 암복호화 함수에서 자료 압축을 할 수 있다.
OpenSSL 라이브러리를 이용해서 컴파일 하면, 보다 다양한 암호 알고리즘을 사용할 수 있다. 또한 공개 키를 사용하는 암호화는 큰 숫자를 처리하는데 최적화된 OpenSSL 라이브러리를 이용하는 것이 더 빠르다.
표 F.19. OpenSSL 라이브러리가 제공하거나 안하는 알고리즘 요약
알고리즘 | 모듈 내장 코드 | OpenSSL에서 제공 |
---|---|---|
MD5 | yes | yes |
SHA1 | yes | yes |
SHA224/256/384/512 | yes | yes |
Other digest algorithms | no | yes (참고 1) |
Blowfish | yes | yes |
AES | yes | yes |
DES/3DES/CAST5 | no | yes |
Raw encryption | yes | yes |
PGP Symmetric encryption | yes | yes |
PGP Public-Key encryption | yes | yes |
참고:
사용하는 OpenSSL 라이브러리가 제공하는 기타 제반 다이제스트 알고리즘. 이것들은 암복호화로 사용할 수 없다.
표준 SQL에서는 모든 함수에서 그 인자가 NULL이면, NULL 값을 반환할 수 있다. 그런데, 암복호화 함수가 이것을 허용하면 보안 취약점이 발생한다.
모든 pgcrypto
함수는 그 데이터베이스 서버 안에서 처리된다.
이 말은 원본 자료와 비밀번호가 pgcrypto
함수와
응용 프로그램 사이에서는 일반 문자열로 처리됨을 의미한다. 즉,
보다 철저한 보안을 위해서는 다음 작업이 함께 되어야 한다:
데이터베이스와 응용 프로그램이 한 호스트 안에 같이 있든지, 아니면, SSL 통신 구간 암호화를 이용해야 한다.
시스템 관리자와 데이터베이스 관리자 사이 서로 믿어야 함
이게 안된다면, 암복호화 작업은 응용 프로그램에서 맡는 것이 낫다.
여기서 구현한 함수로는 부
채널 공격을 막을 수는 없다. 예를 들어,
pgcrypto
에서 제공하는 복호화 함수의 처리 시간은 곧
암호화 되기전 원문의 길이와 비례한다. (이것으로 암호화 기법을 유추해 낸다. - 옮긴이)
https://www.gnupg.org/gph/en/manual.html
GNU 개인정보 소책자.
https://www.openwall.com/crypt/
crypt-blowfish 알고리즘 소개.
https://www.iusmentis.com/security/passphrasefaq/
좋은 비밀번호 만드는 방법.
http://world.std.com/~reinhold/diceware.html
비밀번호를 선택하는 재미난 방법.
http://www.interhack.net/people/cmcurtin/snake-oil-faq.html
암호 기술의 장단점.
https://tools.ietf.org/html/rfc4880
OpenPGP 메시지 양식.
https://tools.ietf.org/html/rfc1321
MD5 메시지-다이제스트 알고리즘.
https://tools.ietf.org/html/rfc2104
HMAC: 메시지 인증용 키기반-해시.
https://www.usenix.org/events/usenix99/provos.html
crypt-des, crypt-md5, bcrypt 알고리즘 비교.
https://en.wikipedia.org/wiki/Fortuna_(PRNG)
Fortuna 난수 생성기.
리눅스용 Jean-Luc Cooke Fortuna-기반 /dev/random
드라이버.
Marko Kreen <markokr@gmail.com>
pgcrypto
모듈은 다음 소스 코드를 이용했다:
알고리즘 | 만든이 | 원래 소스 코드 |
---|---|---|
DES crypt | David Burren과 그 외 | 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 hash 및 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 |