Bonjour

De plus en plus de site réclament des mots de passes complexes. à cela s'ajoute le fait que nous utilisons de plus en plus de sites.
garder en local les mots de passes est toujours un problème.
j'ai donc imaginé un petit plugin qui génère un mot de passe complexe pour chaque site qui n'est pas stocké.

Je ne conseille pas d'utiliser la chose en l'état ce n'était qu'un démonstrateur.

créer un dossier PassGenerator.
tous ce fait dans ce dossier
créer un fichier manifest.json. Attention ce nom est obligatoire
nous y définissons le nom de l'extension ainsi que ses capacités.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
  "name": "Pass generator",
  "description": "create robut password",
  "version": "0.7",
  "permissions": ["contextMenus","activeTab","storage"],
  "background": {
    "persistent": false,
    "scripts": ["sample.js"]
  },
  "content_scripts": [{
    "all_frames": false,
    "matches": [ "http://*/*", "https://*/*" ],
    "js":      ["sha.js", "content.js"]
  }],
  "options_ui": {
    // Required.
    "page": "options.html",
    // Recommended.
    "chrome_style": true
  },
  "icons": {
    "16": "key16.png"
  },
  "manifest_version": 2
}
Quelques éléments intéressants les permissions ou l'on voit contextMenu.
content_scripts qui défini la liste des script qui seront exécuté dans le cadre de la page.
et background qui est le coeur de l'extension.

créer un fichier sample.js. référencé dans background dans le manifeste.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//on défini une fonction handler qui gère le click sur un élément du menu
//vu qu'on a qu'un menu on ne vérifie rien 
function onClickHandler(info, tab) {
  //on lit l'option crypt dans la liste des options de l'extension
  chrome.storage.sync.get({
    crypt: 'bc0377cd1fa1ee55a0fb053a85dbee40c06dd56f', //valeur par défaut mettre ce qu'on veut
    text: "getPassword"
  }, function (result) {
     //on demande à la page qui à été cliqué de répondre au message getPassword
     chrome.tabs.sendMessage(tab.id, result);
  });
};
 
//installation du handler
chrome.contextMenus.onClicked.addListener(onClickHandler);
 
//création du menu
chrome.runtime.onInstalled.addListener(function() {
  var id = chrome.contextMenus.create({"title": "setPassWord", "contexts":["editable"], "id": "page"});
});
Le point important est que c'est bien l'extension qui capte le click mais ce sera un script exécuté dans le contexte de la page qui fera le boulot.
hors mis le fait que nous lisons une option le click ne fait qu'envoyer un message à la page. il lui faut donc du code pour le recevoir.

créer le fichier content.js. lui est référencé dans content_scripts dans le manifeste.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
(function () {
  //garde le dernier élément sur lequel à eu lieu le mousedown
  var dwnElement = null;
  document.addEventListener("mousedown", function(event) {
     dwnElement = event.target;
  });
 
  //Ici on répond au messages
  //on va créer un dialoge HTML5 pour saisir une clef que seul l'utilisateur connais.
  //lorsque la clef sera saisie la fonction keypress  sera activée.
  chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
      if (msg.text && (msg.text == "getPassword")) {
 
        var dialog = document.createElement('DIALOG');
        dialog.innerHTML='Enter you key : ';
        pass = document.createElement('INPUT')
        pass.setAttribute('type', 'password');
        pass.onkeypress=keypress;
        pass["data-dialog"]=dialog;
        pass["data-crypt"]=msg.crypt;
        dialog.appendChild(pass);
        document.body.appendChild(dialog);
        rs = dialog.showModal();
      }
  });
 
  // l'utilisateur entre sa clef s'il appuis sur enter on appelle setPassword
  function keypress (event) {
     if (event.keyCode==13){
      setPassword(this.value, this.baseURI, this["data-crypt"]);
      this["data-dialog"].close(this.value);
     }
  };
 
  //On crée un password robuste en fonction de l'url, de la clef saisie et de la clef de cryptage
  //pour sela on utilise jsSHA (http://caligatio.github.io/jsSHA/)
  function setPassword(password, uri, crypt) {
    var hashInputType = 'TEXT';
    var hashVariant = 'SHA-1';
    var hashRounds = 35;
    var hashOutputType = 'B64';
    var hashObj = new jsSHA(getHost(uri)+ password + crypt, hashInputType);
    var hashOutput  = hashObj.getHash(
      hashVariant,
      hashOutputType,
      hashRounds
    );
    element = dwnElement;
    if (('password' == element.type)||(confirm('the input is not a password ! continue ?'))) {
      element.value = hashOutput;
    }
  };
 
  function getHost(uri) {
     var a = document.createElement('a');
     a.href = uri;
     return a.hostname;
  }
})()
Ici rien de très complexe il s'agit de la gestion d'une boite de dialogue.
le point spécifique à une extension chrome est la réponse à un message. (onMessage)

