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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
# coding: utf8
# Copyright 2002, Hewlett-Packard
#
# A little program to hash a user password with a site-specific string
# The result is a random looking string that can be used as a password
# on that site. This tool lets you enter the same password string for
# all sites, but gives you a unique password to use for each site.
#
# 2002-02-07 - Initial VERSION 0.1
# 2002-02-07 - Changed result field so it can be cut and pasted, VERSION 0.2
# 2005-04-24 - Added alphanumeric option and clipboard handling, VERSION 0.3
# 2015-11-05 - Modify for Python 3 - Add encode('utf-8') and add import hashlib, VERSION 0.4
#
# To do:
# 1. Make a browser plugin that pops up when a password field appears
# 2. Port to Jornada
#
# Alan Karp, alan.karp@hp.com, 7 February 2002
# Ka-Ping Yee, zestyping@hp.com, 24 April 2005
# Ernaelsten Gérard info@formatux.be 04 November 2015
import base64
import hashlib
from tkinter import *
VERSION = '0.4'
LABEL_FONT = ('Helvetica', 9)
ENTRY_FONT = ('Courier', 10)
def show_help():
"""Display the help window."""
window = Toplevel()
Message(window, text="""
Site-Specific Password Generator
(Patent Pending, Hewlett-Packard)
This tool combines your password with a name for a website to produce a
password unique to the site. Using this tool, you only have to memorize
one password for all your Web logins, without worrying that anyone who
knows your password for one site will be able to use it on another one.
There are two input fields:
Your password
A string that you can remember. It should still be hard for others
to guess because this tool uses a well-known algorithm and you
use a well-known site name. Case sensitive.
Site name
Your name for the site. For example, Schwab or Amazon.
Case insensitive.
The site-specific password appears in the third field. It will be 12 ASCII
characters. Click "Copy to Clipboard" or just press the Enter key to put the
generated password on the clipboard so you can paste it into the password
field on the web site. If you are using a site that accepts only numbers and
letters in passwords, check "Letters and numbers only".
""", font=LABEL_FONT).pack()
Button(window, text='Close', font=LABEL_FONT, command=window.destroy).pack()
def generate_password(password, sitename, alphanumeric=0):
"""Compute a site-specific password."""
# Use the MD5 hash algorithm to combine the inputs.
sitename = sitename.encode('utf-8')
password = password.encode('utf-8')
digest = hashlib.md5(sitename.lower() + password).digest()
# Convert the hash to ASCII characters.
digest = base64.encodestring(digest)
intermediaire = digest.replace('+'.encode('utf-8'), 'A'.encode('utf-8'))
digest = intermediaire
intermediaire = digest.replace('/'.encode('utf-8'), 'B'.encode('utf-8'))
digest = intermediaire
if alphanumeric:
digest = '/'.encode('utf-8') + digest[1:]
return digest[:12]
class SitePasswordForm:
def __init__(self, parent):
self.parent = parent
# variables
self.password = StringVar(parent)
self.sitename = StringVar(parent)
self.result = StringVar(parent)
self.alpha = BooleanVar(parent)
self.password.trace('w', self.update_password)
self.sitename.trace('w', self.update_password)
self.alpha.trace('w', self.update_password)
# password entry field
self.password_label = Label(parent, text='Your password:', font=LABEL_FONT)
self.password_entry = Entry(parent, show='*', font=ENTRY_FONT,
textvar=self.password)
# site entry field
self.sitename_label = Label(parent, text='Site name:', font=LABEL_FONT)
self.sitename_entry = Entry(parent, font=ENTRY_FONT, textvar=self.sitename)
# output field
self.result_label = Label(parent, text='Site password:', font=LABEL_FONT)
self.result_entry = Entry(parent, state='readonly', relief=RIDGE,
font=ENTRY_FONT, textvar=self.result)
# check box
self.alpha_check = Checkbutton(parent, text='Include punctuation',
font=LABEL_FONT, variable=self.alpha)
# buttons
self.button_frame = Frame(parent)
self.copy_button = Button(self.button_frame, text='Copy to Clipboard (Enter)',
font=LABEL_FONT, command=self.copy_result, padx=10)
self.help_button = Button(self.button_frame, text='Help',
font=LABEL_FONT, command=show_help, padx=10)
# layout
self.password_label.grid(row=0, column=0, sticky=E)
self.password_entry.grid(row=0, column=1)
self.sitename_label.grid(row=1, column=0, sticky=E)
self.sitename_entry.grid(row=1, column=1)
self.result_label.grid(row=2, column=0, sticky=E)
self.result_entry.grid(row=2, column=1)
self.alpha_check.grid(row=3, column=1, sticky=W)
self.copy_button.pack(side=LEFT)
self.help_button.pack(side=LEFT)
self.button_frame.grid(row=4, column=0, columns=2)
# key bindings
self.password_entry.bind('<Return>', self.handle_return)
self.sitename_entry.bind('<Return>', self.handle_return)
# startup
self.update_password()
self.password_entry.focus()
def update_password(self, *args):
"""Update the site-specific password field."""
password = self.password.get()
password.strip()
sitename = self.sitename.get()
sitename.strip()
alpha = self.alpha.get()
if password and sitename:
self.result.set(generate_password(password, sitename, alpha))
self.copy_button['state'] = ACTIVE
else:
self.result.set('')
self.copy_button['state'] = DISABLED
def handle_return(self, *args):
"""When the user presses Enter, advance to the next obvious step."""
password = self.password.get()
sitename = self.sitename.get()
if not password.strip():
self.password_entry.focus()
elif not sitename.strip():
self.sitename_entry.focus()
else:
self.copy_result()
def copy_result(self, *args):
"""Place the site-specific password on the clipboard."""
if self.result.get():
self.result_entry.focus()
self.result_entry.selection_range(0, 'end')
self.parent.clipboard_clear()
self.parent.clipboard_append(self.result.get())
root = Tk()
root.title('Site-Specific Password ' + VERSION)
SitePasswordForm(root)
root.mainloop() |
Partager