Co to jest SCRAM? Uwierzytelnianie SCRAM-SHA-256 wyjaśnione prosto
Co to jest SCRAM i jak działa SCRAM-SHA-256? Wyjaśniamy mechanizm logowania bez wysyłania hasła, jego zalety nad MD5 i konfigurację w PostgreSQL oraz Kafce.

W skrócie
- SCRAM (Salted Challenge Response Authentication Mechanism) to mechanizm uwierzytelniania hasłem, w którym hasło ani jego skrót nie są przesyłane przez sieć.
- Serwer przechowuje tylko sól, liczbę iteracji i dwa klucze pochodne (StoredKey, ServerKey), a nie samo hasło.
- Uwierzytelnianie jest wzajemne: klient sprawdza też, czy serwer naprawdę zna dane użytkownika.
- SCRAM-SHA-256 jest domyślny w PostgreSQL od wersji 14 i obsługują go m.in. MongoDB, Apache Kafka, serwery XMPP i poczty.
- SCRAM nie zastępuje TLS — szyfrowania połączenia nadal potrzebujesz, a wariant -PLUS wiąże logowanie z sesją TLS.
Spis treści
SCRAM (Salted Challenge Response Authentication Mechanism) to mechanizm uwierzytelniania hasłem, w którym ani hasło, ani jego skrót nie trafiają do sieci. Klient udowadnia serwerowi, że zna hasło, odpowiadając na jednorazowe wyzwanie, a serwer w tym samym czasie udowadnia klientowi, że zna jego dane. Dzięki temu przechwycenie logowania nic atakującemu nie daje.
Mechanizm opisano w RFC 5802 (SCRAM-SHA-1) i RFC 7677 (SCRAM-SHA-256). Działa jako tzw. mechanizm SASL, więc spotkasz go w bazach danych (PostgreSQL, MongoDB), brokerach komunikatów (Apache Kafka), serwerach poczty i komunikatorach XMPP. Jeśli trafiłeś tu, szukając metodyki pracy zespołowej, na końcu artykułu znajdziesz krótkie wyjaśnienie różnicy między SCRAM a Scrum.
Co to jest SCRAM i jaki problem rozwiązuje
Klasyczne logowanie hasłem ma dwa słabe punkty. Pierwszy to transmisja: jeśli hasło (albo jego prosty skrót) leci przez sieć, ktoś może je przechwycić i użyć ponownie. Drugi to przechowywanie: jeśli serwer trzyma hasło w postaci, którą da się bezpośrednio wykorzystać do logowania, wyciek bazy oznacza przejęcie kont.
Starsze mechanizmy rozwiązywały tylko jeden z tych problemów. PLAIN wysyła hasło otwartym tekstem (bezpieczne wyłącznie w tunelu TLS). CRAM-MD5 i DIGEST-MD5 nie wysyłały hasła, ale wymagały, żeby serwer znał je w postaci jawnej lub równoważnej. Uwierzytelnianie md5 w PostgreSQL przechowywało skrót, który sam w sobie wystarczał do zalogowania się.
SCRAM łączy oba wymagania:
- hasło nie jest wysyłane, a każda wymiana jest inna dzięki losowym wartościom (nonce),
- serwer przechowuje tylko dane pochodne, z których nie da się bezpośrednio zalogować,
- skrót hasła jest „solony” i wielokrotnie przeliczany (PBKDF2), co spowalnia łamanie słownikowe,
- uwierzytelnianie jest wzajemne — fałszywy serwer bez danych użytkownika nie przejdzie weryfikacji po stronie klienta.
Jeśli chcesz odświeżyć podstawy, zajrzyj do tekstów o funkcjach skrótu kryptograficznego i hashowaniu z solą — SCRAM korzysta z obu tych idei.
Co serwer przechowuje zamiast hasła
Przy ustawianiu hasła serwer (lub klient, np. polecenie \password w psql) wylicza z niego kilka wartości:
SaltedPassword = PBKDF2(HMAC-SHA-256, hasło, sól, liczba_iteracji)ClientKey = HMAC(SaltedPassword, "Client Key")StoredKey = SHA-256(ClientKey)ServerKey = HMAC(SaltedPassword, "Server Key")
W bazie zostają tylko: sól, liczba iteracji, StoredKey i ServerKey. Samego hasła ani ClientKey serwer nie zna. W PostgreSQL wygląda to tak (kolumna rolpassword w pg_authid):
SCRAM-SHA-256$4096:<sól w base64>$<StoredKey w base64>:<ServerKey w base64>
StoredKey to skrót z ClientKey, więc znając go, nie da się po prostu „podać” go serwerowi jako dowodu — trzeba mieć ClientKey, a ten powstaje wyłącznie z hasła.
Jak działa logowanie SCRAM krok po kroku
Cała wymiana to cztery komunikaty. Przykład dla SCRAM-SHA-256:
- client-first-message — klient wysyła nazwę użytkownika i losowy nonce, np.
n,,n=user,r=rOprNGfwEbeRWgbNEkqO. - server-first-message — serwer dokleja swój nonce i odsyła sól oraz liczbę iteracji:
r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,s=W22ZaJ0SNY7soEsUEjb6gQ==,i=4096. - client-final-message — klient sam wylicza
SaltedPassword,ClientKeyiStoredKey, a następnie podpis:ClientSignature = HMAC(StoredKey, AuthMessage). Wysyła dowódClientProof = ClientKey XOR ClientSignature(polep=). - server-final-message — serwer liczy ten sam podpis ze swojego
StoredKey, „odejmuje” go od dowodu (XOR), dostajeClientKey, haszuje go i porównuje zeStoredKey. Jeśli się zgadza, odsyła własny podpisServerSignature = HMAC(ServerKey, AuthMessage)(polev=), który klient weryfikuje.
AuthMessage to sklejone treści wszystkich wcześniejszych komunikatów, łącznie z oboma nonce. Dlatego każdy dowód jest ważny tylko dla tej jednej sesji — powtórzenie przechwyconej wymiany (replay attack) nie zadziała.
W komunikacie 3 widać też pole c=biws — to zakodowany w base64 nagłówek n,,, czyli informacja, że klient nie używa wiązania z kanałem TLS. W wariancie z channel binding w tym miejscu trafiają dane z sesji TLS.
Warianty: SCRAM-SHA-1, SCRAM-SHA-256, SCRAM-SHA-512 i -PLUS
| Wariant | Gdzie opisany | Uwagi |
|---|---|---|
| SCRAM-SHA-1 | RFC 5802 | Najstarszy, wciąż obecny m.in. w XMPP i MongoDB; w nowych wdrożeniach wybieraj SHA-256 |
| SCRAM-SHA-256 | RFC 7677 | Standard de facto: PostgreSQL, MongoDB 4.0+, Kafka, Dovecot |
| SCRAM-SHA-512 | szkic IETF | Obsługiwany m.in. przez Apache Kafka i część serwerów XMPP |
| SCRAM-…-PLUS | RFC 5802, RFC 9266 | Wariant z channel binding — logowanie powiązane z konkretną sesją TLS |
Wariant -PLUS warto znać szczególnie. Bez niego atakujący, który przechwyci połączenie TLS (np. podstawionym certyfikatem), może pośredniczyć w logowaniu. Channel binding dokłada do AuthMessage informację o sesji TLS (tls-server-end-point lub dla TLS 1.3 tls-exporter), więc dowód wygenerowany w jednym połączeniu nie zadziała w innym.
SCRAM w PostgreSQL: jak przejść z MD5 na scram-sha-256
PostgreSQL obsługuje SCRAM-SHA-256 od wersji 10, a od wersji 14 jest to domyślna wartość password_encryption. W PostgreSQL 18 uwierzytelnianie MD5 zostało oficjalnie oznaczone jako przestarzałe, więc jeśli w starszej instalacji nadal masz hasła MD5, to dobry moment na migrację.
- Sprawdź, którzy użytkownicy mają jeszcze hasła w starym formacie:
SELECT rolname,
CASE WHEN rolpassword LIKE 'SCRAM-SHA-256$%' THEN 'scram'
WHEN rolpassword LIKE 'md5%' THEN 'md5'
ELSE 'brak/inne' END AS format
FROM pg_authid
WHERE rolcanlogin;
- Upewnij się, że nowe hasła będą zapisywane jako SCRAM (w
postgresql.conflub dla sesji):
SET password_encryption = 'scram-sha-256';
- Ustaw ponownie hasła użytkownikom z formatem
md5. Najbezpieczniej w psql poleceniem\password nazwa_uzytkownika— hasło jest wtedy haszowane po stronie klienta i nie trafia do logów serwera. - W pliku
pg_hba.confzmień metodę zmd5nascram-sha-256, np.:
hostssl all all 10.0.0.0/24 scram-sha-256
- Przeładuj konfigurację:
SELECT pg_reload_conf();lubsystemctl reload postgresql.
Wskazówka: Metoda
md5wpg_hba.confakceptuje także hasła zapisane jako SCRAM. Możesz więc najpierw zmienić hasła wszystkim użytkownikom, a dopiero na końcu przełączyćpg_hba.confnascram-sha-256— bez przestoju dla aplikacji.
Od PostgreSQL 16 liczbę iteracji PBKDF2 zmienisz parametrem scram_iterations (domyślnie 4096). Wyższa wartość utrudnia łamanie wykradzionych hashy, ale spowalnia każde logowanie, co ma znaczenie przy aplikacjach otwierających wiele połączeń bez puli.
Typowe błędy po włączeniu SCRAM
SCRAM authentication requires libpq version 10 or above— klient lub sterownik jest za stary. Zaktualizuj libpq, sterownik JDBC, psycopg, Npgsql itd. do wersji wspierającej SCRAM.password authentication failedpo zmianiepg_hba.conf— użytkownik ma nadal hasło w formacie MD5. Ustaw je ponownie przypassword_encryption = 'scram-sha-256'.- Pooler (np. PgBouncer) odrzuca logowanie — starsze wersje i konfiguracje
auth_typemusiały zostać dostosowane do SCRAM; sprawdź dokumentację swojej wersji poolera.
Aby wymusić po stronie klienta wiązanie z TLS, w łańcuchu połączenia libpq (PostgreSQL 13+) dodaj channel_binding=require — klient odmówi wtedy logowania do serwera, który nie potrafi przeprowadzić SCRAM-SHA-256-PLUS.
SCRAM w Apache Kafka, MongoDB i innych usługach
Apache Kafka
Kafka obsługuje SASL/SCRAM-SHA-256 i SASL/SCRAM-SHA-512. Dane logowania tworzysz narzędziem kafka-configs.sh:
kafka-configs.sh --bootstrap-server localhost:9092 --alter \
--add-config 'SCRAM-SHA-512=[iterations=8192,password=TwojeHaslo]' \
--entity-type users --entity-name aplikacja1
W konfiguracji klienta ustawiasz sasl.mechanism=SCRAM-SHA-512 i security.protocol=SASL_SSL. Dokumentacja Kafki wprost zaleca łączenie SCRAM z TLS.
MongoDB
MongoDB używa SCRAM jako domyślnego mechanizmu uwierzytelniania: SCRAM-SHA-1 od wersji 3.0, SCRAM-SHA-256 od wersji 4.0. Mechanizm wybierasz parametrem authMechanism w adresie połączenia, np. authMechanism=SCRAM-SHA-256.
Poczta i komunikatory
W serwerach IMAP/SMTP (np. Dovecot) SCRAM działa jako jeden z mechanizmów SASL obok PLAIN i LOGIN. W XMPP SCRAM-SHA-1 jest mechanizmem obowiązkowym według RFC 6120, a nowoczesne serwery oferują też SCRAM-SHA-256 i warianty -PLUS.
Ograniczenia SCRAM — przed czym nie chroni
SCRAM jest dużym krokiem naprzód względem MD5 i PLAIN, ale ma granice:
- Słabe hasło nadal jest słabe. Wykradziony wpis z bazy (sól, iteracje, klucze) pozwala na atak słownikowy offline. PBKDF2 z 4096 iteracjami to umiarkowane spowolnienie — narzędzia takie jak Hashcat radzą sobie z prostymi hasłami szybko.
- Wyciek bazy + podsłuch = przejęcie konta. Kto ma
StoredKeyi przechwyci jedną poprawną wymianę, może odtworzyćClientKeyi logować się jako użytkownik. Dlatego połączenie musi być szyfrowane TLS. - Kradzież
ServerKeypozwala podszyć się pod serwer wobec klientów tego użytkownika. - Nie chroni przed phishingiem i keyloggerami. Jeśli hasło wycieknie u źródła, mechanizm logowania nic nie pomoże. O tym, jak najczęściej się to dzieje, przeczytasz w tekście o sposobach kradzieży haseł.
Ważne: SCRAM to mechanizm uwierzytelniania, nie szyfrowania. Zawsze uruchamiaj go wewnątrz TLS, a tam, gdzie klient to wspiera, wymuszaj wariant z channel binding.
Tam, gdzie to możliwe, warto dołożyć drugi składnik albo przejść na uwierzytelnianie bez haseł — certyfikaty klienta, Kerberos w środowiskach Active Directory lub klucze FIDO2 w aplikacjach webowych.
SCRAM czy Scrum? Częsta pomyłka w wyszukiwarce
Wiele osób wpisujących „scram” szuka w rzeczywistości Scruma — zwinnej metody organizacji pracy zespołu. To zupełnie inny temat:
- Scrum to framework zarządzania projektami opisany w Scrum Guide. Praca dzieli się na sprinty (zwykle 1–4 tygodnie), a zespół tworzą Product Owner, Scrum Master i Developerzy. Artefakty to Product Backlog, Sprint Backlog i Increment, a wydarzenia to Sprint, Sprint Planning, Daily Scrum, Sprint Review i Sprint Retrospective.
- SCRAM w informatyce to opisany wyżej mechanizm logowania.
- SCRAM w energetyce jądrowej to nazwa awaryjnego wyłączenia reaktora (szybkie wprowadzenie prętów kontrolnych).

