[JAVA] Beispiel zum Erstellen eines Einmalkennworts auf Server- und Clientseite

Ich habe eine Einmalkennwortlogik erstellt

Bis zum 25. September 2020 wurden einige Banken geknackt, aber keine von ihnen verfügt über eine Authentifizierung wie ein Einmalpasswort. Wenn das Einmalpasswort "während dieser einmaligen Zeit" gestohlen wird, ist es natürlich nicht verfügbar, aber es ist für die Person schwierig, den Kommunikationsinhalt jederzeit zu stehlen.

Die Tatsache, dass der Einmalkennwortmechanismus von einem externen Mechanismus wie Google Authenticator abhängt, ist jedoch in einem anderen Sinne ein Risiko (z. B. plötzliche Änderungen der Spezifikationen).

Überprüfen Sie also, wie viel Sie selbst tun können.

Wie funktioniert es?

Die folgenden Elemente werden kombiniert, um einen Digest (sha256) zu generieren, und 6 Ziffern des numerischen Werts werden aus dem Digest extrahiert.

Beispielquelle

Klemmenseite

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>

Serverseite

onetime.rb


require 'digest/sha1'

def onetime_pass(secret_key, next_min = false)
  #Runden Sie den Zeitstempel von Sekunden auf Minuten
  ts_min = Time.now.to_i / 60
  ts_min += 1 if next_min #Wenn Sie bis zur nächsten Minute abdecken möchten (die Seite, die den Scheck erhält)
  text = "#{secret_key}_and_sault"
  Digest::SHA256.hexdigest("#{text}#{ts_min}").to_i(16).to_s[-6, 6]
end

#Unter der Annahme, dass es nur eine Minute dauert, kann ich das Passwort nach einer Minute erhalten
puts onetime_pass('secret_key')
puts onetime_pass('secret_key', true)

Ausführungsergebnis

Sie können sehen, dass auf der Vorderseite und der Serverseite dieselben 6 Ziffern erstellt werden. (Die zweite Zeile auf der Serverseite ist das Passwort nach 1 Minute)

image.png

Der Rest

――Wenn Sie JS zum ersten Mal seit langer Zeit schreiben, kommen nur Versprechen zurück, egal was Sie tun. Ich habe asynchron geschrieben und warte auf Versuch und Irrtum, aber ich habe nicht viel von mir. ――Es scheint, dass RFC auch die Logik eines Einmalkennworts richtig hat, aber anstatt es zu lesen, bin ich sicher, dass es so ist ――Ich habe die Terminalseite in JS geschrieben, aber das wesentliche "Übergeben des privaten Schlüssels" wird in diesem Artikel nicht erwähnt. Es scheint gut, es mit einem QR-Code zu übergeben, aber das Programm, das den QR-Code liest und den privaten Schlüssel im lokalen Speicher auf der Terminalseite speichert, scheint viel länger zu sein als die obige Quelle. In Anbetracht dessen wird Google Authenticator verwendet und die Bibliothek auf der Serverseite von Google Authenticator wird verwendet. Ist dies also eine Lösung? ――Ich habe mit sha256 einen Digest erstellt, aber wenn ich die letzten 6 Ziffern dezimal herausnehme, erhöht sich die Kollisionswahrscheinlichkeit.

Recommended Posts

Beispiel zum Erstellen eines Einmalkennworts auf Server- und Clientseite
(Ruby on Rails6) So erstellen Sie ein Modell und eine Tabelle
So erstellen Sie einen Anwendungsserver auf einer EC2-Instanz von AWS
Apache Geode-Einfache Möglichkeit, Logik auf der Serverseite auszuführen
So führen Sie React und Rails auf demselben Server aus
So erstellen Sie einen Webserver auf einer EC2-Instanz von AWS
Stoppen Sie das erneute Senden vom Client zum Server
[Java] So rufen Sie die von HTML auf der Serverseite übergebenen Parameter ab
Server mit Spring Gradle ausführbar So erstellen Sie JAR und WAR
Debuggen mit VSCode + Next.js + Docker (+ Chrome) (unterstützt sowohl Server- als auch Client-Seite)
Umfang des Versuchs, eine Java-Webanwendung unter Windows Server 2016 zu erstellen
Beispiel für die Anzeige von (Head-up-) Benachrichtigungen auf Android
Java-Implementierung zum Erstellen und Lösen von Labyrinthen
Beispiel zum Erstellen eines benutzerdefinierten Tags für JSP
[Spring-Beispielcode enthalten] So erstellen Sie ein Formular und erhalten mehrere Datensätze
Freigeben auf der Hostseite (Windows) und der Gastseite (CentOS 7) mit VirtualBox