(Obs! Jag är ingen säkerhetsexpert. Jag har ett intresse för området, men det är det. Ha det i åtanke.)
Om möjligt, spara inga lösenord alls
Det beror mycket på vad du har för behov. Det bästa alternativet av allt är att inte använda tvåvägskryptering alls; om du bara kan lagra saltad och envägs-hashad lösenordssammandrag som är idealiskt. Du kan fortfarande testa dem för att se om de matchar ett lösenord som användaren har fått, men du lagrar det aldrig.
Ännu bättre, om dina kunder använder något förnuftigt protokoll (dvs. inte HTTP som vanligt implementerat) kan du använda en mekanism för autentisering av utmaning-svar det betyder att din app aldrig någonsin måste se användarens lösenord, inte ens när de autentiseras. Tyvärr är detta sällan möjligt på den offentliga webben, som har säkerhet som skulle göra 80-talsprogrammerare på skam.
Om du måste lagra lösenordet, isolera nycklarna från appen
Om du måste kunna dekryptera lösenorden bör du helst inte ha alla detaljer för att göra det på ett ställe, och absolut inte en kopierbar, lättillgänglig plats.
Av den anledningen skulle jag personligen föredra att inte använda PgCrypto (som du gör) för detta ändamål eftersom det tvingar dig att avslöja den privata nyckeln och (om den har en) lösenordsfras till servern, där den kan exponeras i PostgreSQL:s loggfiler eller på annat sätt potentiellt sniffade. Jag skulle vilja göra min kryptoklientsida, där jag kunde använda PKCS#11, en nyckelagent eller andra verktyg som låter mig dekryptera data utan att någonsin ha min kod åtkomst till nyckeln.
Problemet med säker nyckellagring är en del av vad PKCS#11 uppfanns för. Det tillhandahåller ett generiskt gränssnitt för applikationer och kryptoleverantörer att prata med allt som kan tillhandahålla vissa signerings- och dekrypteringstjänster utan att någonsin avslöja nyckeln . Den vanliga, men inte bara, användningen är med hårdvarubaserad krypto som smarta kort och hårdvarukryptomoduler. Sådana enheter kan uppmanas att signera eller dekryptera data som skickas till dem, och kan göra det utan att någonsin avslöja nyckeln. Om möjligt, överväg att använda ett smartkort eller HSM. Så vitt jag vet kan PgCrypto inte använda PKCS#11 eller andra HSM:er/smartkort.
Om du inte kan göra det kan du förmodligen fortfarande använda en nyckelhanteringsagent, där du laddar din nyckel i ett nyckelhanteringsprogram manuellt när servern startar, och nyckelhanteringsprogrammet tillhandahåller ett PKCS#11 (eller något annat) gränssnitt för signering och dekryptering via en socket. På så sätt behöver din webbapp aldrig känna till nyckeln alls. gpg-agent
kan kvalificera sig för detta ändamål. Återigen, så vitt jag vet kan PgCrypto inte använda en nyckelhanteringsagent, även om det skulle vara en bra funktion att lägga till.
Även en liten förbättring kan hjälpa. Det är bäst om lösenordsfrasen för din nyckel inte lagras på disken, så du kan kräva att den skrivs in när appen startas så att nyckeln kan dekrypteras. Du lagrar fortfarande den dekrypterade nyckeln i minnet, men alla detaljer för att dekryptera den finns inte längre på disken och lätta att komma åt. Det är mycket svårare för en angripare att stjäla den dekrypterade nyckeln från minnet än att ta ett "password.txt" från disken.
Vad du väljer att göra beror mycket på detaljerna i dina säkerhetsbehov och vilken data du arbetar med. I din situation skulle jag helt enkelt inte lagra lösenorden om det alls var möjligt, och om jag var tvungen skulle jag vilja använda en PKCS#11-kompatibel hårdvaruenhet.