déjà l'extension fonctionne au détails de la gestion des options et des icônes.

pour gérer les options on ajoute les fichiers options.js et options.html.
il s'agit d'un simple formulaire
Code html : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html>
   <head>
      <title>Pass generator Options
      </title>
      <style>
         body: { padding: 10px; }
      </style>
   </head>
   <body>
      <label>
         <label for="crypt">Crypt key.
         </label>
         <input type="text" id="crypt">
      </label>
      <div id="status">
      </div>
      <button id="save">Save
      </button>
<script src="options.js"></script>
   </body>
</html>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
(function () {
  // Saves options to chrome.storage.sync.
  function save_options(event) {
    var crypt = document.getElementById('crypt').value;
    chrome.storage.sync.set({
      crypt: crypt
    }, function() {
      // Update status to let user know options were saved.
      var status = document.getElementById('status');
      status.textContent = 'Options saved.';
      setTimeout(function() {
        status.textContent = '';
      }, 750);
    });
    event.view.close();
  }
 
  // Restores select box and checkbox state using the preferences
  // stored in chrome.storage.
  function restore_options() {
    // Use default value color = 'red' and likesColor = true.
    chrome.storage.sync.get({
      crypt: 'bc0377cd1fa1ee55a0fb053a85dbee40c06dd56f' //valeur par défaut
    }, function(items) {
      document.getElementById('crypt').value = items.crypt;
    });
  }
  document.addEventListener('DOMContentLoaded', restore_options);
  document.getElementById('save').addEventListener('click',save_options);
})()
les chose sont relativement simple au chargement on lit le datastore et sur appuit de "save" on écrit dans le datastore.

Attention à la valeur par défaut qui est aussi présente dans le fichier sample.js.
Ajouter au dossier le fichier key16.png et sha.js. jsSHA

ouvrir l'onglet extensions de chrome activer les options développeur si besoin
cliquez sur "charger l'extension non empaqueté"
choisir le dossier PassGenerator.
finaliser l'installation.
cliquer sur options
un dialogue s'ouvre pour choisir une autre clef de cryptage n'importe quelle chaîne fait l'affaire.

ouvrez un site avec un formulaire.
sur l'un des inputs faire un click droit et choisir setPassword
Un dialogue demande d'entrer votre clef
une fois la touche "enter" enfoncée si l'input est de type password le mot de passe est rempli
s'il s'agit d'un champ texte une confirmation est demandé

on obtient un mot de passe du type
xY2/WB9GCk5gDNIYVtaxDYZqdkc=

il suffit donc de retenir une clef simple pour obtenir un mot de passe robuste par site.
testé sur http://www.passwordmeter.com/ en entrant la clef titi le score est :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Score:      100% 
Complexity: Very Strong
 
 
Number of Characters  Flat           +(n*4)       28 + 112
Uppercase Letters  Cond/Incr         +((len-n)*2) 8  + 40
Lowercase Letters  Cond/Incr         +((len-n)*2) 12 + 32
Numbers  Cond                        +(n*4)       6  + 24
Symbols  Flat                        +(n*6)       2  + 12
Middle Numbers or Symbols  Flat      +(n*2)       7  + 14
Requirements  Flat                   +(n*2)       5  + 10
Deductions
Letters Only  Flat                   -n           0    0
Numbers Only  Flat                   -n           0    0
Repeat Characters (Case Insensitive) Comp  -      8  - 1
Consecutive Uppercase Letters  Flat  -(n*2)       2  - 4
Consecutive Lowercase Letters  Flat  -(n*2)       5  - 10
Consecutive Numbers  Flat            -(n*2)       2  - 4
Sequential Letters (3+)  Flat        -(n*3)       0    0
Sequential Numbers (3+)  Flat        -(n*3)       0    0
Sequential Symbols (3+)  Flat        -(n*3)       0    0
A+JYT