java - Perché char [] è preferito a String per le password?





security passwords (16)


  1. Le stringhe sono immutabili in Java se si memorizza la password come testo normale sarà disponibile in memoria fino a quando Garbage Collector non lo cancella e poiché le stringhe vengono utilizzate nel pool di stringhe per la riutilizzabilità ci sono possibilità piuttosto elevate che rimanga in memoria per un lungo durata, che rappresenta una minaccia per la sicurezza. Dal momento che chiunque abbia accesso al dump della memoria può trovare la password in chiaro
  2. Raccomandazione Java che utilizza il metodo getPassword() di JPasswordField che restituisce un metodo char [] e deprecato getText() che restituisce la password in chiaro, indicando il motivo di sicurezza.
  3. toString () c'è sempre il rischio di stampare testo normale in file di log o console, ma se si usa Array non si stamperà il contenuto dell'array, ma si stamperà la sua posizione di memoria.

    String strPwd = "passwd";
    char[] charPwd = new char[]{'p','a','s','s','w','d'};
    System.out.println("String password: " + strPwd );
    System.out.println("Character password: " + charPwd );
    

    Parola d'ordine stringa: passwd

    Password caratteri: [C @ 110b2345

Considerazioni finali: sebbene l'uso di char [] non sia sufficiente, è necessario cancellare il contenuto per renderlo più sicuro. Suggerisco anche di lavorare con hash o password cifrata invece di testo normale e di cancellarlo dalla memoria non appena l'autenticazione è completata.

In Swing, il campo password ha un getPassword() (restituisce char[] ) invece del solito getText() (restituisce String ). Allo stesso modo, ho trovato un suggerimento di non usare String per gestire le password.

Perché String pone una minaccia alla sicurezza quando si tratta di password? È scomodo usare char[] .




La risposta breve e diretta sarebbe perché char[]è mutabile mentre gli Stringoggetti non lo sono.

Stringsin Java sono oggetti immutabili. Questo è il motivo per cui non possono essere modificati una volta creati, e quindi l'unico modo per rimuovere i loro contenuti dalla memoria è quello di averli raccolti. Sarà solo allora quando la memoria liberata dall'oggetto può essere sovrascritta, e i dati saranno spariti.

Ora la garbage collection in Java non si verifica in nessun intervallo garantito. Il Stringpuò quindi persistere in memoria per un lungo periodo di tempo, e se un processo si blocca durante questo periodo, il contenuto della stringa potrebbe finire in un dump della memoria o in qualche registro.

Con un array di caratteri , puoi leggere la password, terminare di lavorare il prima possibile, e quindi modificare immediatamente il contenuto.




Mentre altri suggerimenti qui sembrano validi, c'è un altro buon motivo. Con la String semplice hai molte più possibilità di stampare accidentalmente la password su registri , monitor o qualche altro posto non sicuro. char[] è meno vulnerabile.

Considera questo:

public static void main(String[] args) {
    Object pw = "Password";
    System.out.println("String: " + pw);

    pw = "Password".toCharArray();
    System.out.println("Array: " + pw);
}

stampe:

String: Password
Array: [[email protected]



La stringa è immutabile e va al pool di stringhe. Una volta scritto, non può essere sovrascritto.

char[] è un array che dovresti sovrascrivere una volta che hai usato la password e questo è come dovrebbe essere fatto:

char[] passw = request.getPassword().toCharArray()
if (comparePasswords(dbPassword, passw) {
 allowUser = true;
 cleanPassword(passw);
 cleanPassword(dbPassword);
 passw=null;
}

private static void cleanPassword (char[] pass) {
 for (char ch: pass) {
  ch = null;
 }
}

Uno scenario in cui l'hacker potrebbe utilizzarlo è un crashdump: quando la JVM si arresta in modo anomalo e genera un dump della memoria, sarà possibile vedere la password.

Questo non è necessariamente un aggressore esterno malintenzionato. Questo potrebbe essere un utente di supporto che ha accesso al server per scopi di monitoraggio. Poteva sbirciare in un crashdump e trovare le password.




Come afferma Jon Skeet, non c'è modo se non usando la riflessione.

Tuttavia, se la riflessione è un'opzione per te, puoi farlo.

public static void main(String[] args) {
    System.out.println("please enter a password");
    // don't actually do this, this is an example only.
    Scanner in = new Scanner(System.in);
    String password = in.nextLine();
    usePassword(password);

    clearString(password);

    System.out.println("password: '" + password + "'");
}

private static void usePassword(String password) {

}

private static void clearString(String password) {
    try {
        Field value = String.class.getDeclaredField("value");
        value.setAccessible(true);
        char[] chars = (char[]) value.get(password);
        Arrays.fill(chars, '*');
    } catch (Exception e) {
        throw new AssertionError(e);
    }
}

quando corri

please enter a password
hello world
password: '***********'

Nota: se il carattere stringa [] è stato copiato come parte di un ciclo GC, è possibile che la copia precedente sia da qualche parte in memoria.

Questa vecchia copia non comparirebbe in un dump dell'heap, ma se si ha accesso diretto alla memoria grezza del processo si potrebbe vederlo. In generale si dovrebbe evitare a chiunque abbia tale accesso.




Non penso che questo sia un suggerimento valido, ma, posso almeno indovinare il motivo.

Penso che la motivazione sia quella di voler essere sicuro di poter cancellare tutte le tracce della password in memoria prontamente e con certezza dopo l'uso. Con un char[] potresti sovrascrivere ogni elemento dell'array con uno spazio vuoto o qualcosa di sicuro. Non è possibile modificare il valore interno di una String questo modo.

Ma quella sola non è una buona risposta; perché non assicurarti solo che un riferimento al char[] o String non sfugga? Quindi non c'è alcun problema di sicurezza. Ma il fatto è che gli oggetti String possono essere intern() ed in teoria e mantenuti in vita all'interno del pool costante. Suppongo che l'uso di char[] impedisca questa possibilità.




Questi sono tutti i motivi, si dovrebbe scegliere char [] array invece di String per password.

1. Poiché le stringhe sono immutabili in Java se si memorizza la password come testo normale, sarà disponibile in memoria fino a quando Garbage Collector non lo cancella e poiché String viene utilizzato nel pool di stringhe per riusabilità, è molto probabile che rimanga in memoria a lungo durata, che rappresentano una minaccia per la sicurezza. Dal momento che chiunque abbia accesso al dump della memoria può trovare la password in chiaro e questa è un'altra ragione per cui si dovrebbe sempre usare una password crittografata rispetto al testo normale. Poiché le stringhe non sono modificabili, non è possibile modificare il contenuto delle stringhe perché qualsiasi modifica produrrà una nuova stringa, mentre se si char [] è ancora possibile impostare tutti i suoi elementi come vuoti o nulli. Pertanto, la memorizzazione della password nell'array di caratteri attenua chiaramente il rischio di sicurezza di furto della password.

2. Java stesso consiglia di utilizzare il metodo getPassword () di JPasswordField che restituisce un metodo char [] e getText () che restituisce la password in chiaro, indicando il motivo di sicurezza. È buono seguire i consigli del team di Java e aderire allo standard piuttosto che andare contro di esso.

3. Con String c'è sempre il rischio di stampare testo normale in file di log o console, ma se si usa Array non si stamperà il contenuto dell'array, ma si stamperà la sua posizione di memoria. anche se non è una vera ragione, ma ha ancora senso.

    String strPassword="Unknown";
    char[] charPassword= new char[]{'U','n','k','w','o','n'};
    System.out.println("String password: " + strPassword);
    System.out.println("Character password: " + charPassword);

    String password: Unknown
    Character password: [[email protected]

Riferimento da: http://javarevisited.blogspot.com/2012/03/why-character-array-is-better-than.html Spero che questo aiuti.




Alcune persone credono che sia necessario sovrascrivere la memoria utilizzata per memorizzare la password quando non è più necessaria. Ciò riduce la finestra temporale in cui un utente malintenzionato deve leggere la password dal proprio sistema e ignora completamente il fatto che l'utente malintenzionato ha già bisogno di accesso sufficiente per dirottare la memoria JVM per farlo. Un aggressore con un tale accesso può catturare i tuoi eventi chiave rendendolo completamente inutile (AFAIK, quindi correggimi se sbaglio).

Aggiornare

Grazie ai commenti devo aggiornare la mia risposta. Apparentemente ci sono due casi in cui questo può aggiungere un (molto) minore miglioramento della sicurezza in quanto riduce il tempo che una password potrebbe atterrare sul disco rigido. Comunque penso che sia eccessivo per la maggior parte dei casi d'uso.

  • Il tuo sistema di destinazione potrebbe essere configurato male o devi supporre che sia e devi essere paranoico sui core dump (può essere valido se i sistemi non sono gestiti da un amministratore).
  • Il tuo software deve essere eccessivamente paranoico per prevenire perdite di dati con l'hacker che ha accesso all'hardware - usando cose come TrueCrypt (fuori produzione), VeraCrypt o CipherShed .

Se possibile, disabilitare i core dump e il file di swap si prenderà cura di entrambi i problemi. Tuttavia, richiederebbero i diritti di amministratore e potrebbero ridurre la funzionalità (meno memoria da utilizzare) e la rimozione della RAM da un sistema in esecuzione rappresenterebbe ancora un problema valido.




Le stringhe sono immutabili e non possono essere modificate una volta che sono state create. La creazione di una password come una stringa lascerà riferimenti vaghi alla password nell'heap o nel lotto di stringhe. Ora se qualcuno prende un dump dell'heap del processo Java e analizza attentamente potrebbe essere in grado di indovinare le password. Ovviamente queste stringhe non usate saranno raccolte da garbage ma dipende da quando il GC entra in gioco.

D'altra parte, char [] sono modificabili non appena l'autenticazione è terminata, è possibile sovrascriverli con qualsiasi carattere come tutte le M o le barre inverse. Ora anche se qualcuno prende una discarica dell'heap potrebbe non essere in grado di ottenere le password che non sono attualmente in uso. Questo ti dà un maggiore controllo nel senso, come liberare il contenuto dell'oggetto da te stesso in attesa che il GC lo faccia.




Le stringhe sono immutabili . Ciò significa che una volta creata la String , se un altro processo può eseguire il dump della memoria, non c'è modo (a parte la reflection ) di liberarsi dei dati prima che la raccolta dati venga presa a calci.

Con un array, puoi cancellare i dati in modo esplicito dopo aver finito. Puoi sovrascrivere l'array con qualsiasi cosa tu voglia e la password non sarà presente in nessun punto del sistema, anche prima della garbage collection.

Quindi sì, questo è un problema di sicurezza - ma anche l'uso di char[] riduce solo la finestra di opportunità per un utente malintenzionato, ed è solo per questo specifico tipo di attacco.

Come notato nei commenti, è possibile che gli array che vengono spostati dal garbage collector lascino in memoria le copie vaganti dei dati. Credo che questo sia specifico per l'implementazione: il garbage collector può cancellare tutta la memoria nel suo svolgimento, per evitare questo genere di cose. Anche se lo fa, c'è ancora il tempo durante il quale il char[] contiene i caratteri reali come una finestra di attacco.




Modifica: Tornando a questa risposta dopo un anno di ricerche sulla sicurezza, mi rendo conto che ciò comporta l'implicazione piuttosto sfortunata di poter effettivamente confrontare le password in chiaro. Per favore non farlo. Utilizzare un hash unidirezionale sicuro con un sale e un numero ragionevole di iterazioni . Prendi in considerazione l'utilizzo di una libreria: questa roba è difficile da ottenere!

Risposta originale: per quanto riguarda il fatto che String.equals () utilizza la valutazione di cortocircuito ed è quindi vulnerabile a un attacco di temporizzazione? Potrebbe essere improbabile, ma in teoria è possibile calcolare il confronto delle password per determinare la sequenza corretta dei caratteri.

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        // Quits here if Strings are different lengths.
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            // Quits here at first different character.
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

Altre risorse su attacchi di temporizzazione:




Per citare un documento ufficiale, la guida di Java Cryptography Architecture dice questo su char[] rispetto alle password di String (sulla crittografia basata su password, ma questo è più in generale sulle password, ovviamente):

Sembrerebbe logico raccogliere e memorizzare la password in un oggetto di tipo java.lang.String . Tuttavia, ecco l'avvertenza: Gli Object di tipo String sono immutabili, ovvero non ci sono metodi definiti che consentono di modificare (sovrascrivere) o azzerare il contenuto di una String dopo l'uso. Questa funzione rende gli oggetti String inadatti per la memorizzazione di informazioni sensibili alla sicurezza come le password utente. Dovresti sempre raccogliere e archiviare le informazioni sensibili per la sicurezza in un array di char .

Linee guida 2-2 delle Linee guida per la codifica sicura per Java Programming Language, la versione 4.0 dice anche qualcosa di simile (sebbene sia originariamente nel contesto della registrazione):

Linea guida 2-2: non registrare informazioni altamente sensibili

Alcune informazioni, come numeri di sicurezza sociale (SSN) e password, sono estremamente sensibili. Questa informazione non dovrebbe essere conservata più a lungo del necessario né dove possa essere vista, anche dagli amministratori. Ad esempio, non dovrebbe essere inviato ai file di registro e la sua presenza non dovrebbe essere rilevabile attraverso le ricerche. Alcuni dati transitori possono essere conservati in strutture di dati mutabili, ad esempio array di caratteri, e cancellati immediatamente dopo l'uso. La cancellazione delle strutture di dati ha ridotto l'efficacia sui tipici sistemi di runtime Java man mano che gli oggetti vengono trasferiti in memoria in modo trasparente al programmatore.

Questa linea guida ha anche implicazioni per l'implementazione e l'uso di librerie di livello inferiore che non hanno conoscenza semantica dei dati con cui hanno a che fare. Ad esempio, una libreria di analisi delle stringhe di basso livello può registrare il testo su cui lavora. Un'applicazione può analizzare un SSN con la libreria. Ciò crea una situazione in cui gli SSN sono disponibili per gli amministratori con accesso ai file di registro.




Non c'è nulla che l'array di char ti dia rispetto a String a meno che non lo pulisci manualmente dopo l'uso, e non ho visto nessuno farlo davvero. Quindi per me la preferenza di char [] vs String è un po 'esagerata.

Dai un'occhiata alla vasta libreria Spring Security here usata e chiediti: le password incompetenti o char [] di Spring Security non hanno molto senso. Quando un brutto hacker afferra i dump di memoria della tua RAM assicurati che otterrà tutte le password anche se usi metodi sofisticati per nasconderle.

Tuttavia, Java cambia continuamente e alcune funzionalità spaventose come la funzionalità di deduplicazione delle stringhe di Java 8 potrebbero internare gli oggetti String a tua insaputa. Ma questa è una conversazione diversa.




La stringa in java è immutabile. Quindi, ogni volta che viene creata una stringa, essa rimarrà nella memoria fino a quando non viene raccolta. Quindi chiunque abbia accesso alla memoria può leggere il valore della stringa.
Se il valore della stringa viene modificato, verrà creata una nuova stringa. Quindi sia il valore originale che il valore modificato rimangono nella memoria fino a quando non viene raccolto.

Con l'array di caratteri, il contenuto dell'array può essere modificato o cancellato una volta che lo scopo della password è servito. Il contenuto originale dell'array non verrà trovato in memoria dopo che è stato modificato e anche prima che la garbage collection abbia effetto.

A causa della sicurezza, è meglio memorizzare la password come array di caratteri.




1) Poiché le stringhe sono immutabili in Java se si memorizza la password come testo normale, sarà disponibile in memoria fino a quando Garbage Collector non lo cancella e poiché String viene utilizzato nel pool di stringhe per riusabilità, è molto probabile che rimanga in memoria per la lunga durata, che rappresenta una minaccia per la sicurezza. Dal momento che chiunque abbia accesso al dump della memoria può trovare la password in chiaro e questa è un'altra ragione per cui si dovrebbe sempre usare una password crittografata rispetto al testo normale. Poiché le stringhe sono immutabili, non è possibile modificare il contenuto delle stringhe perché qualsiasi modifica produrrà una nuova stringa, mentre se si char [] è ancora possibile impostare tutti i suoi elementi come vuoti o nulli. Pertanto, la memorizzazione della password nell'array di caratteri riduce il rischio di sicurezza di furto della password.

2) Java raccomanda di utilizzare il metodo getPassword () di JPasswordField che restituisce un metodo char [] e getText () che restituisce la password in chiaro, indicando il motivo di sicurezza. È bene seguire i consigli del team di Java e aderire allo standard piuttosto che andare contro di esso.




In base al commento che ho fatto sulla domanda:
Un punto importante è stato sorvolato da quasi tutti ... La mia reazione iniziale è stata molto simile a @ Michael Brooks, fino a quando ho capito, come @stefanw, che il problema qui è che i requisiti sono rotti, ma questi sono ciò che sono.
Ma poi, mi è venuto in mente che potrebbe non essere nemmeno il caso! Il punto mancante qui è il valore non scritto delle risorse dell'applicazione. In parole povere, per un sistema a basso valore, un meccanismo di autenticazione completamente sicuro, con tutto il processo coinvolto, sarebbe eccessivo e la scelta di sicurezza sbagliata .
Ovviamente, per una banca, le "migliori pratiche" sono un must e non c'è modo di violare eticamente CWE-257. Ma è facile pensare a sistemi a basso valore dove non ne vale la pena (ma una semplice password è ancora richiesta).

È importante ricordare che la vera competenza in materia di sicurezza consiste nel trovare i compromessi appropriati, NON nel formulare dogmaticamente le "Best Practices" che chiunque può leggere online.

Come tale, suggerisco un'altra soluzione:
A seconda del valore del sistema e SOLO SE il sistema ha un valore appropriato basso senza risorse "costose" (l'identità stessa inclusa), E ci sono requisiti aziendali validi che rendono impossibile il processo corretto (o sufficientemente difficile / costoso) , E il cliente è reso consapevole di tutti gli avvertimenti ...
Quindi potrebbe essere opportuno semplicemente consentire la crittografia reversibile, senza che cerchi speciali possano passare.
Sto semplicemente smettendo di dire di non preoccuparmi affatto della crittografia, perché è molto semplice / economico da implementare (anche considerando una gestione delle chiavi passibile), e fornisce una protezione SOME (più del costo di implementazione). Inoltre, vale la pena guardare come fornire all'utente la password originale, tramite e-mail, visualizzazione sullo schermo, ecc.
Poiché qui si assume che il valore della password rubata (anche in aggregato) è piuttosto basso, qualsiasi di queste soluzioni può essere valida.

Dal momento che c'è una vivace discussione in corso, in realtà SEVERAL discussioni vivaci, nei diversi post e discussioni separate, aggiungerò alcuni chiarimenti e risponderò ad alcuni dei punti molto positivi che sono stati sollevati altrove qui.

Per iniziare, penso che sia chiaro a tutti qui che è possibile recuperare la password originale dell'utente, è una cattiva pratica e generalmente non è una buona idea. Questo non è affatto in discussione ...
Inoltre, sottolineo che in molti, anzi MOST, situazioni - è davvero sbagliato, anche fallo, cattivo, E brutto .

Tuttavia, il punto cruciale della domanda è intorno al principio , c'è qualche situazione in cui potrebbe non essere necessario vietarlo, e in tal caso, come farlo nel modo più corretto appropriato alla situazione .

Ora, come @Thomas, @sfussenegger e pochi altri menzionati, l'unico modo corretto per rispondere a questa domanda è di fare un'analisi approfondita del rischio di qualsiasi situazione (o ipotetica) data, per capire cosa è in gioco, quanto vale proteggere e quali altre mitigazioni sono in gioco per permettersi quella protezione.
No, NON è una parola d'ordine, questo è uno degli strumenti di base e più importanti per un professionista della sicurezza in tempo reale. Le migliori pratiche sono valide fino ad un certo punto (di solito come linee guida per gli inesperti e gli hack), dopo di che prende il sopravvento l'analisi dei rischi.

Sai, è divertente - mi sono sempre considerato uno dei fanatici della sicurezza, e in qualche modo sono dalla parte opposta dei cosiddetti "esperti di sicurezza" ... Beh, la verità è - perché sono un fanatico, e un vero esperto di sicurezza nella vita reale - Non credo nel lanciare dogmi (o CWE) di "Best Practice" SENZA quell'importante analisi del rischio .
"Fai attenzione al fanatico della sicurezza che è veloce nell'applicare tutto nella cintura degli attrezzi senza sapere quale sia il vero problema con cui si stanno difendendo. Una maggiore sicurezza non equivale necessariamente a una buona sicurezza".
L'analisi del rischio e i veri fanatici della sicurezza farebbero riferimento a un compromesso più intelligente, basato su rischio / rischio, potenziale perdita, possibili minacce, mitigazioni complementari, ecc. Qualsiasi "esperto di sicurezza" che non può puntare a un'analisi del rischio solida come Basandosi sulle loro raccomandazioni, o supportando i compromessi logici, ma preferirebbero piuttosto sputare dogma e CWE senza nemmeno capire come eseguire un'analisi del rischio, non sono altro che Security Hacks, e la loro competenza non vale la carta igienica su cui l'hanno stampata.

In effetti, è così che otteniamo il ridicolo che è la sicurezza aeroportuale.

Ma prima di parlare dei compromessi appropriati da fare in QUESTA SITUAZIONE, diamo un'occhiata ai rischi apparenti (evidente, perché non abbiamo tutte le informazioni di base su questa situazione, stiamo tutti ipotizzando - poiché la domanda è quale ipotetica situazione potrebbe esserci ...)
Assumiamo un sistema LOW-VALUE, ma non così trival che è un accesso pubblico - il proprietario del sistema vuole evitare la rappresentazione casuale, tuttavia la sicurezza "alta" non è fondamentale quanto la facilità d'uso. (Sì, è un compromesso legittimo accettare il rischio che qualsiasi abile script-kiddie possa hackerare il sito ... Aspetta, non è APT in voga ora ...?)
Per esempio, diciamo che sto organizzando un sito semplice per una grande riunione di famiglia, consentendo a tutti di fare un brainstorming su dove vogliamo andare nel nostro campeggio quest'anno. Sono meno preoccupato per un hacker anonimo, o anche per il cugino Fred che mi spreme in ripetuti suggerimenti per tornare al lago Wantanamanabikiliki, dato che sono a conoscenza di zia Erma che non è in grado di accedere quando è necessario. Ora, la zia Erma, essendo un fisico nucleare, non è molto brava a ricordare le password o persino a usare il computer ... Quindi voglio rimuovere tutto l'attrito possibile per lei. Ancora una volta, NON sono preoccupato per gli hack, semplicemente non voglio errori stupidi di login errati - Voglio sapere chi sta arrivando e cosa vogliono.

Comunque.
Quindi quali sono i nostri principali rischi qui, se crittografiamo simmetricamente le password, invece di usare un hash unidirezionale?

  • Impersonare gli utenti? No, ho già accettato questo rischio, non interessante.
  • Amministratore malvagio? Beh, forse ... Ma ancora una volta, non mi interessa se qualcuno può impersonare un altro utente, INTERNO o no ... e comunque un amministratore malvagio otterrà la tua password non importa cosa - se il tuo amministratore è andato male, il suo gioco comunque.
  • Un altro problema che è stato sollevato è che l'identità è effettivamente condivisa tra diversi sistemi. Ah! Questo è un rischio molto interessante, che richiede uno sguardo più attento.
    Permettetemi di iniziare affermando che non è l' identità reale che è condivisa, piuttosto la prova o le credenziali di autenticazione. Ok, dal momento che una password condivisa mi consentirà effettivamente l'accesso a un altro sistema (ad esempio, il mio conto bancario o gmail), questa è effettivamente la stessa identità, quindi è solo semantica ... Tranne che non lo è . L'identità è gestita separatamente da ciascun sistema, in questo scenario (anche se potrebbero esserci sistemi di id di terze parti, come OAuth - ancora, è separato dall'identità in questo sistema - ne parleremo più avanti).
    Come tale, il punto di rischio principale qui è che l'utente inserirà volentieri la sua (stessa) password in diversi sistemi - e ora, io (l'amministratore) o qualsiasi altro hacker del mio sito avrò accesso alle password di zia Erma per il sito dei missili nucleari.

Hmmm.

Ti sembra qualcosa qui?

Dovrebbe.

Cominciamo dal fatto che proteggere il sistema di missili nucleari non è una mia responsabilità , sto solo costruendo un sito per la famiglia frakkin (per la mia famiglia). Quindi di chi è la responsabilità? Umm ... E il sistema di missili nucleari? Duh.
In secondo luogo, se volessi rubare la password di qualcuno (qualcuno che è noto per utilizzare ripetutamente la stessa password tra siti sicuri e non sicuri), perché dovrei preoccuparmi di hackerare il tuo sito? O alle prese con la tua crittografia simmetrica? Goshdarnitall, posso semplicemente creare il mio semplice sito web , far iscrivere gli utenti a ricevere NOTIZIE MOLTO IMPORTANTI su quello che vogliono ... Puffo Presto, ho "rubato" le loro password.

Sì, la formazione degli utenti torna sempre a morderci nel ciao, vero?
E non c'è nulla che tu possa fare a riguardo ... Anche se TU STAVI l'hash delle loro password sul tuo sito, e fai tutto il resto a cui la TSA può pensare, hai aggiunto la protezione alla loro password NON UNO WHIT , se hanno intenzione di mantenere attaccare promiscuamente le loro password in ogni sito in cui si imbattono. Non preoccuparti di provare.

In altre parole , non possiedi le loro password , quindi smetti di provare a comportarti come fai tu.

Quindi, miei cari esperti di sicurezza, come una vecchia signora chiedeva per Wendy, "DOVE è il rischio?"

Altri punti, in risposta ad alcune questioni sollevate sopra:

  • CWE non è una legge, o regolamento, o addirittura uno standard. È una raccolta di punti deboli comuni , ovvero l'inverso delle "Best Practices".
  • Il problema dell'identità condivisa è un problema reale, ma frainteso (o travisato) dagli oppositori qui. È un problema di condivisione dell'identità in sé e per sé (!), NON di cracking delle password su sistemi di basso valore. Se stai condividendo una password tra un sistema a basso valore e un valore elevato, il problema è già lì!
  • In base al punto, il punto precedente potrebbe effettivamente puntare contro l'uso di OAuth e simili per entrambi questi sistemi a basso valore e per i sistemi bancari ad alto valore.
  • So che è stato solo un esempio, ma (purtroppo) i sistemi dell'FBI non sono davvero i più sicuri in circolazione. Non proprio come i server del blog del tuo gatto, ma nemmeno superano alcune delle banche più sicure.
  • Dividere le conoscenze, o il doppio controllo, delle chiavi di crittografia NON si verifica solo nelle forze armate, infatti PCI-DSS ora richiede questo praticamente da tutti i commercianti, quindi non è così tanto lontano là fuori (SE il valore lo giustifica).
  • A tutti coloro che si lamentano del fatto che domande come queste siano ciò che rende la professione degli sviluppatori un aspetto così negativo: sono risposte come quelle che rendono la professione della sicurezza ancora peggiore. Ancora una volta, l'analisi del rischio focalizzata sul business è ciò che è richiesto, altrimenti ti rendi inutile. Oltre ad essere sbagliato.
  • Immagino che questo sia il motivo per cui non è una buona idea assumere solo uno sviluppatore abituale e far cadere più responsabilità di sicurezza su di lui, senza allenarsi a pensare in modo diverso, e cercare i compromessi giusti. Senza offesa, per quelli di voi qui, sono tutto per questo - ma più allenamento è in ordine.

Accidenti. Che post lungo ...
Ma per rispondere alla tua domanda iniziale, @Shane:

  • Spiega al cliente il modo corretto di fare le cose.
  • Se insiste ancora, spiegane qualcos'altro, insisti, discuti. Fai un capriccio, se necessario.
  • Spiega a lui il RISCHIO AZIENDALE. I dettagli sono buoni, le cifre sono migliori, una demo dal vivo è solitamente la migliore.
  • SE ANCORA insiste, E presenta validi motivi di lavoro - è tempo che tu faccia una chiamata di giudizio:
    Questo sito è di basso valore? È davvero un caso aziendale valido? È abbastanza buono per te? Non ci sono altri rischi che puoi prendere in considerazione, che superano i validi motivi commerciali? (E ovviamente, il client NON è un sito malevolo, ma è così).
    Se è così, vai avanti. Non vale la pena, l'attrito e l'uso perso (in questa situazione ipotetica) per mettere in atto il processo necessario. Qualsiasi altra decisione (di nuovo, in questa situazione) è un compromesso negativo.

Quindi, bottom line e una risposta reale: crittografalo con un semplice algoritmo simmetrico, proteggi la chiave di crittografia con ACL forti e preferibilmente DPAPI o simili, documentalo e chiedi al client (qualcuno abbastanza anziano per prendere quella decisione) di firmare esso.





java string security passwords char