\df *crypt
psql'de pgcrypto encrypt
ve decrypt
işlevlerin bağımsız değişken türlerini ( PgCrypto belgeleri gibi ) gösterir:
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
...
böylece hem encrypt
ve decrypt
işlevleri anahtarın olmasını bekler bytea
. Hata iletisine göre, "açık tür yayınlar eklemeniz gerekebilir".
Ancak, burada Pg 9.1 üzerinde iyi çalışıyor, bu yüzden gösterdiğinizden daha fazlası olduğundan şüpheleniyorum. Belki de encrypt
üç argümanla adlandırılmış başka bir fonksiyonunuz var mı?
Temiz bir Pg 9.1 üzerinde nasıl çalıştığı aşağıda açıklanmıştır:
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)
Awooga! Awooga! Başlıca maruz kalma riski, aşırı idari önlem gereklidir!
BTW, lütfen PgCrypto'nun gerçekten doğru seçim olup olmadığını dikkatlice düşünün. Sorgularınızdaki anahtarlar açığa çıkarılabilir pg_stat_activity
ve sistem log_statement
bir hatayla başarısız olan kripto ifadeleriyle veya aracılığıyla oturum açar. IMO uygulamada kripto yapmak genellikle daha iyidir .
client_min_messages
Günlüklerde nelerin görüneceğini görebilmeniz için bu oturuma etkin olarak tanık olun:
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)
Hata! Eğer log_min_messages
yeterince düşük ise , muhtemelen günlüklerde açık anahtar . Şifrelenmiş verilerle birlikte sunucunun deposunda. Başarısız. İfadenin log_statement
günlüğe kaydedilmesine neden olacak bir hata oluşursa veya büyük olasılıkla auto_explain
etkinleştirilirse aynı sorun olmaz .
Yoluyla maruz kalma pg_stat_activity
da mümkündür .. İki oturum açın ve:
- 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();
Tüh! Anahtar yine gidiyor. LOCK TABLE
Ayrıcalıklı olmayan bir saldırgan olmadan çoğaltılabilir , doğru zamanlamak daha zordur. Üzerinden gelen pg_stat_activity
erişimi iptal ederek saldırı önlenebilir , ancak uygulamanızın erişen tek şey olduğunu bilmediğiniz sürece anahtarınızı DB'ye göndermenin en iyi yol olmayabileceğini gösterir. O zaman bile sevmem.pg_stat_activity
public
Parolalarsa, bunları saklamanız gerekir mi?
Ayrıca, şifreleri saklıyorsanız, bunları iki yönlü şifrelemeyin; tuz şifreleri mümkün olduğunda bunları kesin ve sonucu saklayın . Genellikle parola açık metnini kurtaramazsınız, yalnızca depolanan karmanın, kullanıcının aynı tuzla karıklandığında oturum açmanız için gönderdiği şifreyle eşleştiğini onaylayın.
Eğer doğruysa, başkasının sizin için yapmasına izin verin
Daha da iyisi, şifreyi hiç saklamayın, LDAP, SASL, Active Directory, bir OAuth veya OpenID sağlayıcısına veya önceden tasarlanmış ve çalışan başka bir harici sistemde kimlik doğrulaması yapmayın.
kaynaklar
ve daha fazlası.