Spørsmål:
Hash funksjon endring
h9lpq0u
2012-08-27 19:01:29 UTC
view on stackexchange narkive permalink

Jeg har passord for brukerkontoer lagret i en database ved hjelp av en usikker (gammel) kryptografisk hashfunksjon.

Hva er den beste / vanlige metoden for å endre passordhash-funksjon? Bare to ideer kommer til å tenke meg:

  1. Be alle brukere om å endre passordene ved neste innlogging og hash passordene sine med ny funksjon når de gjør det. Dette er ikke et godt alternativ på grunn av mange problemer (inaktive brukere, lang migreringsperiode, komplisert implementering ...)

  2. Hash de gamle hashverdiene med ny hash-funksjon, og re -skrive metoden for å sjekke passord mot database: newHash (salt + oldHash (salt + passord))

Denne doble hashingen virker for meg som en god idé, både elegant og enkel å implementere.

Jeg vil gjerne vite om det er noen advarsler jeg ikke legger merke til her. Er dette slik dette vanligvis gjøres, eller er det en annen metode? Er det noe kjent kryptografisk sårbarhet ved bruk av output med svak hashfunksjon som input for sterk hashfunksjon.

Hvis det er en god idé, hva med salt? Ville det være greit å bruke det samme saltet til begge hasjfunksjonene? ​​

