diff --git a/cranspasswords.py b/cranspasswords.py
index bcd239099f9c046253a8777315806dae5dfeeb5f..f3ff69643ead2ee894e0d2e36fcea01278da53ef 100755
--- a/cranspasswords.py
+++ b/cranspasswords.py
@@ -70,9 +70,9 @@ def gpg(command, args = None):
     if args:
         full_command.extend(args)
     if VERB:
-        stderr=sys.stderr
+        stderr = sys.stderr
     else:
-        stderr=subprocess.PIPE
+        stderr = subprocess.PIPE
         full_command.extend(['--debug-level=1'])
     #print full_command
     proc = subprocess.Popen(full_command,
@@ -163,7 +163,7 @@ def gen_password():
     random.seed(datetime.datetime.now().microsecond)
     chars = string.letters + string.digits + '/=+*'
     length = 15
-    return ''.join([random.choice(chars) for _ in xrange(length)])
+    return u''.join([random.choice(chars) for _ in xrange(length)])
 
 ######
 ## Local commands
@@ -174,36 +174,35 @@ def update_keys():
     keys = all_keys()
     
     _, stdout = gpg("receive-keys", [key for _, key in keys.values() if key])
-    return stdout.read()
+    return stdout.read().decode("utf-8")
 
 def check_keys():
     """Vérifie les clés existantes"""
-    print "Who cares ?"
-#    keys = all_keys()
-#    gpg = gnupg.GPG(gnupghome='~/.gnupg')
-#    localkeys = gpg.list_keys()
-#    failed = False
-#    for (mail, fpr) in keys.values():
-#        if fpr:
-#            if VERB:   print "Checking %s" % (mail)
-#            corresponds = [key for key in localkeys if key["fingerprint"] == fpr]
-#            # On vérifie qu'on possède la clé…
-#            if len(corresponds) == 1:
-#                correspond = corresponds[0]
-#                # …qu'elle correspond au mail…
-#                if mail.lower() in sum([re.findall("<(.*)>", uid.lower()) for uid in correspond["uids"]], []):
-#                    meaning, trustvalue = GPG_TRUSTLEVELS[correspond["trust"]]
-#                    # … et qu'on lui fait confiance
-#                    if not trustvalue:
-#                        print (u"--> Fail on %s:%s\nLa confiance en la clé est : %s" % (meaning,)).encode("utf-8")
-#                        failed = True
-#                else:
-#                    print (u"--> Fail on %s:%s\n!! Le fingerprint et le mail ne correspondent pas !" % (fpr, mail)).encode("utf-8")
-#                    failed = True
-#            else:
-#                print (u"--> Fail on %s:%s\nPas (ou trop) de clé avec ce fingerprint." % (fpr, mail)).encode("utf-8")
-#                failed = True
-#    return not failed
+    keys = all_keys()
+    gpg = gnupg.GPG(gnupghome='~/.gnupg')
+    localkeys = gpg.list_keys()
+    failed = False
+    for (mail, fpr) in keys.values():
+        if fpr:
+            if VERB:   print (u"Checking %s" % (mail)).encode("utf-8")
+            corresponds = [key for key in localkeys if key["fingerprint"] == fpr]
+            # On vérifie qu'on possède la clé…
+            if len(corresponds) == 1:
+                correspond = corresponds[0]
+                # …qu'elle correspond au mail…
+                if mail.lower() in sum([re.findall("<(.*)>", uid.lower()) for uid in correspond["uids"]], []):
+                    meaning, trustvalue = GPG_TRUSTLEVELS[correspond["trust"]]
+                    # … et qu'on lui fait confiance
+                    if not trustvalue:
+                        print (u"--> Fail on %s:%s\nLa confiance en la clé est : %s" % (meaning,)).encode("utf-8")
+                        failed = True
+                else:
+                    print (u"--> Fail on %s:%s\n!! Le fingerprint et le mail ne correspondent pas !" % (fpr, mail)).encode("utf-8")
+                    failed = True
+            else:
+                print (u"--> Fail on %s:%s\nPas (ou trop) de clé avec ce fingerprint." % (fpr, mail)).encode("utf-8")
+                failed = True
+    return not failed
 
 def get_recipients_of_roles(roles):
     """Renvoie les destinataires d'un rôle"""
@@ -212,13 +211,12 @@ def get_recipients_of_roles(roles):
     for role in roles:
         for recipient in allroles[role]:
             recipients.add(recipient)
-    
     return recipients
 
 def get_dest_of_roles(roles):
     """Renvoie la liste des "username : mail (fingerprint)" """
     allkeys = all_keys()
-    return ["%s : %s (%s)" % (rec, allkeys[rec][0], allkeys[rec][1])
+    return [u"%s : %s (%s)" % (rec, allkeys[rec][0], allkeys[rec][1])
                for rec in get_recipients_of_roles(roles) if allkeys[rec][1]]
 
 def encrypt(roles, contents):
@@ -235,11 +233,11 @@ def encrypt(roles, contents):
             fpr_recipients.append(fpr)
     
     stdin, stdout = gpg("encrypt", fpr_recipients)
-    stdin.write(contents)
+    stdin.write(contents.encode("utf-8"))
     stdin.close()
-    out = stdout.read()
+    out = stdout.read().decode("utf-8")
     if out == '':
-        if VERB: print "Échec de chiffrement"
+        if VERB: print u"Échec de chiffrement".encode("utf-8")
         return None
     else:
         return out
@@ -247,9 +245,9 @@ def encrypt(roles, contents):
 def decrypt(contents):
     """Déchiffre le contenu"""
     stdin, stdout = gpg("decrypt")
-    stdin.write(contents)
+    stdin.write(contents.encode("utf-8"))
     stdin.close()
-    return stdout.read()
+    return stdout.read().decode("utf-8")
 
 def put_password(name, roles, contents):
     """Dépose le mot de passe après l'avoir chiffré pour les
@@ -258,7 +256,7 @@ def put_password(name, roles, contents):
     if NROLES != None:
         roles = NROLES
         if VERB:
-            print "Pas de nouveaux rôles"
+            print u"Pas de nouveaux rôles".encode("utf-8")
     if enc_pwd <> None:
         return put_file(name, roles, enc_pwd)
     else:
@@ -272,7 +270,7 @@ def get_password(name):
 ######
 ## Interface
 
-def editor(texte, annotations=""):
+def editor(texte, annotations=u""):
     """ Lance $EDITOR sur texte.
     Renvoie le nouveau texte si des modifications ont été apportées, ou None
     """
@@ -281,23 +279,23 @@ def editor(texte, annotations=""):
     # for annotations ...
     f = tempfile.NamedTemporaryFile(suffix='.txt')
     atexit.register(f.close)
-    f.write(texte)
-    for l in annotations.split('\n'):
-        f.write("# %s\n" % l.encode('utf-8'))
+    if annotations:
+        annotations = "# " + annotations.replace("\n", "\n# ")
+    f.write((texte + "\n" + annotations).encode("utf-8"))
     f.flush()
     proc = subprocess.Popen([os.getenv('EDITOR', '/usr/bin/editor'), f.name])
     os.waitpid(proc.pid, 0)
     f.seek(0)
-    ntexte = f.read()
+    ntexte = f.read().decode("utf-8")
     f.close()
-    ntexte = '\n'.join(filter(lambda l: not l.startswith('#'), ntexte.split('\n')))
+    ntexte = u'\n'.join(filter(lambda l: not l.startswith('#'), ntexte.split('\n')))
     if texte != ntexte:
         return ntexte
     return None
 
 def show_files():
     """Affiche la liste des fichiers disponibles sur le serveur distant"""
-    print """Liste des fichiers disponibles :"""
+    print u"Liste des fichiers disponibles :".encode("utf-8")
     my_roles = get_my_roles()
     files = all_files()
     keys = files.keys()
@@ -310,16 +308,16 @@ def show_files():
     
 def show_roles():
     """Affiche la liste des roles existants"""
-    print """Liste des roles disponibles :"""
+    print u"Liste des roles disponibles".encode("utf-8")
     for role in all_roles().keys():
         if not role.endswith('-w'):
-            print " * " + role 
+            print (u" * " + role ).encode("utf-8")
 
 def show_servers():
     """Affiche la liste des serveurs disponibles"""
-    print """Liste des serveurs disponibles :"""
+    print u"Liste des serveurs disponibles".encode("utf-8")
     for server in config.servers.keys():
-        print " * " + server
+        print (u" * " + server).encode("utf-8")
 
 old_clipboard = None
 def saveclipboard(restore=False):
@@ -333,7 +331,7 @@ def saveclipboard(restore=False):
     if not restore:
         old_clipboard = proc.stdout.read()
     else:
-        raw_input("Appuyez sur Entrée pour récupérer le contenu précédent du presse papier.")
+        raw_input(u"Appuyez sur Entrée pour récupérer le contenu précédent du presse papier.".encode("utf-8"))
         proc.stdin.write(old_clipboard)
     proc.stdin.close()
     proc.stdout.close()
@@ -343,37 +341,35 @@ def clipboard(texte):
     saveclipboard()
     proc =subprocess.Popen(['xclip', '-selection', 'clipboard'],\
         stdin=subprocess.PIPE, stdout=sys.stdout, stderr=sys.stderr)
-    proc.stdin.write(texte)
+    proc.stdin.write(texte.encode("utf-8"))
     proc.stdin.close()
-    return "[Le mot de passe a été mis dans le presse papier]"
+    return u"[Le mot de passe a été mis dans le presse papier]"
 
 
 def show_file(fname):
     """Affiche le contenu d'un fichier"""
     value = get_file(fname)
     if value == False:
-        print "Fichier introuvable"
+        print u"Fichier introuvable".encode("utf-8")
         return
     (sin, sout) = gpg('decrypt')
-    sin.write(value['contents'])
+    sin.write(value['contents'].encode("utf-8"))
     sin.close()
-    texte = sout.read()
-    ntexte = ""
+    texte = sout.read().decode("utf-8")
+    ntexte = u""
     hidden = False  # Est-ce que le mot de passe a été caché ?
     lines = texte.split('\n')
     for line in lines:
         catchPass = PASS.match(line)
         if catchPass != None and CLIPBOARD:
-            hidden=True
+            hidden = True
             line = clipboard(catchPass.group(1))
         ntexte += line + '\n'
     showbin = "cat" if hidden else "less"
     proc = subprocess.Popen(showbin, stdin=subprocess.PIPE, shell=True)
     out = proc.stdin
-    out.write("Fichier %s:\n\n" % (fname,))
-    out.write(ntexte)
-    out.write("-----\n")
-    out.write("Visible par: %s\n" % ','.join(value['roles']))
+    raw = u"Fichier %s:\n\n%s-----\nVisible par: %s\n" % (fname, ntexte, ','.join(value['roles']))
+    out.write(raw.encode("utf-8"))
     out.close()
     os.waitpid(proc.pid, 0)
 
@@ -385,26 +381,26 @@ def edit_file(fname):
     annotations = u""
     if value == False:
         nfile = True
-        print "Fichier introuvable"
+        print u"Fichier introuvable".encode("utf-8")
         if not confirm("Créer fichier ?"):
             return
         annotations += u"""Ceci est un fichier initial contenant un mot de passe
 aléatoire, pensez à rajouter une ligne "login: ${login}"
 Enregistrez le fichier vide pour annuler.\n"""
-        texte = "pass: %s\n" % gen_password()
+        texte = u"pass: %s\n" % gen_password()
         roles = get_my_roles()
         # Par défaut les roles d'un fichier sont ceux en écriture de son
         # créateur
         roles = [ r[:-2] for r in roles if r.endswith('-w') ]
         if roles == []:
-            print "Vous ne possédez aucun rôle en écriture ! Abandon."
+            print u"Vous ne possédez aucun rôle en écriture ! Abandon.".encode("utf-8")
             return
         value = {'roles' : roles}
     else:
         (sin, sout) = gpg('decrypt')
-        sin.write(value['contents'])
+        sin.write(value['contents'].encode("utf-8"))
         sin.close()
-        texte = sout.read()
+        texte = sout.read().decode("utf-8")
     value['roles'] = NROLES or value['roles']
 
     annotations += u"""Ce fichier sera chiffré pour les rôles suivants :\n%s\n
@@ -416,19 +412,19 @@ C'est-à-dire pour les utilisateurs suivants :\n%s""" % (
     ntexte = editor(texte, annotations)
 
     if ntexte == None and not nfile and NROLES == None:
-        print "Pas de modifications effectuées"
+        print u"Pas de modifications effectuées".encode("utf-8")
     else:
         ntexte = texte if ntexte == None else ntexte
         if put_password(fname, value['roles'], ntexte):
-            print "Modifications enregistrées"
+            print u"Modifications enregistrées".encode("utf-8")
         else:
-            print "Erreur lors de l'enregistrement (avez-vous les droits suffisants ?)"
+            print u"Erreur lors de l'enregistrement (avez-vous les droits suffisants ?)".encode("utf-8")
 
 def confirm(text):
     """Demande confirmation, sauf si on est mode ``FORCED``"""
     if FORCED: return True
     while True:
-        out = raw_input(text + ' (O/N)').lower()
+        out = raw_input((text + ' (O/N)').encode("utf-8")).lower()
         if out == 'o':
             return True
         elif out == 'n':
@@ -436,12 +432,12 @@ def confirm(text):
 
 def remove_file(fname):
     """Supprime un fichier"""
-    if not confirm('Êtes-vous sûr de vouloir supprimer %s ?' % fname):
+    if not confirm((u'Êtes-vous sûr de vouloir supprimer %s ?' % fname).encode("utf-8")):
         return
     if rm_file(fname):
-        print "Suppression effectuée"
+        print u"Suppression effectuée".encode("utf-8")
     else:
-        print "Erreur de suppression (avez-vous les droits ?)"
+        print u"Erreur de suppression (avez-vous les droits ?)".encode("utf-8")
 
 
 def my_check_keys():
@@ -450,7 +446,7 @@ def my_check_keys():
 
 def my_update_keys():
     """Met à jour les clés existantes et affiche le résultat"""
-    print update_keys()
+    print update_keys().encode("utf-8")
 
 def update_role():
     """Rechiffre les fichiers"""
@@ -465,7 +461,7 @@ def update_role():
     for (fname, froles) in all_files().iteritems():
         if set(roles).intersection(froles) == set([]):
             continue
-        print "Rechiffrement de %s" % fname
+        print (u"Rechiffrement de %s" % fname).encode("utf-8")
         put_password(fname, froles, get_password(fname))
 
 def parse_roles(strroles):
@@ -478,17 +474,17 @@ def parse_roles(strroles):
     writable = False
     for role in strroles.split(','):
         if role not in roles.keys():
-            print("Le rôle %s n'existe pas !" % role)
+            print (u"Le rôle %s n'existe pas !" % role).encode("utf-8")
             return False
         if role.endswith('-w'):
-            print("Le rôle %s ne devrait pas être utilisé ! (utilisez %s)"
-                % (role,role[:-2]))
+            print (u"Le rôle %s ne devrait pas être utilisé ! (utilisez %s)"
+                   % (role,role[:-2])).encode("utf-8")
             return False
         writable = writable or role in my_roles_w
         ret.add(role)
     
     if not FORCED and not writable:
-        if not confirm("""Vous vous apprêtez à perdre vos droits d'écritures\
+        if not confirm(u"""Vous vous apprêtez à perdre vos droits d'écritures\
 (role ne contient pas %s) sur ce fichier, continuer ?""" %
             ", ".join(my_roles_w)):
             return False
@@ -555,7 +551,7 @@ if __name__ == "__main__":
         if parsed.action.func_code.co_argcount == 0:
             parsed.action()
         elif parsed.fname == None:
-            print("Vous devez fournir un nom de fichier avec cette commande")
+            print u"Vous devez fournir un nom de fichier avec cette commande".encode("utf-8")
             parser.print_help()
         else:
             parsed.action(parsed.fname)
diff --git a/server.py b/server.py
index 60358db534befeec61cc8c9af4103936bf3c83d6..5316d1c559a8a3b8839e8fe5b0b916cbe2fc82b2 100755
--- a/server.py
+++ b/server.py
@@ -92,11 +92,10 @@ def putfile(filename):
     else:
         if not validate(oldroles,'w'):
             return False
-    
-        backup(filename, old)
-        notification(u"Modification de %s" % filename,
-            u"Le fichier %s a été modifié par %s." % (filename, MYUID),
-            filename, old)
+        
+        corps = u"Le fichier %s a été modifié par %s." % (filename, MYUID)
+        backup(corps, filename, old)
+        notification(u"Modification de %s" % filename, corps, filename, old)
     
     writefile(filepath, json.dumps({'roles': roles, 'contents': contents}))
     return True
@@ -110,21 +109,20 @@ def rmfile(filename):
         return True
     else:
         if validate(roles,'w'):
-            backup(filename, old)
-            notification(u"Suppression de %s" % filename,
-                u"Le fichier %s a été supprimé par %s." % (filename, MYUID),
-                filename, old)
+            corps = u"Le fichier %s a été supprimé par %s." % (filename, MYUID)
+            backup(corps, filename, old)
+            notification(u"Suppression de %s" % filename, corps, filename, old)
             os.remove(getpath(filename))
         else:
             return False
     return True
 
-def backup(fname, old):
+def backup(corps, fname, old):
     """Backupe l'ancienne version du fichier"""
     back = open(getpath(fname, backup=True), 'a')
     back.write(json.dumps(old))
     back.write('\n')
-    back.write('* %s: %s\n' % (str(datetime.datetime.now()),corps)) 
+    back.write((u'* %s: %s\n' % (str(datetime.datetime.now()), corps)).encode("utf-8"))
     back.close()
 
 def notification(subject, corps, fname, old):