[JAVA] Exemple pour créer un mot de passe à usage unique côté serveur et côté client

J'ai créé une logique de mot de passe à usage unique

Au 25 septembre 2020, certaines banques ont été piratées, mais aucune d'entre elles n'a d'authentification comme un mot de passe à usage unique. Bien sûr, si le mot de passe à usage unique est volé "pendant cette seule fois", il sera éliminé, mais il est plus difficile de voler le contenu de la communication à tout moment.

Cependant, le fait que le mécanisme de mot de passe à usage unique dépende d'un mécanisme externe tel que Google Authenticator est un risque dans un autre sens (comme des changements soudains dans les spécifications).

Alors, vérifiez tout ce que vous pouvez faire par vous-même.

Comment ça marche?

Les éléments suivants sont combinés pour générer un condensé (sha256), et 6 chiffres de la valeur numérique sont extraits du condensé.

Source de l'échantillon

Côté terminal

onetime.js



async function digestMessage(message) {
  const encoder = new TextEncoder();
  const data = encoder.encode(message);
  const hash = crypto.subtle.digest('SHA-256', data);
  return hash;
}

function buf2hex(buffer) { // buffer is an ArrayBuffer
  return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}

async function onetimePass(secret_key){
  const ts_min = parseInt( Date.now() / 60000 ).toString();
  const buffer = await digestMessage(secret_key + '_and_sault' + ts_min);
  const hexString = '0x' + await buf2hex(buffer) ;
  const digitString = BigInt(hexString).toString(10);
  return digitString.slice(-6);
}

onetime.html


<html>
<script type="text/javascript" src="./onetime.js"></script>
<body>
<script>
(async () => {
document.write(await onetimePass('secret_key'));
})();
</script>
</body>
</html>

Du côté serveur

onetime.rb


require 'digest/sha1'

def onetime_pass(secret_key, next_min = false)
  #Arrondissez l'horodatage de secondes en minutes
  ts_min = Time.now.to_i / 60
  ts_min += 1 if next_min #Si vous voulez couvrir jusqu'à la minute suivante (le côté recevant le chèque)
  text = "#{secret_key}_and_sault"
  Digest::SHA256.hexdigest("#{text}#{ts_min}").to_i(16).to_s[-6, 6]
end

#En supposant qu'il ne durera qu'une minute, je serai en mesure d'obtenir le mot de passe après une minute
puts onetime_pass('secret_key')
puts onetime_pass('secret_key', true)

Résultat d'exécution

Vous pouvez voir que les mêmes 6 chiffres sont créés sur la face avant et côté serveur. (La deuxième ligne côté serveur est le mot de passe après 1 minute)

image.png

La part qui reste

――Si vous écrivez JS pour la première fois depuis longtemps, quoi que vous fassiez, seules les promesses reviendront. J'ai écrit async et j'attends par essais et erreurs, mais je n'ai pas beaucoup de moi. ――Il semble que RFC a également la logique du mot de passe à usage unique correctement, mais j'en ai fini avec "Je suis sûr que c'est le cas" sans le lire. «J'ai écrit le côté terminal dans JS, mais l'essentiel" comment passer la clé privée "n'est pas mentionné dans cet article. Il semble bon de le transmettre avec un code QR, mais le programme qui lit le code QR et stocke la clé privée dans le stockage local côté terminal semble être beaucoup plus long que la source ci-dessus. Compte tenu de cela, Google Authenticator est utilisé et la bibliothèque côté serveur de Google Authenticator est utilisée, est-ce donc une solution? ――J'ai fait un condensé avec sha256, mais quand je retire les 6 derniers chiffres en décimal, la probabilité de collision augmente.

Recommended Posts

Exemple pour créer un mot de passe à usage unique côté serveur et côté client
(Ruby on Rails6) Comment créer un modèle et une table
Comment créer un serveur d'applications sur une instance EC2 d'AWS
Apache Geode-Easy moyen d'exécuter la logique côté serveur
Comment exécuter React et Rails sur le même serveur
Comment créer un serveur Web sur une instance EC2 d'AWS
Arrêter de renvoyer du client au serveur
[Java] Comment récupérer les paramètres passés du html côté serveur
Exécutable serveur avec Spring gradle Comment créer JAR et WAR
Déboguer avec VSCode + Next.js + Docker (+ Chrome) (prend en charge à la fois le côté serveur et le côté client)
Volume d'essais pour créer une application Web Java sur Windows Server 2016
Exemple d'affichage des notifications (tête haute) sur Android
Implémentation Java pour créer et résoudre des labyrinthes
Exemple pour créer une balise personnalisée pour JSP
[Exemple de code Spring inclus] Comment créer un formulaire et comment obtenir plusieurs enregistrements
Comment partager côté hôte (Windows) et côté invité (CentOS 7) avec VirtualBox