Garder un secret de chaîne dans le code source (ouvert)

50

J'ai fini de développer une application pour Android et j'ai l'intention de la publier avec GPL. Je veux qu'elle soit open source. Cependant, la nature de l'application (un jeu) est qu'elle pose des énigmes et que les réponses sont codées dans la ressource chaîne. Je ne peux pas publier les réponses! On m'a dit de chercher à stocker les mots de passe en toute sécurité - mais je n'ai rien trouvé de approprié.

Est-il possible de publier mon code source avec un tableau de chaînes caché, crypté ou autrement masqué? Peut-être en lisant les réponses d'une base de données en ligne?

Mise à jour

La solution de Yuval Filmus ci-dessous a fonctionné. Quand je l'ai lu pour la première fois, je ne savais toujours pas comment le faire. J'ai trouvé des solutions, pour la deuxième option: stocker la solution hachée dans le source et calculer le hachage à chaque fois que l'utilisateur le devinait. Pour ce faire, vous devez utiliser la bibliothèque crypto-js à l' adresse http://code.google.com/p/crypto-js/ . Pour Android, utilisez la fonction MessageDigest . Il existe une application (sur fdroid / github) appelée HashPass qui fait cela.

Plus jamais
la source
11
Je me demande à quel point cela est ici. Dans tous les cas, il peut être mieux adapté à la sécurité de l’information .
Raphaël
2
@YuvalFilmus Ne vous laissez pas berner par les votes "Hot Question". Mais point pris.
Raphaël
4
Les informations importantes manquantes ici sont les suivantes: voulez-vous simplement vérifier les réponses des utilisateurs ou voulez-vous aussi pouvoir imprimer la bonne réponse? Et avez-vous besoin de fuzzines, ou existe-t-il simplement un ensemble clair et limité de réponses correctes (qui vous permettent de vérifier la réponse de l'utilisateur par rapport à cet ensemble, une par une)?
Hyde
4
Toutes les réponses demandent quel est le problème que vous souhaitez résoudre. Pourquoi ne pouvez-vous pas publier les réponses?
Rhymoid
1
Qu'est-ce que votre code doit pouvoir faire avec ces chaînes? At-il besoin de pouvoir les décoder? Ou est-il suffisant de pouvoir comparer des chaînes à ces chaînes?
David Schwartz

Réponses:

83

Vous avez au moins deux options, en fonction du problème que vous souhaitez résoudre.

Si vous souhaitez que des lecteurs innocents de votre code n'obtiennent pas les réponses par inadvertance, ou au moins que vous vouliez rendre les choses plus difficiles pour que les utilisateurs ne soient pas tentés, vous pouvez chiffrer les solutions et stocker la clé dans le code, par exemple. résultat de quelques calculs (pour le rendre encore plus difficile).

Si vous souhaitez empêcher les utilisateurs de récupérer la réponse, vous pouvez utiliser une fonction unidirectionnelle ou, dans le jargon de l'ordinateur, une fonction de hachage . Stocker un hachage de la réponse, et ils vous pouvez tester si la réponse est correcte sans qu'il soit possible d' en déduire la réponse du tout sans la trouver d' abord. Cela a pour inconvénient qu'il est plus difficile de rechercher une réponse proche de la bonne réponse, bien qu'il existe des solutions même à ce problème.

Yuval Filmus
la source
9
J'ajouterais que si vous avez besoin de plus de sécurité, chaque réponse doit probablement être salée avec un sel différent. Cela évite une attaque par dictionnaire contre toutes les réponses à la fois. Si vous voulez voir comment les "vrais" spécialistes de la cryptographie le font, jetez un coup d'œil au système String-to-Key d'OpenPGP .
Pseudonyme
1
Conserver les hachages dans le code signifie que toutes les informations sont statiques et que le sel ou tout autre élément sera facilement disponible. Je pense qu'en conséquence, il serait raisonnable que l'espace de réponse soit suffisamment grand (comme une gamme complète de valeurs entières de 32 bits), sinon (dans le cas de questions à choix multiples), un tableau arc-en-ciel donnerait rapidement les réponses correctes.
Alexei Levenkov
3
Comme Alexei le fait remarquer, si vos entrées possibles couvrent un petit espace, le stockage des réponses dans le code les ouvrira à tout attaquant déterminé - et je suppose que la plupart des énigmes auront des espaces d'état plutôt petits, car leurs réponses doivent généralement être: soit des mots ou des nombres relativement petits. Vous pouvez utiliser un hachage ou un cryptage pour éviter les erreurs innocentes, mais rien n'empêche quelqu'un d'obtenir la réponse qui le souhaite vraiment. (En plus, ils pourraient simplement demander à quelqu'un qui a déjà résolu votre énigme!)
Chris Hayes
4
Pour contrer ce que Chris mentionne, vous pouvez choisir un processus de hachage très lent, par exemple, cela prend 100 ms (c'est l'approche adoptée par certaines normes PK). Ceci est encore très rapide du point de vue de l'utilisateur, mais rend l'énumération beaucoup plus difficile.
Yuval Filmus
12
@YuvalFilmus Encore une fois, dans une certaine mesure. Si votre énigme se termine par "Jan, Joe ou Jane étaient-ils des criminels?" il sera alors très facile à énumérer même si vous faites en sorte que le hachage prenne une minute complète. Si le jeu n’est pas écrit dans cet esprit et si toutes les questions sont extrêmement ouvertes, cela posera un problème. Mais oui, si vos questions sont si ouvertes que l’espace d’état est suffisamment grand, les réponses peuvent être protégées.
Chris Hayes,
28

Vous avez deux trois options:

Gardez les réponses séparées du reste du code source

Si vous voulez que votre code soit open source, mais que les réponses ne soient pas open source, vous devez ouvrir le code source de l'application sans les questions et réponses, les questions et réponses étant un "plugin" fermé distinct ou fichier de données. Votre application Android regrouperait ces deux éléments en une seule application.

Mettez les réponses dans votre code source

Sinon, si vous considérez les questions et les réponses comme une partie essentielle de ce que vous voulez utiliser en source ouverte, vous devriez alors placer les réponses dans le code source, de préférence non obscurci pour que les autres puissent les lire et les modifier . Obstruer le code source afin qu'il ne puisse pas être compris et modifié ne correspond pas vraiment aux principes du code source ouvert.

Mettez les réponses sur un serveur sur Internet

Avec les deux solutions ci-dessus, il est possible pour quelqu'un qui a téléchargé votre application de trouver les réponses sans lire votre programme dans les deux cas - peu importe la façon dont vous obscurcissez / chiffrez vos réponses, si votre programme peut identifier la réponse sans informations supplémentaires, Un humain peut-il examiner votre application compilée?

Si vous voulez vraiment vous assurer que personne ne peut trouver les réponses, alors la seule véritable option est de ne pas leur donner les réponses et de laisser l'application appeler un service Web, etc. ... chaque fois qu'ils veulent connaître la réponse. L’application doit envoyer la réponse saisie par l’utilisateur et le service Web doit indiquer à l’application si la réponse est correcte ou non. De cette manière, l’utilisateur n’a aucun moyen de dire quelle est la réponse tant qu’ils ne disposent pas de la bonne réponse (bref). forcer brusquement le service Web, que vous pouvez détecter et protéger contre).

Si vous cherchez des moyens de brouiller vos réponses, cela me suggère que vous ne voulez pas vraiment ouvrir vos réponses en source, alors vous devriez envisager les premières options.

S'il est essentiel que l'utilisateur ne puisse pas trouver la réponse à l'avance, alors la troisième option est votre seul choix réel. Cependant, j'ai du mal à imaginer un scénario dans lequel cela en vaudrait la peine, surtout parce que cela empêche vos utilisateurs d'utiliser votre application sans connexion Internet.

Justin
la source
8
Les questions-réponses n'ont même pas besoin d'être un plugin, il peut s'agir d'un simple fichier de données. Les fichiers de données d'entrée ne font pas nécessairement partie du logiciel sous licence et peuvent être couverts par leur propre licence distincte. Tant que vous fournissez un exemple de fichier de données (différent) à utiliser avec le code source, vous ne faites pas obstacle à l'utilisation gratuite de la source ou des programmes compilés à partir de cette source et ne devez donc pas enfreindre la GPL.
Doktor J
Je ne suis pas sûr que cela résolve vraiment son problème - que les réponses soient cryptées et codées en dur dans le code ou distribuées sous forme de fichier séparé, le code doit toujours être en mesure de déchiffrer les réponses, afin que celui qui télécharge son application puisse faire ce qu'il veut. le code source fait pour obtenir les réponses. (sauf s'ils sont hachés, comme suggéré dans une autre réponse)
Johnny
1
Si l'objectif est de vérifier les réponses et de ne pas exiger qu'elles soient affichées, cela peut se faire de la même manière que les mots de passe avec un hachage à sens unique.
JamesRyan
@Justin, merci de votre réponse, et vos commentaires sur l'opportunité de créer une source ouverte sont intéressants. Je pense que cacher les réponses n’a pas pour but d’obscurcir le code source, ni le fonctionnement de l’application, mais plutôt de préserver l’intégralité du défi. Il s'avère que la cryptographie est un moyen formidable de distribuer des énigmes sans être obligée d'être présente lorsque l'utilisateur devine ("est-ce cela, est-ce que c'est?")
Nevermore
4

