Page 1 sur 1

Sécurité des mots de passe

Posté : 18 oct. 2006, 18:15
par momox
Bonsoir,
soucieux d'avoir un accès quelque peu sécurisé pour mes utilisateurs, j'aurais souhaité savoir comment faire pour tester la compléxité d'un mot de passe tel que gmail ou hotmail qui affichent une sorte de curseur indiquant la compléxité du mot de passe.
Enfin bon, bref, comment tester la compléxité de celui ci afin qu'un pirate qui use de la brute force n'ait pas trop de facilités a trouver le mot de passe.
Merci d'avance ;)
@+

Posté : 18 oct. 2006, 19:57
par starkeus
Essaie de voir cet addon sur un CMS appelé NK:
http://www.nuked-klan.org/index.php?fil ... &dl_id=304
Il y a surement de l'idée ;)

Posté : 18 oct. 2006, 20:13
par naholyr
Tu peux fonctionner par un système de score :
- mot présent dans le dictionnaire (fais une recherche automatisée sur le-dictionnaire.com par exemple, ou stocke la liste des mots du dico dans un fichier local, ou encore mieux fais une recherche automatisée sur google et vérifie que le nombre de résultat est inférieur à une valeur arbitraire donnée) = -5 points
- utilisation de minuscules = +1 point
- utilisation de majuscules = +1 point
- utilisation de chiffres = +1 point
- utilisation de caractères non alphanumériques = +2 points
- longueur > 6 caractères = +1 point par 6 caractères

Un mot de passe de 18 caractères bien mélangés de toutes sortes aura un score de 1+1+1+2+18/6 = 8. On peut considérer qu'à partir de 8 un mot de passe est très fort, et tu peux donner noter les mots de passe entre 0 et 8 (les scores négatifs sont ramenés à 0, les supérieurs à 8 sont ramenés à 8).

Posté : 18 oct. 2006, 20:49
par momox
Pas bête naho, j'avais pas pensé dans ce sens la.
Mais c'est une solution a explorer.
Maintenant, comment detecter les majuscules et les minuscules?
Je dois faire des chaines de majuscules et minuscules?
@+

Posté : 18 oct. 2006, 21:34
par Ouaibou
---

Posté : 18 oct. 2006, 22:36
par Ajoloca
Bonsoir,

Une façon relativement simple est de comparer en utilisant la fonction strtoupper()
if ($a == strtoupper($a)) // Majus
Elle n'est pas sure à 100% si on sort du jeux de caractères ASCII.

Posté : 19 oct. 2006, 00:03
par BeRoots
Le mieux je pense est de faire un regex par type de caractère (tres simple la regex

Les chiffre, les majuscules, les minuscule et enfin tout ce qui n'est pas l'un de ces trois caractère ;)

ensuite via un preg_match() le tour est jouer :)

Posté : 19 oct. 2006, 07:25
par momox
Bonsoir,

Une façon relativement simple est de comparer en utilisant la fonction strtoupper()
if ($a == strtoupper($a)) // Majus
Elle n'est pas sure à 100% si on sort du jeux de caractères ASCII.
Tu est sur que ca prend en compte la casse les conditions de ce type?
@+

Posté : 19 oct. 2006, 11:13
par Ouaibou
---

Posté : 19 oct. 2006, 17:38
par naholyr
Tiens il me semblait bien que j'avais déjà écrit quelque chose comme ça. Cela nécessite bien sûr une clé Google API que tu peux obtenir très simplement ici [ http://code.google.com/apis/ajaxsearch/signup.html ] en entrant http://localhost tout simplement)

Je te mets tout ça brut de béton c'est un peu commenté tu devrais t'en sortir si tu connais un peu JavaScript. Note que les codes commencent par "<?php" il faut bien sûr le virer ce n'est que pour la coloration syntaxique.

