\df *crypt
psql에서 pgcrypto encrypt
및 decrypt
함수 의 인수 유형을 나타냅니다 ( PgCrypto docs와 마찬가지로 ).
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+-----------------+------------------+--------------------------+--------
...
public | decrypt | bytea | bytea, bytea, text | normal
public | encrypt | bytea | bytea, bytea, text | normal
...
따라서 encrypt
및 decrypt
함수 모두 키가 될 것으로 예상합니다 bytea
. 오류 메시지에 따라 "명시 적 유형 캐스트를 추가해야 할 수도 있습니다".
그러나 Pg 9.1에서는 제대로 작동하므로 표시된 것보다 많은 것이 있다고 생각합니다. 아마도 encrypt
세 개의 인수로 명명 된 다른 함수가 있습니까?
깨끗한 Pg 9.1에서 작동하는 방법은 다음과 같습니다.
regress=# create table demo(pw bytea);
CREATE TABLE
regress=# insert into demo(pw) values ( encrypt( 'data', 'key', 'aes') );
INSERT 0 1
regress=# select decrypt(pw, 'key', 'aes') FROM demo;
decrypt
------------
\x64617461
(1 row)
regress=# select convert_from(decrypt(pw, 'key', 'aes'), 'utf-8') FROM demo;
convert_from
--------------
data
(1 row)
아우가! 아우가! 주요 노출 위험, 극도의 관리자주의가 필요합니다!
BTW, PgCrypto가 실제로 올바른 선택인지 신중하게 생각하십시오. 쿼리의 키가 공개 될 수 있으며 pg_stat_activity
시스템 log_statement
은 오류와 함께 실패한 암호문을 통해 또는 로그를 통해 기록됩니다 . IMO 종종 응용 프로그램에서 암호화를 수행하는 것이 좋습니다 .
이 세션을 감시하고 client_min_messages
활성화하면 로그에 무엇이 표시되는지 확인할 수 있습니다.
regress# SET client_min_messages = 'DEBUG'; SET log_statement = 'all';
regress=# select decrypt(pw, 'key', 'aes') from demo;
LOG: statement: select decrypt(pw, 'key', 'aes') from demo;
LOG: duration: 0.710 ms
decrypt
------------
\x64617461
(1 row)
키 log_min_messages
가 충분히 낮 으면 키에 로그에 노출 될 수 있습니다. 이제 암호화 된 데이터와 함께 서버의 스토리지에 있습니다. 불합격. log_statement
명령문이 로그되도록하는 오류가 발생하거나 사용 가능한 경우 동일한 문제 가 발생 하지 않습니다 auto_explain
.
다음을 통한 노출 pg_stat_activity
도 가능합니다. 두 세션을 열고 :
- S1 :
BEGIN;
- S1 :
LOCK TABLE demo;
- S2 :
select decrypt(pw, 'key', 'aes') from demo;
- S1 :
select * from pg_stat_activity where current_query ILIKE '%decrypt%' AND procpid <> pg_backend_pid();
으악! 열쇠가 다시 간다. LOCK TABLE
권한이없는 공격자가 없이 복제 할 수 있으며 , 정확한 시간을 맞추기가 더 어렵습니다. from에 pg_stat_activity
대한 액세스를 취소 하여 공격을 피할 수 있지만 앱이 액세스하는 유일한 방법을 알지 못하면 키를 DB에 보내는 것이 가장 좋지 않을 수도 있습니다. 그럼에도 불구하고, 나는 싫어한다.pg_stat_activity
public
비밀번호 인 경우 전혀 저장해야합니까?
또한 비밀번호를 저장하는 경우 양방향 암호화하지 마십시오. 모든 가능한 소금 암호라면 해시하고 결과를 저장하십시오 . 일반적으로 비밀번호 일반 텍스트를 복구 할 필요는 없으며 저장된 해시가 사용자가 동일한 소금으로 해시 할 때 사용자가 보낸 비밀번호와 일치하는지 확인하십시오.
인증 된 경우 다른 사람이 대신 해 줄 수 있습니다.
또한 암호를 전혀 저장하지 말고 LDAP, SASL, Active Directory, OAuth 또는 OpenID 공급자 또는 이미 설계되어 작동하는 다른 외부 시스템에 대해 인증하지 마십시오.
자원
그리고 더 많은.