Si l'objet doit masquer des chaînes provenant d'une lecture occasionnelle du code source mais les garder ouvertes afin que d'autres personnes puissent facilement apporter leurs propres modifications - par exemple, si vous publiez le code source dans une aventure textuelle et que vous ne voulez pas qu'un texte descriptif apparaisse qui constituerait un spoiler, alors utilisez quelque chose de réversible comme rot13.

En fait, vous pouvez effectuer une rotation 13 dans tous vos fichiers de traduction et les retourner à la volée.

C'est garder l'esprit ouvert. La "magie" aléatoire n'est pas vraiment conviviale pour les programmeurs.

moopet
la source
4
N'oubliez pas que beaucoup de personnes parmi nous, GéoCaching, lisent rot13 presque aussi couramment que l'original.
Yo '
4

Open source nécessite que le code source soit rendu public et disponible, pas les données du jeu. Vous pouvez donc facilement placer les données dans un autre fichier et ne pas le publier. Ajoutez un peu de cryptage si vous souhaitez empêcher la lecture accidentelle du fichier. Je doute qu'un crypto fort soit nécessaire pour votre application.

liftarn
la source
1
Dans quel sens pouvez-vous "ne pas publier" les données du jeu? Le jeu doit pouvoir accéder à ces données pour que quiconque en ait une copie en ait une copie. C’est à peu près exactement ce que l’édition est: rendre public.
David Richerby
1
@DavidRicherby Dépend de ce que vous voulez publier et comment se terminer. Ce jeu ou votre moteur pourrait-il être utilisé pour créer de nombreux jeux similaires? Autoriser les gens à manipuler votre jeu, inspecter le code pour détecter les failles de sécurité ou simplement réutiliser des composants? Si votre interface est aussi simple que "CSV avec q & a + programme = jeu", je pense qu'il est concevable de ne publier que le programme, pas le CSV.
Raphaël
1
@Raphael Mais distribuer un jeu constitué d'un exécutable et d'un fichier de données en texte brut n'atteint pas l'objectif de rendre les réponses secrètes. Si vous souhaitez proposer une version chiffrée du fichier de données, c'est très bien, tant que tout le monde comprend qu'il ne s'agit que de sécurité par obscurité (la clé est dans la source). Mais nous abordons ensuite la question de savoir si le texte en clair du fichier de données constitue un code source au sens de la GPL et, à ce stade, la question devient une question d’interprétation de la GPL, plutôt que de l’informatique.
David Richerby,
@DavidRicherby: D'accord. Malgré tout, bien que IANAL, je doute fort qu'un fichier de données composé de devinettes et de leurs réponses soit considéré comme une partie essentielle et irremplaçable du programme, de sorte qu'il ne puisse pas faire l'objet d'une licence séparée - en particulier si vous incluez un exemple de fichier de données non crypté la distribution source, accompagnée d'instructions de modification et de cryptage si nécessaire, indique clairement que toute personne disposant du code source peut en effet créer ses propres fichiers de données personnalisés et les utiliser avec le programme.
Ilmari Karonen
4