test-password.html (démo d'utilisation)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
        <title>My Google AJAX Search API Application</title>
        <link href="http://www.google.com/uds/css/gsearch.css" type="text/css" rel="stylesheet"/>
        <script src="http://www.google.com/uds/api?file=uds.js&v=1.0&key=MA-CLE-GOOGLE-API-ICI" type="text/javascript"></script>
        <script language="Javascript" type="text/javascript" src="passwordcheck.js"></script>
        <script type="text/javascript" type="text/javascript" src="test-password.js"></script>
    </head>
    <body>
        <input type="text" id="password" onchange="pc.evaluate(this.value)" />
        <div id="wait" style="display:none">Calcul...</div>
        <div id="affichage-score"></div>
        <div id="search"></div>
    </body>
</html>
passwordcheck.js (la librairie en elle-même)
// from prototype.js
if (!Object.extend) {
    Object.extend = function(o1, o2) {
        for (key in o2) {
            o1[key] = o2[key];
        }
        return o1;
    }
}

function PasswordChecker(options) {

    // public readonly : uniqid attributed for public access (needed for setTimeout calls)
    this.idprefix = '__pswd__chk__';
    this.uniqid = 0;
    
    // private : google API components (only if it exists)
    if (GSearchControl && GwebSearch) {
        this.sc = new GSearchControl();
        this.ws = new GwebSearch();
    }
    else {
        this.sc = false;
        this.ws = false;
    }

    // options
    this.options = Object.extend({
        'scoreWordExists' : -5, // score added when password found in google
        'scoreLowCase' :    +1, // score added when lower case characters [a-z] used
        'scoreUpCase' :     +1, // score added when upper case characters [A-Z] used
        'scoreDigit' :      +1, // score added when digits [0-9] used
        'scoreNonAlnum' :   +1, // score added when other charaters [^a-zA-Z0-9] used
        'scoreSlice' :      +1, // score added per each slice found
        'sliceSize' :       6, // size of each slice
        'scoreMin' :        0, // min score (lower scores are brought to this score)
        'scoreMax' :        8, // max score (bigger scores are brought to this score)
        'callback' :        function(score) { alert(score) }, // function called to display the score, you must defined this one
        'onStart' :         function() {}, // function called just before calculus
        'onEnd' :           function() {}, // function called after calculus, just before callback
        'googleSrcLayer' :  document.createElement('div') // layer where google search results are displayed (default = mute layer)
    }, options);

    // initialize object only when "evaluate is called"
    this.initialized = false;
    this.initialize = function() {
        if (this.sc) {
            // background google search control
            this.sc.setResultSetSize(GSearch.LARGE_RESULTSET);
            this.sc.addSearcher(this.ws);
            this.sc.draw(this.options.googleSrcLayer);
            this.sc.setTimeoutInterval(GSearchControl.TIMEOUT_MEDIUM); // medium : about 500ms
        }
        // unique id for globalization
        while (typeof window[this.idprefix+this.uniqid] != 'undefined') {
            this.uniqid++;
        }
        window[this.idprefix+this.uniqid] = this;
        this.initialized = true;
    }
    
    // private : used to follow the password in public calls (needed for setTimeout)
    this.checkedPassword = '';

    // public : evaluate score of parameter
    this.evaluate = function(password) {
        if (!this.initialized) {
            this.initialize();
        }
        this.options.onStart(); // 'onStart' is called here
        if (!this.options.scoreWordExists || !this.sc) {
            // direct evaluation, no need to search on google (or can't because API unavailable)
            this.score = this.directEvaluate(password);
            this.options.onEnd(); // 'onEnd' called before callback
            this.options.callback(Math.min(this.options.scoreMax,Math.max(this.options.scoreMin,score)));
        }
        else {
            // search on google, and then give result + basic evaluation
            this.ws.clearResults();
            this.sc.execute(password);
            this.checkedPassword = password;
            this.checkSearchState(0);
        }
    }

    // public but must not be called directly : called regularly to check state of the google search
    this.checkSearchState = function(elapsedTime) {
        if (elapsedTime > GSearchControl.TIMEOUT_MEDIUM || this.ws.results.length > 0) {
            var score = this.directEvaluate(this.checkedPassword);
            if (this.ws.results.length > 0) {
                score += this.options.scoreWordExists
            }
            this.options.onEnd(); // 'onEnd' called before callback
            this.options.callback(Math.min(this.options.scoreMax,Math.max(this.options.scoreMin,score)));
        }
        else {
            setTimeout('window.'+this.idprefix+this.uniqid+'.checkSearchState('+(elapsedTime+100)+')', 100);
        }
    }

    // public : returns score of the password without google search (only characters-analysis)
    this.directEvaluate = function(password) {
        var useUpCase = 0;
        var useLowCase = 0;
        var useNonAlnum = 0;
        var useDigit = 0;
        var slices = Math.floor(password.length/this.options.sliceSize);
        for (var i=0; i<password.length; i++) {
            var code = password.charCodeAt(i);
            if (97 <= code && code <= 122) {
                useLowCase = 1;
            }
            else if (65 <= code && code <= 90) {
                useUpCase = 1;
            }
            else if (48 <= code && code <= 57) {
                useDigit = 1;
            }
            else {
                useNonAlnum = 1;
            }
        }
        return useUpCase * this.options.scoreUpCase
            + useLowCase * this.options.scoreLowCase
            + useDigit * this.options.scoreDigit
            + useNonAlnum * this.options.scoreNonAlnum
            + slices * this.options.scoreSlice;
    }

}
test-password.js (le script de la page de démo, exemple d'initialisation de l'objet)
var pc = new PasswordChecker({
    'scoreMin' : 0,
    'scoreMax' : 6,
    'onStart'  : function() {
        document.getElementById('wait').style.display = 'block';
    },
    'onEnd'    : function() {
        document.getElementById('wait').style.display = 'none';
    },
    'callback' : function(score) {
        var layer = document.getElementById('affichage-score');
        layer.innerHTML = score+'/6';
    }
});

Posté : 19 oct. 2006, 18:08
par momox
Le seul truc qui est génant avec l'API google, c'est qu'il faut s'inscrire.
Enfin bon, je sais que ca permet de limiter les abus, mais ca fait forcer les webmasters a s'inscrire pour pouvoir utiliser le système.
@+

Posté : 19 oct. 2006, 18:40
par naholyr
En même temps tu as certainement un compte google parce que tu as du avoir un compte gmail du temps où c'était la grosse mode, et tu es donc déjà inscrit. De plus si tu suis le lien que je t'ai donné et que tu entres simplement l'adresse de ton site tu as ta clé dans la seconde.

Ceci étant dit, si tu regardes le code tu verras que j'ai bien fait les choses et l'API google est facultative : s'il ne trouve pas les classes définies par la librairie google, il ne va simplement pas faire de recherche. Il faut juste le prendre en compte parce que du coup seul le mot de passe vide vaut 0.