\df *cryptpsql'de pgcrypto encryptve decryptiş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 encryptve decryptiş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_activityve sistem log_statementbir hatayla başarısız olan kripto ifadeleriyle veya aracılığıyla oturum açar. IMO uygulamada kripto yapmak genellikle daha iyidir .
client_min_messagesGü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_messagesyeterince düşük ise , muhtemelen günlüklerde açık anahtar . Şifrelenmiş verilerle birlikte sunucunun deposunda. Başarısız. İfadenin log_statementgünlüğe kaydedilmesine neden olacak bir hata oluşursa veya büyük olasılıkla auto_explainetkinleştirilirse aynı sorun olmaz .
Yoluyla maruz kalma pg_stat_activityda 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 TABLEAyrıcalıklı olmayan bir saldırgan olmadan çoğaltılabilir , doğru zamanlamak daha zordur. Üzerinden gelen pg_stat_activityeriş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_activitypublic
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ı.