Pourquoi voudriez-vous stocker vos réponses dans votre code source GPL si vous ne voulez pas que vos utilisateurs les connaissent? Même s'ils ne sont pas connus ou faciles à craquer maintenant, ils peuvent l'être (et le seront probablement) à l'avenir.

Au lieu de les stocker dans votre application, utilisez une base de données externe. Créez un petit service Web qui compare les réponses à ce qui se trouve dans votre base de données. Laissez ensuite votre application appeler ce service Web chaque fois que celle-ci doit être vérifiée. Le principal problème est que, du fait qu’il nécessite un accès à Internet, vous perdrez un peu de vitesse et votre potentiel d’utilisateur. votre licence d'application ne devrait s'appliquer que pour l'application elle-même, pas pour le service Web.

Vous pouvez aussi simplement mettre vos réponses dans une petite base de données et la mettre dans votre programme. Autant que je sache, la GPL ne s'applique qu'au code source, pas aux données stockées par votre application. Je peux me tromper à ce sujet, cependant.

Nzall
la source
1
"Pour autant que je sache, la GPL ne s'applique qu'au code source, pas aux données stockées par votre application". La licence GPL stipule que "vous devez accorder une licence à l’ensemble du travail, en vertu de la présente licence, à toute personne qui entre en possession d’une copie". Vous pourriez donc penser que nous devons maintenant décider si les données font partie de "l'ensemble du travail". Mais en réalité, toutes les restrictions de la GPL (y compris celle-ci) ne s’appliquent qu’aux licenciés. Il est bon que les donneurs de licence respectent également l'esprit de la GPL, mais ils ne devraient pas avoir à s'inquiéter de la visite de la police des droits d'auteur.
Peter Ford
1

