코드 수정을 피하고 함수가 NULL
을 오류로 반환하도록하려면 BEGIN ... EXCEPTION
블록을 사용하여 오류를 트 랩핑하는 PL/PgSQL 함수에서 래핑하여이 작업을 수행 할 수 있습니다.
regress=# \set VERBOSITY verbose
regress=# SELECT pgp_sym_decrypt('fred','key');
ERROR: 39000: Wrong key or corrupt data
LOCATION: decrypt_internal, pgp-pgsql.c:607
내가 직접 오류 처리기에서 이것을 사용할 수 있습니다,하지만 난 상징적 인 이름을 사용하는 것을 선호, 그래서 오류 이름을 조회 :
은 처음에는 오류에 대한 SQLSTATE를 얻을이 작업을 수행하려면
Appendix A - Error codes에서 39000과 연결되어 일반 함수 호출 오류
external_routine_invocation_exception
이라는 것을 알게되었습니다. 우리가 좋아할만큼 구체적이지는 않지만 그렇게 할 것입니다.
이제 래퍼 기능이 필요합니다. 이와 같은 것을 정의해야하며 지원하려는 오버로드 된 각 서명에 대해 하나의 함수로 pgp_sym_decrypt
을 정의해야합니다. 예를 들어, text
를 반환 (bytea,text)
양식 :
CREATE OR REPLACE FUNCTION pgp_sym_decrypt_null_on_err(data bytea, psw text) RETURNS text AS $$
BEGIN
RETURN pgp_sym_decrypt(data, psw);
EXCEPTION
WHEN external_routine_invocation_exception THEN
RAISE DEBUG USING
MESSAGE = format('Decryption failed: SQLSTATE %s, Msg: %s',
SQLSTATE,SQLERRM),
HINT = 'pgp_sym_encrypt(...) failed; check your key',
ERRCODE = 'external_routine_invocation_exception';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
나는 DEBUG
수준 메시지에 원래 오류를 preseve을 선택했습니다. 다음은 원본과 래퍼를 비교하여 전체 메시지와 디버그 수준 출력을 표시합니다.
디버그 출력을 활성화하여 RAISE
을 표시합니다. 매개 변수를 포함하여 pgp_decrypt_sym
호출의 원래 쿼리 텍스트도 표시됩니다.
regress=# SET client_min_messages = DEBUG;
는 새로운 자세한 로깅을 사용하는 경우 기능은 여전히 오류를보고 포장하지만, NULL
반환
regress=# SELECT pgp_sym_decrypt_null_on_err('redsdfsfdsfd','bobsdf');
LOG: 00000: statement: SELECT pgp_sym_decrypt_null_on_err('redsdfsfdsfd','bobsdf');
LOCATION: exec_simple_query, postgres.c:860
DEBUG: 39000: Decryption failed: SQLSTATE 39000, Msg: Wrong key or corrupt data
HINT: pgp_sym_encrypt(...) failed; check your key
LOCATION: exec_stmt_raise, pl_exec.c:2806
pgp_sym_decrypt_null_on_err
-----------------------------
(1 row)
실패 원본에 비해 :
regress=# SELECT pgp_sym_decrypt('redsdfsfdsfd','bobsdf');
LOG: 00000: statement: SELECT pgp_sym_decrypt('redsdfsfdsfd','bobsdf');
LOCATION: exec_simple_query, postgres.c:860
ERROR: 39000: Wrong key or corrupt data
LOCATION: decrypt_internal, pgp-pgsql.c:607
참고 모두 있음 양식은 실패했을 때 함수가 호출 된 매개 변수를 보여줍니다.. 매개 변수는 바인드 매개 변수 ("준비된 명령문")를 사용한 경우 표시되지 않지만 데이터베이스 내 암호화를 사용하는 경우 로그가 보안 위험으로 간주해야합니다.
개인적으로 나는 앱에서 암호를하는 것이 더 좋다고 생각하기 때문에 DB는 결코 키에 액세스 할 수 없습니다.
답변 해 주셔서 감사합니다.나는 최후의 수단으로 이런 종류의 기능을 구현하기로 결정했다. 실제로 매우 유용합니다. 나는 in-build pgsql 함수를 최대한 활용하려고 노력 중이다. 그게 얼마나 도움이되는지 봅시다. 또한 앱의 모든 암호를 수행 할 것을 제안 해 주셔서 감사합니다. 내가 이미 앱에서 몇 가지 중요한 기능을 변경하려고 계획 한 방법입니다. 나중에 모든 것을 바꿀 것입니다. –
@ user1365983 좋은 생각입니다. 아주 좋은 생각이라고 생각하지 않습니다. 그렇게하기를 계획하지 않았기 때문에 기쁩니다. 도움이된다면 답을 수락하십시오. 왼쪽 상단에있는 답 점수 아래의 체크를 사용하십시오. –