La solution pour des identicones sécurisées: le random id

Une identicone c’est une image qui permet d’identifier un compte, ça permet de voir rapidement si on est sur le bon compte ou non, car le cerveau humain mémorise et reconnaît bien plus vite efficacement une image qu’une suite de caractère pseudo-aléatoire en base58.

Le problème, c’est que les identicones ont une entropie très faible, bien souvent pas plus de quelques dizaines de milliers d’images suffisamment différentes pour ne pas être confondues.

Il est donc facile pour un attaquant de bruteforcer un input de manière à avoir la même identicone qu’un autre compte, pour réaliser une attaque de phising par exemple.

Or il est certain que si l’on fournit une identicone, la plupart des utilisateurs lambda ne feront plus attention à l’adresse (anciennement clé publique), et il sera donc plus (trop) facile de réaliser une attaque de phising.

Pour avoir des identicones sécurisés, il faut donc que l’input sur lequel on se base pour générer l’identicone ne soit pas influençable par l’utilisateur.

Hum, générer une donnée non influençable par l’utilisateur, c’est exactement l’une des propriétés qu’apportent les VRF (Verifiable random Function).

Avec duniter-v2s, on a une source d’aléatoire robuste et vérifiable fournie par le consensus BABE, et l’on peut se servir de cette source d’aléatoire pour tout usage.

L’idée est donc de générer un random id pour chaque compte Ğ1, ce random id pourra alors être utilisé comme « graine » pour les identicones, et éventuellement pour d’autres usages.

Afin que ce random id ne soit réellement ni prédictible ni influençable, il doit être généré à partir d’une VRF collective qui concatène toutes les VRF d’une epoch, ce qui nécessite un délai de quelques heures entre la demande du random id et son assignation.

La demande de random id sera automatique dès la création du compte, la création d’un compte étant définie comme le fait d’y déposer de la monnaie. Ainsi, tout compte Ğ1 aura son random id.

Pour l’attaquant, il reste possible de créer plein de comptes pour demander plein de random id dans l’espoir d’en obtenir un qui donne la même identicone que le compte pour lequel il souhaite se faire passer.

Pour empêcher cela, mais également pour se protéger contre le spam de création de plein de simples portefeuilles, la création d’un simple portefeuille sera payante, le prix étant une constante du runtime, dont il faudra choisir la valeur, valeur qui sera modifiable par runtime upgrade.

Les frais ne seront pas détruits, mais alimenteront une trésorerie commune (pallet treasury), on verra plus tard comment la gérée, dans un premier temps ce sera par une proportion des membres forgerons pour faire simple.

Le random id fait 32 octets, c’est en fait un hash blake2-256 entre la seed aléatoire fournie par la blokchain et le AccountId.

1 « J'aime »

Bonne idée.

Mais les frais d’ouverture de comptes ne serviront qu’à ce random id ?

Ça risque de compliquer l’utilisation de compte jetables, nécessaires par exemple pour l’anonymisation. Peut-être qu’on pourrait ne pas demander de random id pour certains comptes, mais ça complexifierait les extrinsics…

Ça sert aussi à lutter contre le spam de comptes. Car chaque nouveau compte à un coût en terme de stockage onchain lié à la seule existence du compte.

Créer un nouveau compte pour chaque transfert c’est coûteux en traitement pour la blockchain, car la notion de compte gère beaucoup de choses dont on a par besoin pour un compte jetable à usage unique, comme le nonce par exemple.

Le mieux c’est de créer 2 extrinsics dédiés pour les transfert vers et depuis un compte jetable, ce sera beaucoup plus efficient.
Ce serait un compte spécial dégradé qui ne pourrait que « transfer all » et une seule fois avec 2 destinataires en paramètres.

1 « J'aime »

Et pourquoi ne pas faire une identicon basé sur le checksum de la pubkey ?
J’ai fait ça dernièrement pour g1compagnon, avec la couleur de fond basée aussi sur la pubkey :

image

Je trouve ce genre d’identicon beaucoup plus identifiable que ce genre d’identicons :

source : https://github.com/ethereum/blockies

Peux-tu expliciter ? En plus du minimum d’existence du compte (mettons 1G1) , il faudrait payer des frais si on verse de la monnaie sur un compte pas encore existant en BDD?

Qu’en serait-il pour un compte qui aurait été vidé (donc supprimé de la BDD), puis recrédité ? Devra-t-il subir de nouveau des frais lors du versement ?

Relis le début de mon post @ManUtopiK , j’explique pourquoi li ne faut surtout par faire ça pour des raisons de sécurité.
Il est très facile de générer des milliards de pubkey très rapidement pour obtenir l’identicone qu’on veut, or il ne faut pas que l’utilisateur puisse choisir quelle identicone il aura.
L’identicone doit être dérivé d’informations qui ne peuvent pas être chosies ni manipulées par l’utilisateur, la seule solution que je vois c’est d’utiliser une source aléatoire robuste et vérifiable.