N'oubliez pas que même si vous stockez une base de données sur un serveur Web distant, vous pouvez toujours dupliquer la base de données en notant simplement toutes les paires clé / valeur correctes observées. Et de manière générale, les applications mobiles doivent essayer de ne pas générer d'erreurs ni de cesser de fonctionner parce que le réseau est en panne (utilisez la messagerie en file d'attente et mettez à jour lorsque vous le pouvez).

Donc, si vous voulez une base de données locale, mais que vous n'aimez pas l'idée de le déchiffrer de manière flagrante, vous pouvez utiliser un filtre bloom (pour éviter de parler à un réseau ou d'avoir une grosse base de données déchiffrée localement). C’est ainsi que les vérificateurs d’orthographe fonctionnaient lorsque l’espace mémoire était vraiment restreint.

Donc, si vous ajoutez des paires question / réponse dans le filtre comme:

Hash (NormalizeString (Question [n])) + Hash (NormalizeString (Réponse [n]))

Si vous demandez si "Capitol of Virginia? Richmond" est dans le jeu, il répondra soit "définitivement non", soit "presque certainement oui". Si vous obtenez trop de faux positifs, agrandissez la base de données.

Vous pouvez disposer d’une immense base de données dans un espace restreint, en supposant que l’utilisateur épellera la question et la réponse exactement comme vous le souhaitez. La taille réduite de la base de données facilite les mises à jour, car elles doivent probablement être transférées via des réseaux sans fil.

Rob
la source