Je vous propose un challenge intéressant avec un début de réponse: comment écrire un programme qui se teste lui-même pour savoir s'il n'a pas été modifié.
(bien sûr cela ne compte pas d'utiliser la date de modification du fichier)
Bien entendu "cela ne peut pas marcher car on peut toujours modifier le programme pour enlever l'étape de vérification" et le sujet a sans doute été maintes fois abordés de manière bien plus complexe par ceux qui luttent contre le piratage ou la tricherie.
Mais j'ai trouvé l'idée rigolote d'essayer d'inclure un checksum du code dans le code lui-même.
J'ai donc implémenté cela en utilisant l'algorithme Luhn mod N et cela donne ça en Python 3:
import argparse, string
def GenerateCheckCharacter(codepoints, text):
factor = 2
summation = 0
n = len(codepoints)
for i in range(len(text)-1, -1, -1):
codePoint = codepoints.index(text[i])
addend = factor * codePoint
factor = 1 if (factor == 2) else 2
addend = int(addend / n) + (addend % n)
summation += addend
remainder = summation % n
checkCodePoint = (n - remainder) % n
return codepoints[checkCodePoint]
def ValidateCheckCharacter(codepoints, text):
factor = 1
summation = 0
n = len(codepoints)
for i in range(len(text)-1, -1, -1):
codePoint = codepoints.index(text[i])
addend = factor * codePoint
factor = 1 if (factor == 2) else 2
addend = int(addend / n) + (addend % n)
summation += addend
remainder = summation % n
return (remainder == 0)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Luhn mod N algorithm demonstration')
parser.add_argument('--codepoints', type=str, nargs='?', default = string.printable, help='Verify file')
parser.add_argument('--generate', type=str, nargs='?', default = None, help='Generate check character to add at the end of the file')
parser.add_argument('--verify', type=str, nargs='?', default = None, help='Verify file')
args = parser.parse_args()
if args.generate:
filename = args.generate
elif args.verify:
filename = args.verify
else:
filename = __file__
with open(filename) as fp:
text = fp.read()[:-1]
if args.generate:
character = GenerateCheckCharacter(args.codepoints, text)
print(f"Character to add at the end of the file: '{character}' (character code {args.codepoints.index(character)})")
else:
character = text[-1]
print(f"Character found at the end of the file: '{character}' (character code {args.codepoints.index(character)})")
print(f"File is verified: {ValidateCheckCharacter(args.codepoints, text)}")
print("Script ended successfully")
# <
Vous pouvez donc voir le "checksum" à la fin du code. Notez bien que j'enlève le vrai dernier caractère (retour à la ligne) pour l'algorithme.
Si on modifie le code, le "checksum" va changer et la vérification ne marchera plus.
Ce que je n'ai pas réussi à faire, c'est de me passer d'ajouter ce dernier caractère.
Normalement le dernière caractère c'est un retour à ligne et si on est malin on peut modifier astucieusement le dernier print pour que le "checksum" corresponde exactement à un retour à la ligne.
J'image qu'il faut tenter une approche "brute-force" en générant des phrases autour de variations ("Script ended perfectly", "Script executed without issues", "No errors detected", etc.). Mais pour l'instant cela dépasse mes compétences, mais si vous voulez tenter…
Ce serait vraiment rigolo car cela rendrait vraiment le programme assez mystérieux pour les non-initiés.
Voilà, j'ai trouvé cet algorithme Luhn Mod N assez sympathique et je souhaitais partager cela avec vous.
Peut-être que vous avez d'autres algorithmes dans ce genre pour la même utilisation ?
# Rigolo.
Posté par Axioplase ıɥs∀ (site web personnel) . Évalué à 3 (+1/-0).
On peut rajouter des espaces, tabs, du dead code partout pour changer le checksum.
C'est souvent comme ca que les attaques de collision sont generees.
Envoyer un commentaire
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.