De plus, dans la Ğ1v2 il n’y aura plus de pubkey ni de checksum, mais des adresses au format ss58, un format qui intègre nativement un checksum dans l’adresse.

Oui c’est exactement ça. Voici un exemple avec un dépôt d’existence de 2 Ğ1 et le frais de création de compte de 3 Ğ1. Soit Alice un compte avec 10 Ğ1 et Bob un compte qui n’existe pas (donc avec 0 Ğ1 et pas d’identité).
Alice doit alors verser au moins 5Ğ1 sur le compte de Bob. Si elle en verse moins, l’intégralité des Ğ1 versées seront transférées à la trésorerie au bloc d’après.
Si Alice verse par exemple 8 Ğ1 sur l’adresse de Bob, le compte de Bob aura 5Ğ1, et 3 Ğ1 iront à la trésorerie.

Oui il devra les payer de nouveau.

Je vois l’intérêt coté sécurité et anti-spam.
En revanche je vois aussi le surplus de complexité pour l’utilisateur.
Ça ne veut pas dire que je suis contre, mais qu’il me semble important de réfléchir à comment rendre ça simple d’usage, plus particulièrement pour les nouvelleaux avant de le mettre en place.

  • Je débarque dans la ML, je trouve intéressant et je ne connais encore personne, je veux créer un compte porte feuille pour vendre des choses, comment je fais ? Avec ce que j’ai compris, j’ai besoin d’un don ou d’une vente pour ouvrir mon compte, mais je ne connais pas encore l’adresse ss58 correspondante, du coup ça me donne l’impression d’un serpent qui se mort la queue.
  • Je veux créer un compte anonyme, je dois lui envoyer de la monnaie depuis un compte existant, qui lui même aura reçu pour sa création de la monnaie depuis un compte existant… Ok, ça n’empèche pas de mixer à certain moment, mais ça me semble complexifier l’anonymat. Ceci dit, pour ce sénario @elois à déjà proposé une solution technique :
1 « J'aime »

Mais pourquoi donc ?? Je ne vois aucune raison de ne pas afficher l’adresse correspondante à une clé publique, ceci ne dépend pas de la blockchain.

Du point de vue de l’UX, l’utilisateur aura toujours l’impression de « créer » son compte alors que son application n’a fait que générer une paire de clé, et afficher une adresse avec un solde de zéro.

Svp quand je parle des règles de la blockchain arrêter d’essayer de calquer ça tel quel à l’UX, c’est évidemment idiot de le calquer tel quel, aucune application grand public ne fait ça.

Concrètement pour l’utilisateur ça change une seule et unique chose: le premier dépôt sur un compte doit être d’au moins 5 Ğ1.

Ce qui est déjà le cas dans Duniter v1, et ce qui est forcément le cas dans tous les cas, puisque de la monnaie ne peut être reçue que depuis un compte qui en possède, sauf à créer le DU mais dans ce cas ce n’est pas un simple portefeuille.

Je ne suis pas d’accords, ce serait justement peut être intéressant que « les applications grand public » dans l’écosystème blockchain s’intéressent un peu plus à l’UX qu’implique leur protocole blockchain.

Malgré leurs moyens, je ne sais pas vraiment à qui s’adresse l’UX développé par les équipes de polkadot. Rien de ce que je vois ne semble s’adresser à M. tout le monde. Ils semblent s’adresser à un public d’expert ou de passionné, présents uniquement par intéret mercantile, et donc prêt à passer des heures d’apprentissage extérieur pour comprendre les tenants et aboutissant des interfaces qui leurs sont proposés.

Les réflexions de 1000i100 me semblent donc saines.


En manipulant la lib JS polkadot, j’observe que la gestion d’identicon/avatar semble complètement intégré à la génération et gestion d’adresses.

Pour eux visiblement (polkadot & co) cela ne semble pas poser de problème de sécurité.
Ce que tu proposes ici, semble certe très intéressant, mais implique des choses qui alourdissent encore le protole et l’UX. Cela ne me semble pas KISS.

Est-on sûr que celà soit prioritaire pour la migration ?
Je compends que changer de format d’identicon en cours de route ne serait pas sympa pour les utilisateurs et lourd à pousser sur tous les clients wallets.
Mais ne pourrait-on pas juste ne pas poposer d’identicon au début le temps de bien analyser pourquoi polkadot et toutes les cryptos ne semblent pas voir de problème à utiliser des identidon basés sur leurs addresse+checksum, et évaluer d’abords avec un peu de recul ce que donne les autres règles anti-spam induites par la migration, avant d’en rajouter ?

Personellement je suis pour rester coller un max à ce que propose les libs substrate dans un premier temps.

Question ouverte hein, je ne sais pas.

Un problème tout de même : la quantité d’identicones que peut posséder une personne dépend directement de sa richesse.

Donc plus on est riche, plus on a de chances de tromper les gens trop peu rigoureux avec un identicone ressemblant à un autre. Mais j’imagine que ça ne devrait pas gêner si l’UX n’incite pas à les utiliser pour reconnaître à coup sûr un compte dans un annuaire, mais plutôt pour le retrouver dans son carnet d’adresse personnel.