Andre er mest sannsynlig OK, med mindre `oldHash` er ekstremt dårlig (langt verre enn MD5). Noen mennesker vil anbefale separate salter, men jeg tror ikke det er veldig nødvendig.
Kan du legge ut hva slags hasj du bruker (gammel og ny), og hvordan du genererer saltet?
Old hash er unix crypt (DES-basert) og ny er ikke bestemt ennå. Salt er tilfeldig for hver bruker.
Jeg er ganske sikker på at vi har et duplikat spørsmål her eller på krypto. Men jeg fant det ikke.
@CodesInChaos: Tenker du på [Må jeg beregne alle hashes på nytt hvis jeg endrer arbeidsfaktoren i bcrypt?] (Http://crypto.stackexchange.com/questions/3003/do-i-have-to-recompute-all- hashes-if-i-change-the-work-factor-in-bcrypt)?
Hvis du ikke er bekymret for det ekstra databasesøket, kan du implementere et alternativ for passordhistorikk. Det vil la deg legge til hashing-versjoner for alltid, og også la deg tilbakestille til gamle passord, overvåke endringer osv.
Se også på http://en.wikipedia.org/wiki/Scrypt. Med massivt parallelle GPU- og FPGA-sprekkemaskiner tilgjengelig for bare noen få hundre dollar, er det minne som blir flaskehalsen, ikke ALU-instruksjoner.
Seks svar:
dr jimbob
2012-08-27 19:40:06 UTC
view on stackexchange narkive permalink

Personlig vil jeg sannsynligvis implementere både med at nye brukere får en sterk moderne hash (bcrypt eller annen nøkkelforsterket kryptografisk hash) og gamle brukere som har den svake hashen pakket rundt bcrypt. Før folk klager over ekstra implementeringskompleksitet, er alternativet å alltid tvinge nye brukere til å bruke svak hash-algoritme pakket rundt sterk hash-algoritme, og det betyr at du aldri blir kvitt den opprinnelige ordningen.

Jeg vil ha en eller annen dokumentert indikator av typen hash-ordning som er analog med $ 1 $ , $ 2a $ , $ 5 $ , eller $ 6 $ i krypt (sitat fra kryptsiden):

  Hvis salt er en tegnstreng som begynner med tegnene "$ id $" etter ned av en streng avsluttet med "$": $ id $ salt $ kryptert ... id identifiserer krypteringsmetoden som brukes, og dette bestemmer deretter hvordan resten av passordstrengen tolkes. Følgende verdier av id støttes: ID | Metode ─────────────────────── ──────── 1 | MD5 2a | Blowfish (ikke i hovedlinjen glibc; lagt til i noen | Linux-distribusjoner) 5 | SHA-256 (siden glibc 2.7) 6 | SHA-512 (siden glibc 2.7)  

I dette tilfellet trenger du tre typer passordhash:

  1. De gamle raske svake hashene
  2. Den gamle raske svake hasjen som er pakket rundt en langsom hasj med et sterkt salt
  3. Den nye langsomme hasjen.

På dag 1 vil jeg ta alt fra kategori 1 og flytte det til kategori 2. Nye passord vil bli satt inn i kategori 3. Videre, når folk logger inn, kan du til og med migrere alle vellykkede autentiserte hash fra kategori 2 til kategori 3 mens passordet for ren tekst er i minnet. På et tidspunkt kan du til og med fullstendig eliminere bevis / arv vedlikehold av den svake hashing-ordningen. (For eksempel å tvinge brukere med kontoer som ikke har logget på i over 2 år etter endringen til å tilbakestille passordene sine.)

Jeg liker ideen om å migrere brukere automatisk bak kulissene når de logger på. Kudos.
Hva er fordelen med gradvis migrasjon? Den eneste fordelen jeg ser er at etter en gitt periode vil jeg være i stand til å "pensjonere" den gamle passordordningen. Men hvorfor trenger jeg å gjøre det? Jeg har allerede metodene for å bruke den, så det plager meg ikke.
Thomas Pornin
2012-08-27 20:38:12 UTC
view on stackexchange narkive permalink

Forslaget ditt 2 (ta den gamle hashverdien som "passord" for den nye hashen) er god hvis følgende forhold stemmer:

  • gammel hash er tilstrekkelig motstandsdyktig mot forhåndsbilder.
  • Den nye hashen bruker alle de nødvendige bells'n-fløytene for å betrakte den som "robust" (dvs. det er bcrypt med mange runder, og et nytt tilfeldig salt for hvert passord, inkludert for passordendringer for en gitt bruker).
  • Den gamle hashen kan beregnes effektivt nok til at hele "konfigurerbar treghet" -virksomheten er avhengig av den nye hasjen eksklusivt.

Merk at MD5, selv om den er grundig ødelagt med hensyn til kollisjoner, fremdeles ser ut til å være rimelig sterk når det gjelder forhåndsbilder.

Det vil fortsatt tjene best for deg interesser for å inkludere et "type hash" -felt i databasen din, slik at migrasjoner kan håndteres greit. Du kan for eksempel bruke hash-of-hash, og deretter planlegge en overføring til en passordhashing-ordning som bare bruker den nye hash-passord vil bli oppdatert til den nye ordningen når de blir opprettet eller endret, for en gradvis migrasjon. Senere (si om ett år) kan du konfigurere en tvungen oppdatering (brukeren må oppgi passordet ved neste pålogging) for passordene som fremdeles bruker det gamle formatet.

Selv om du ikke liker migrasjoner ( hvem gjør det?), virker det bare forsvarlig å sørge for en mulig fremtidig migrasjon, hvis forholdene på det tidspunktet tvinger migrasjonen mot deg (f.eks. et ødeleggende kryptanalytisk brudd).

Hva er fordelen med gradvis migrasjon? Den eneste fordelen jeg ser er at etter en gitt periode vil jeg være i stand til å "pensjonere" den gamle passordordningen. Men hvorfor trenger jeg å gjøre det? Jeg har allerede metodene for å bruke den, så det plager meg ikke.
@h9lpq0u Hvis det gamle skjemaet oppdages å være brutt når det gjelder forhåndsbilder, kan det kombinerte passordskjemaet ditt bli usikkert.
Oleksi
2012-08-27 19:13:49 UTC
view on stackexchange narkive permalink

Jeg vil bruke bcrypt som den nye hashen. Ellers bør løsningen din med å "pakke inn" de gamle hasjene være sikre, gitt at du bruker et godt salt for for bcrypt. Jeg har sett denne løsningen fungere et par ganger når systemer vil oppgradere hvordan de hash passordene sine.

Takk. Hvorfor anbefaler du bcrypt over SHA-2 (og snart SHA-3), som er NIST-standard for kryptografisk hash? Er det (bare) fordi bcrypt kan gjøres vilkårlig treg?
Delvis. Bcrypt, og mer generelt adaptive hash-algoritmer, ser ut til å være den nåværende pålitelige løsningen i bransjen. Jeg mistenker at ting som bcrypt vil overleve lenger. For eksempel er det allerede GPU-baserte angrep som kan kompromittere mange SHA-512 hashed-passord.
Kjerneproblemet er det samme; Disse hashmetodene er ment for hashhastighet, som er det motsatte av det du vil ha for en passordhashmetode.
Takk for oppklaringen. Jeg vil definitivt ta det i betraktning.
@h9lpq0u Det er [bare to gode måter å hashe et passord på (kanskje tre hvis du er eventyrlysten)] (http://security.stackexchange.com/a/1164/1983). SHA-2 / SHA-3 er ikke designet for dette.
bcrypt tror jeg er den eneste hashing-funksjonen som ikke kan fremskyndes av GPUer, og heller ikke kompromitteres av kvantedatamaskiner
@h9lpq0u Se [Anbefaler noen sikkerhetseksperter bcrypt for passordlagring?] (Http://security.stackexchange.com/q/4781/836) på dette nettstedet.
@Earlz bcrypt * kan * økes av GPUer, men ikke av en faktor i nærheten av tradisjonelle funksjoner. scrypt er enda bedre på grunn av den minneharde funksjonen. GPUer kan ha mye innebygd RAM, men båndbredden per kjerne kveler ytelsen.
Earlz
2012-08-27 22:49:36 UTC
view on stackexchange narkive permalink

Hvis du ikke vil bry deg med å bruke den gamle hash-funksjonen, men ikke vil tvinge alle til å endre passordet ditt, er det en elegant løsning.

Legg til en kolonne / verdi i hver brukerprofil. La oss ringe hvis HashVersion

Når brukeren går for å logge på for første gang siden overføringen din, vil systemet da kunne oppdage at det bruker den gamle hash-funksjonen. Så hvis passordet som leveres av brukeren samsvarer med hash-en, tar du passordet i ren tekst og hash det med den nye algoritmen din, og tilbakestiller salter og så videre. Og så støter du HashVersion slik at du vet at den nå bruker den nye hash-funksjonen.

Dette er etter min mening den beste løsningen, spesielt hvis din forrige hash-funksjon var veldig usikker.

Mens det ligner på ThomasPornin og mine tidligere svar, etterlater løsningen din svake hashes i databasen til brukeren logger på neste, noe som er mindre enn ideelt, da de gamle hashene kan bli angrepet i mellomtiden hvis hasjene noen gang lekker. Forutsatt at den gamle måten var `md5 (salt + pw)` og den nye hash er bcrypt, bør h9lpq0u først flytte til et skjema som `bcrypt (bcrypt_salt (log_rounds = 12), md5 (salt + pw))`. Ellers, hvis hasjene ble kompromittert i mellomtiden (før neste innlogging), si for en konto som ofte brukes, kan en angriper lett tvinge brukerens passord.
@dr j, Ah, vel da for det beste fra begge verdener, erstatt den gamle hashverdien med `NewHash (old_hash_value)`. Og når de logger inn for første gang, erstatter du det med bare `NewHash (passord + salt)`
Med hash-versjonsnummeret lekker du informasjon til angriperen om styrken og mulig type algoritme.Det er ikke mye info skjønt, men det ville fortsatt være bedre å bruke en slags tilfeldig id som HashingAlgorithmIdentifier i stedet for å versjonere den.
CodesInChaos
2012-08-27 19:09:48 UTC
view on stackexchange narkive permalink

Så lenge den gamle hasjen er anstendig (MD5 eller DES-Crypt er greit, ikke CRC32), er denne tilnærmingen sikker. Bruk av det samme saltet bør heller ikke føre til problemer, forutsatt at saltet er godt nok, dvs. (nesten) globalt unikt.

For den ytre hashfunksjonen anbefaler jeg å bruke en av scrypt, bcrypt eller PBKDF2.

tylerl
2012-08-28 08:13:45 UTC
view on stackexchange narkive permalink

Du finner dusinvis av open source-applikasjoner som har løst dette problemet. Wordpress kommer raskt i tankene, men det er andre også. Selv Microsoft Windows bruker samme teknikk. Den generelle løsningen er denne:

  • Utgangen for hver støttede hashfunksjon distribueres lett; enten ved å sjekke utgangsformatet eller lengden, eller (mer hensiktsmessig) ved å forhåndsstille en identifikatorstreng (f.eks. sha1: salt: _hash_output ____ ) eller ved å legge til et nytt felt i databasen for å identifisere hash-typen.
  • Du fortsetter å støtte autentisering via alle tidligere brukte hashfunksjoner, men alle nye hashes sender bare den foretrukne versjonen.
  • Eventuelt hvis en bruker er autentisert ved hjelp av en tidligere hash-versjon vil det autentiserte passordet bli hashatt på nytt ved hjelp av den foretrukne algoritmen, og den lagrede hash vil bli oppdatert.
Å holde svake hashes rundt til den aktuelle brukeren logger på er en dårlig ide IMO. Hvis dette er et vanlig nettsted, vil de fleste brukere ikke logge på lenge om noen gang.
@CodesInChaos Security er alltid en kompromiss. Du kan, hvis du velger, deaktivere kontoer med gamle hashes eller tilbakestille alt det gamle passordet eller hva du vil, egentlig. Men det du ikke kan gjøre er å oppdatere hasjen uten å ha passordet i ren tekst. Så uansett om du synes dette er en god idé eller ikke, det er det nesten alle gjør.
Du kan bruke teknikken med dobbel hash-oppdatering dette innlegget handler om. Muligens sammen med en opprydding ved neste pålogging.
@CodesInChaos Ja - det er en interessant løsning, noe som gjør det mer interessant at du ikke ser denne løsningen mer i bruk i den virkelige verden. Jeg lurer på hvorfor ikke.


Denne spørsmålet ble automatisk oversatt fra engelsk.Det opprinnelige innholdet er tilgjengelig på stackexchange, som vi takker for cc by-sa 3.0-lisensen den distribueres under.
Loading...