[*] -  SecureInfo.eu, /Crypto/xor.py

Back


#!/opt/homebrew/bin/python3
# -*- coding: utf-8 -*-

#
# Imports
#

# sys.exit()
import sys

# getopt.getopt
from getopt import getopt

# base64.encodestring
import base64

# decode hexa
from binascii import unhexlify

#
# Variables globales
#

# Nom de l'application
APP="xor"

# Fonction ...: <string> complexify(key<string>,arg<string>)
#
# Variables ..: key= Clé, arg= Données à chiffrer
#
# Retourne ...: newkey= Nouvelle clé
#
# Description : Genère une clé au moins aussi longue que les données à chiffrer
#
#   === Données d'entrée
#   Longueur de 'arg' ..: 38
#   Valeur de 'arg' ....: ceci est un message privé à chiffrer
#
#   === Tour n° 1
#   Longueur de 'newkey': 13
#   Valeur de 'newkey' .: UEBzc3cwcmQ=
#
#   === Tour n° 2
#   Longueur de 'newkey': 29
#   Valeur de 'newkey' .: VUVCemMzY3djbVE9ClBAc3N3MHJk
#
#   === Tour n° 3
#   Longueur de 'newkey': 53
#   Valeur de 'newkey' .: VlVWQ2VtTXpZM2RqYlZFOUNsQkFjM04zTUhKawpQQHNzdzByZA==
#
#
# -----------------------------------------------------------------------------
#
def complexify(key,arg):

  newkey = ""
  i = 0
  # print "#\n#   === Données d'entrée"
  # print "#   Longueur de 'arg' ..:",len(arg)
  # print "#   Valeur de 'arg' ....: "+arg
  # print "#\n"
  while len(newkey) <= len(arg):
    i = i + 1
    # print "#   === Tour n°",i
    newkey = base64.encodestring(newkey + key)
    # print "#   Longueur de 'newkey':",len(newkey)
    # print "#   Valeur de 'newkey' .: "+newkey
  return( newkey.strip() )

# Fonction ...: <string> xor(arg<string>,key<string>,format<string>)
#
# Variables ..: arg= Données à chiffrer, key= Clé, format= Format d'affichage
#
# Retourne ...: enc= Données (dé)chiffrées
#
# Description : Chiffre les valeur ordinales des octets des données
#               avec l'opération XOR
#
# -----------------------------------------------------------------------------
#
def xor(arg,key,method):

  if method == 'string':
    i,enc,key = 0,b'',key.encode('utf8') # ,'surrogatepass')
    while i < len(arg):
      enc = enc + bytes([ arg[i]^key[i%len(key)] ])
      i = i + 1
    return(enc)

  if method == 'hex':
    i,enc,key = 0,b'',unhexlify(key)
    while i < len(arg):
      enc = enc + bytes([ arg[i]^key[i%len(key)] ])
      i = i + 1
    return(enc)

# Fonction ...: <void> usage(err<int>)
#
# Variables ..: err= Numéro de code d'erreur de sortie du programme via exit()
#
# Retourne ...: -
#
# Description : Affichage de l'aide d'utilisation
#
# -----------------------------------------------------------------------------
#
def usage(err):
  print("""
Usage: %s <-s string|-f file> <-k|-x password> [-z] [-o file]

    -s : string to (de)crypt
    -X : string in hexa format

    -k : password
    -K : password in hexa format

    -f : file to crypt
    -o : file to write output

    -z : harden password by cumulative base64 encoding until the length
         of the password is greater than the content to encrypt

  """ % APP)
  sys.exit(err)

# Fonction ...: <void> error(err<int>)
#
# Variables ..: descr= description Ă  afficher
#               err= Numéro de code d'erreur de sortie du programme via exit()
#
# Retourne ...: Sorts avec le code d'erreur fourni
#
# Description : Affichage d'un message d'erreur et sort du programme
#
# -----------------------------------------------------------------------------
#
def error(descr,err):
  print("\nError: " + descr + "\n")
  sys.exit(err)


# Variables ..: Les paramètres cités ci-dessus
#
# Retourne ...: Si la sortie est dans un fichier: : rien
#               Sinon affiche le résultat au format sélectionné
#
# Description : Programme principal
#
# -----------------------------------------------------------------------------
#
if __name__ == '__main__':

  out = ""
  key = ""
  operation = ""
  target = ""
  arg = ""

  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  #
  # * On essaye de récupérer les arguments passés ... 
  #
  try:
    opts,args = getopt(sys.argv[1:],"x:zCHRDIs:f:k:ho:X:K:")
    for o,a in opts:
      # Seule l'option -s ou ...
      if o == "-s":
        if target:
          usage
        target="string"
        arg = a.encode()
      if o == "-X":
        arg = unhexlify(a)
        target="string"
      # ... l'option -f doit ĂŞtre choisie
      if o == "-f":
        if target:
          usage
        target="file"
        arg = a
      if o == "-K":
        key = a
        method = "hex"
      if o == "-k":
        key = a
        method = "string"
      if o == "-o":
        out = a
      if o == "-z":
        operation = "hardkey"
      if o == "-h":
        usage(0)

  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  #
  # * .. sinon on y arrive pas, on affichage l'aide
  #
  except:
    error("invalid arguments.",1)

  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  #
  # Si les arguments obligatoires ne sont pas définis
  # on affiche l'aide
  #
  if not ( key and arg and target ) : 
    usage(1)
    sys.exit(1)

  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  #
  # Si les données à chiffrer sont dans un fichier, on récupère son contenu
  #
  if target == "file":
    # On essaie de lire le fichier (il peut ĂŞtre binaire)
    try:
      fh = open(arg,"rb")
      buff = fh.read()
      fh.close()
    except:
      error("unable to read input file",1)

    # Reposition dans 'arg' le contenu de 'buff'
    # Pour éviter les opérations distinctes -> [2]
    arg = buff

  # Si ça n'est pas un fichier, et que ça n'est pas une chaine de caractère
  # (cas improbable), on gère l'erreur et on affiche l'aide
  elif target != "string":
    error("this is not a valid string",2)

  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  #
  # Opérations commune à toutes les options
  #

  # [1] -> Le renforcement ou non, de la clé est commune à tester dans
  # tous les cas
  if operation == "hardkey":
    key = complexify(key,arg)
    fh = open(out+".key","w")
    fh.write(key)
    fh.close()

  # [2] -> L'opération de chiffrement est commune à toutes les options
  enc = xor(arg,key,method)

  # [3] -> Si l'opération d'écriture dans un fichiers
  if out == "":
    print(enc.decode())
  else:
    try:
      fh = open(out,"wb")
      fh.write(enc)
      fh.close()
    except:
      error("unable to write output file",1)
⬆️ Top
admin