Les riches pourraient aussi profiter plus de cette fonctionnalité, mais bon à quoi ça servirait d’avoir 10000 identicones, une dizaine par personne devrait largement suffire, ce qui devrait être abordable par tous.

Cette proposition me convient, à condition d’avoir des comptes à usage unique peu chers.

Je ne pense pas, mais si on prévoit de faire ça plus tard il faut que les devs de clients s’accordent pour ne pas inventer d’identicones de leur côté avant que ce soit implémenté globalement…

J’en ai marre de ne pas être compris :confused:

Putain bien sûr qu’il faut réfléchir à l’UX, que c’est ultra essentiel, je suis à fond d’accord, mais justement l’UX ne pout pas et ne doit pas se calquer bêtement sur les règles de la blockchain, je dois le dire en chinois ou bien ?

Non les remarque de @1000i100 sont à côté de la plaque, je suis désole mais si on doit perdre du temps avec des bases aussi triviales on ne va pas pouvoir avancer, je crois qu’elle ne va jamais se faire cette migration si vous continuez …

Mais non justement, tu viens de le dire c’est fait pour les geeks ou les riches, qui donc savent ce qu’ils font et vérifient bien les adresses car en cas d’erreur ils perdent beaucoup d’argent.

Si je propose ce random id c’est justement car je pense qu’il est particulièrement adapté pour protéger des utilisateurs lambda non-avertis, M. tout le monde quoi.

M. tout le monde quoi n’a pas conscience de comment ça marche derrière et si on leur donne une image ils ne se fieront qu’à elle, donc elle doit impérativement être difficile à falsifier.

Sauf que non, car tu oublies le délai entre 2 générations de random id, et même avec des centaines de milliers de Ğ1 ça reste infiniment plus limité (quelques essais par heure) que de bruteforcer urne adresse (des milliards d’essais par seconde pour ce même riche qu peut se payer une machine puissante).
Et si un « riche » en génère plein ça va se voir en blockchain, donc on peut prévenir plus particulièrement la communauté, et puis fa oblige ce riche à faire des « dons » très conséquents à la communauté puisse chaque tentative implique un paiement à la trésorerie commune.

2 « J'aime »

Ok, je suis reposé, et je ne trouve toujours pas mes question débile, donc il doit y avoir une incompréhension majeur entre nous @elois
Ce que j’ai compris :
Pour générer un nouveau porte-feuille, il faut passer par un random-id payant (qui sert de seed depuis laquelle sera dérivé la clef publique au format ss58).

  • Vu tes réactions, c’est très probablement que le random-id n’interviens pas à cet endroit, du coup, pourrais-tu clarifier cet aspect ?
  • Notamment si le random-id n’a rien à voir avec la crypto du compte porte-feuille, comment compte et random-id sont ils lié ?
  • l’identicon à pour vocation de vérifier simplement qu’il s’agit du bon compte. Si le random-id n’est pas la seed du compte, alors cette vérification ne marche qu’en requêtant la blockchain (ou proxy) pour vérifier le lien. Ce n’est pas vérifiable offline. On ne peut régénérer l’identicon depuis la ss58 (sauf à requêter pour avoir le random-id associé).

On a donc 2 cas :

  • si je comprends bien, celui que tu proposes : seed(privateKey) + ss58(pubKey) + random-id (associé à la ss58 par un document en blockchain) → conséquence : création de compte offline mais vérification identicon online
  • ce que j’avais compris : seed=random-id(privateKey) +ss58(pubKey) → conéquence : complexifie la création de compte même portefeuille (et encore plus celle d’hardware wallet), complexifie l’anonymat à la création (puisque qu’on peut raisonnablement considérer que l’auteur d’un porte-feuille de cette manière est aussi l’approvisionneur du financement de la création), en revanche, les vérifications par l’identicon peuvent être faites simplement et offline avec le gain de sécurité de ne pas pouvoir bruteforcer pour avoir des identicons proche d’un autre.

Si cette fois j’ai bien compris ce que tu proposes, ma question aux dev de wallet deviens :
Vos scénarios de vérification d’adresses ss58 sont-ils compatibles (côté connectivité et réactivité) avec la génération d’un identicon faisant suite à une requête du random-id correspondant au ss58 à vérifier ?

D’après ce que j’ai compris ça n’a rien à voir avec la clé privée :

pubkey + blockchain → [VRF] → random_id → identicon

L’identicone se déduit donc de la clé publique et des paramètres de la VRF au moment de la génération du random_id. La clé publique reste générée hors-ligne.

Est-ce qu’un client voulant afficher un identicone doit demander à un indexeur le random_id correspondant à la clé publique, ou peut-il stocker un historique pas trop grand des résultats de VRF pour en déduire tous les random_id antérieurs ?

Si chaque affichage d’identicone nécessite un accès réseau ou un index à jour, ça fait moins envie…

1 « J'aime »