Jeśli więc w dokumentacji bazy danych, brokera komunikatów lub serwera poczty widzisz „SCRAM-SHA-256”, chodzi o bezpieczne uwierzytelnianie hasłem — i w nowych wdrożeniach to właśnie ten mechanizm powinien być Twoim domyślnym wyborem.
Najczęściej zadawane pytania
Co to jest SCRAM-SHA-256?
To wariant mechanizmu SCRAM opisany w RFC 7677, który używa funkcji skrótu SHA-256 i PBKDF2 z HMAC-SHA-256. Jest obecnie zalecanym sposobem logowania hasłem m.in. w PostgreSQL.
Czy SCRAM jest bezpieczniejszy niż MD5 w PostgreSQL?
Tak. Przy MD5 skrót zapisany w bazie wystarczy do zalogowania się, a sam algorytm jest szybki do łamania. SCRAM używa soli i wielu iteracji, a przechwycona wymiana nie pozwala zalogować się ponownie.
Czy SCRAM szyfruje połączenie?
Nie. SCRAM chroni tylko proces logowania. Dane przesyłane po zalogowaniu nadal trzeba szyfrować TLS, najlepiej z channel binding (SCRAM-SHA-256-PLUS).
Co oznacza błąd „SCRAM authentication requires libpq version 10 or above”?
Twój klient lub sterownik PostgreSQL jest zbyt stary i nie obsługuje SCRAM. Zaktualizuj bibliotekę libpq lub sterownik aplikacji do wersji zgodnej z PostgreSQL 10 lub nowszym.
Czy SCRAM to to samo co Scrum?
Nie. SCRAM to mechanizm uwierzytelniania w informatyce, a Scrum to zwinna metoda zarządzania pracą zespołu. Nazwy są często mylone ze względu na podobną pisownię.
Autor
Założyciel i redaktor XAD.pl. Pisze o sieciach, bezpieczeństwie IT, administracji systemami Windows i Linux oraz o sprzęcie, który sprawia ludziom problemy na co dzień.


