Ôtant une ID
Je suis à la recherche d'un moyen de crypter/obscurcir un ID d'entier dans un autre entier. Plus précisément, j'ai besoin d'une fonction int F(int x)
, de sorte que
- x<->F(x) est one-to-one correspondance (si x != y, F(x) != F(y))
- donnée F(x), il est facile à trouver x donc F n'est pas une fonction de hachage
- x et F(x), il est difficile/impossible de trouver F(y), quelque chose comme
x ^ 0x1234
ne fonctionne pas
Pour plus de clarté, je ne suis pas à la recherche d'une forte solution de chiffrement, c'est seulement de l'obscurcissement. Imaginez une application web avec les url comme example.com/profile/1
, example.com/profile/2
etc. Les profils eux-mêmes ne sont pas secrets, mais je tiens à prévenir casual voyeurs à vue/chercher tous les profils, l'un après l'autre, donc, je préfère les cacher derrière quelque chose comme example.com/profile/23423
, example.com/profile/80980234
etc. Bien que la base de données stockée jetons peuvent faire le travail assez facilement, je suis curieux de savoir si il y a quelques calculs simples disponibles pour cela.
Une exigence importante je n'ai pas été clair, c'est que les résultats devraient regarder "aléatoire", c'est, étant donné une séquence x,x+1,...,x+n
, F(x),F(x+1)...F(x+n)
ne devrait pas former une progression de tout genre.
- Est int F(int x) d'une obligation, ou pourrait-il en être de type int[2]F(int x) ?
- Rieck, dans l'idéal, j'aimerais x et F(x) soit dans la gamme de nombre
- Peut-F(X) secret?
- oui la fonction sera gardé secret
- puisque vous avez dit que vous aimeriez aller sans jeton, est-ce à dire que vous voulez éviter tout type de table de recherche?
- Mošmondor, oui, exactement.
- L'homme, cette question est parfaitement indiqué et c'est exactement ce que je cherche. Nice job.
Vous devez vous connecter pour publier un commentaire.
Dissimuler avec une combinaison de 2 ou 3 méthodes simples:
x
ety
qui sont multiplicatif inverses les uns des autres (modulo 232), puis multiplier parx
pour dissimuler et de se multiplier pary
à restaurer, toutes les multiplications sont modulo 232 (source: "Une utilisation pratique de multiplicative inverses" par Eric Lippert)De longueur Variable numberic méthode de système de ne pas obéir à votre "progression" exigence sur son propre. Il produit toujours de courte progressions arithmétiques. Mais lorsqu'il est combiné avec une autre méthode, il donne de bons résultats.
La même chose est vraie pour les représentations modulaires méthode.
Voici le code C++ exemple pour 3 de ces méthodes. Lecture aléatoire de bits exemple possible d'utiliser certains de ces masques et les distances à être de plus en plus imprévisibles. 2 autres exemples sont bons pour de petits nombres (juste pour donner l'idée). Ils devraient être étendus pour dissimuler toutes les valeurs entières correctement.
Vous voulez que la transformation est réversible, et pas évident. Qui sonne comme un chiffrement qui prend un nombre dans un intervalle donné et produit un nombre différent dans la même gamme. Si votre portée est de 64 bits, puis utiliser DES. Si votre portée est de 128 bits, puis d'utiliser AES. Si vous souhaitez une autre gamme, alors votre meilleur pari est probablement Hasty Pudding de chiffrement, qui est conçu pour faire face à différentes tailles de bloc et avec des tranches de numéros qui ne sont pas parfaitement dans un bloc, comme 100 000 à 999,999.
Obscurcissement n'est pas vraiment suffisante en termes de sécurité.
Toutefois, si vous essayez de déjouer le spectateur occasionnel, je vous recommande une combinaison de deux méthodes:
a été appliqué
Voici un exemple (à l'aide de pseudo-code):
Je ne l'ai pas testé, mais je pense que c'est réversible, doit être rapide, et pas trop facile à démêler la méthode.
return x XOR rotr(31415927, 5)
bien, non? La dernière xor annule la première, et la tourne annuler eachother.. et bien sûr, toute la chaîne réversible est également réversible, de sorte qu'il ne satisfait à cette condition.x = x XOR F(0)
, oux = x XOR 3087989491
, oux = x XOR rotr(31415927, 5)
. Votre prénom et votre xors annuler les uns les autres, de sorte que tous vous avez à faire est xoring la bitshifted entrée avec la touche - ou, de manière équivalente, xoring de l'entrée avec la bitshifted clé. Remarque c'est vrai même si vous avez utilisé des clés différentes pour chaque étape - toutes les touches pourraient être composés dans une seule clé peut être xored avec le texte en clair.J'ai trouvé ce morceau particulier de Python/PHP code très utile:
https://github.com/marekweb/opaque-id
J'ai écrit un article sur sécuriser les permutations avec des algorithmes de chiffrement par bloc, qui devrait répondre à vos exigences comme indiqué.
Que je vous suggère, cependant, que si vous voulez dur à deviner identifiants, vous devez simplement les utiliser en premier lieu: générer des Uuid, et les utiliser comme clé primaire pour vos dossiers, en premier lieu - il n'y a pas besoin d'être en mesure de convertir vers et à partir d'un "vrai" ID.
Faire n'importe quoi avec les bits de l'IDENTIFIANT qui ne les détruisent pas. Par exemple:
Pour le décryptage, faire tout ce qui dans l'ordre inverse.
Créer un programme pour "chiffrer" certains les valeurs intéressantes pour vous et les mettre dans un tableau, vous pouvez examiner. Ont le même programme de TEST de cryptage/décryptage de routine AVEC tout un ensemble de valeurs que vous voulez avoir dans votre système.
Ajouter des éléments à la liste ci-dessus dans les routines jusqu'à ce que vos numéros regarde bien mutilé pour vous.
Pour quoi que ce soit d'autre, d'obtenir une copie de Le Livre.
J'ai écrit quelques code JS à l'aide de certaines des idées dans ce fil:
Elle produit de bons résultats comme:
Test avec:
XOR1
etXOR2
sont juste des nombres aléatoires entre 0 etMAX
.MAX
est2**32-1
; vous devez définir ce que vous pensez que votre ID plus sera.COPRIME
est un nombre premier ' w/MAX
. Je pense premier les nombres eux-mêmes sont premiers entre eux avec chaque autre numéro (à l'exception des multiples d'eux-mêmes).INVERSE
est difficile à comprendre. Ces billets de blog ne donne pas une réponse directe, mais WolframAlpha peut le comprendre pour vous. Fondamentalement, suffit de résoudre l'équation(COPRIME * x) % MAX = 1
pourx
.La
build
fonction est quelque chose que j'ai créé pour faciliter la création de ces encoder/décoder des pipelines. Vous pouvez nourrir autant d'opérations que vous voulez que[encode, decode]
paires. Ces fonctions doivent être égales et opposées. LeXOR
fonctions sont leurs propres compliments de sorte que vous n'avez pas besoin d'une paire de là.Voici un autre plaisir l'involution:
(ce qui suppose que 24 bits entiers -- il suffit de changer les numéros pour toute autre taille)
n
est un certain nombre de postfix pour BigInts. C'est un nouveau JS fonctionnalité qui vous permet vraiment de grands nombres. J'avais besoin de l'utiliser parce que je suis en multipliant par vraiment des grands nombres qui peuvent causer l'une des valeurs intermédiaires temporairement dépasserNumber.MAX_SAFE_INTEGER
et perdre de la précision.Pas sûr de savoir comment "dur" que vous en avez besoin, comment rapide, ou comment peu de mémoire à utiliser. Si vous n'avez pas de contraintes de mémoire, vous pourriez faire une liste de tous les nombres entiers, les mélanger et utiliser cette liste comme une cartographie. Cependant, même pour un 4 octets entier vous aurait besoin de beaucoup de mémoire.
Toutefois, cela pourrait être plus petits de sorte qu'au lieu de la cartographie de tous les nombres entiers vous mappez seulement 2 (ou pire des cas 1) octet de poids fort et de les appliquer à chaque groupe en entier. Donc, à l'aide de 2 octets entier serait (groupe1)(groupe2) vous mappez chaque groupe par le biais de la carte aléatoire. Mais cela signifie que si vous modifiez uniquement le groupe2 le mappage pour le groupe1 resterait la même. Cela pourrait "fixe" de la cartographie des différents bits de chaque groupe.
Donc, *(groupe2) pourrait être (peu 14,12,10,8,6,4,2,0) donc, l'ajout de 1 changerait à la fois groupe1 et groupe2.
Encore, ce n'est que la sécurité par l'obscurité, quelqu'un qui peut nourrir des numéros dans votre fonction (même si vous gardez la fonction secret) pourrait assez facilement le comprendre.
Générer un privé clé symétrique pour l'utiliser dans votre application, et chiffrer votre entier avec elle. Cela permettra de satisfaire aux trois exigences, y compris les plus difficiles #3: on aurait besoin de deviner votre clé afin de briser votre système.
Ce que vous décrivez ici semble être à l'opposé d'une fonction: il est facile d'inverser mais super difficile à appliquer. Une option serait d'utiliser une norme, hors-the-shelf de la clé publique de chiffrement algorithme dans lequel vous fixer un (secret, au hasard choisi) de la clé publique que vous garder un secret et d'une clé privée que vous partagez avec le monde entier. De cette façon, votre fonction F(x) serait le chiffrement de x à l'aide de la clé publique. Vous pouvez ensuite facilement décrypter F(x) à x en utilisant le privé, clé de déchiffrement. Notez que les rôles des clés publiques et privées sont reprises ici - vous donner la clé privée à tout le monde afin qu'ils puissent décrypter la fonction, mais de garder la clé publique de secret sur votre serveur. De cette façon:
Cela a de nombreux avantages. Tout d'abord, vous pouvez être assuré que la crypto système est sûr, car si vous utilisez un réseau bien établi d'algorithme de type RSA, alors vous n'avez pas besoin de vous soucier accidentelle de l'insécurité. Deuxièmement, il y a déjà des bibliothèques pour ce faire, de sorte que vous n'avez pas besoin de code beaucoup et peut être à l'abri de côté les attaques par canaux. Enfin, vous pouvez rendre possible pour quiconque d'aller et inverser F(x) sans que personne effectivement en mesure de calculer F(x).
Un détail vous devriez certainement pas juste être en utilisant le standard de type int ici. Même avec les entiers 64 bits, il y a si peu de combinaisons possible pour un attaquant de juste force brute essayer d'inverser tout jusqu'à ce qu'ils trouvent le chiffrement F(y) pour un certain y même si elles n'ont pas la clé. Je suggère d'utiliser quelque chose comme un 512-bit de la valeur, étant donné que même la science-fiction attaque ne serait pas en mesure de forcer cette.
Espérons que cette aide!
Si
xor
est acceptable pour tout, mais inférerF(y)
donnéx
etF(x)
alors je pense que vous pouvez le faire avec un sel. Choisissez d'abord un secret une sorte de fonction. Par exempleS(s) = MD5(secret ^ s)
. PuisF(x) = (s, S(s) ^ x)
oùs
est choisi au hasard. J'ai écrit que comme un tuple, mais vous pouvez combiner les deux pièces en un entier, par exempleF(x) = 10000 * s + S(s) ^ x
. Le déchiffrement des extraits du sels
de nouveau et utiliseF'(F(x)) = S(extract s) ^ (extract S(s)^x)
. Compte tenu dex
etF(x)
vous pouvez voirs
(même si elle est légèrement obscurci) et vous pouvez déduireS(s)
mais pour un autre utilisateury
avec un autre hasard selt
l'utilisateur sachantF(x)
ne pouvez pas trouverS(t)
.S(s)
permettra également de regarder de manière aléatoire de sorteF(x)
n'importe quel type de progression de la maladie à tous.