Frage

Wie der Titel sagt, versuche ich, die programmatischen Teile von RFC4226 "Hotp: Ein HMAC-basierter einmaliger Kennwortalgorithmus" in SQL zu implementieren. Ich denke, ich habe eine Version, die funktioniert (in dem für ein kleines Testbild produziert es das gleiche Ergebnis wie die Java -Version im Code), enthält jedoch ein verschachteltes Paar Hex -Anrufe (unlehörlich ()), die ich Das Gefühl kann besser gemacht werden. Ich bin eingeschränkt, indem ich a) diesen Algorithmus und b) in MySQL tun muss, sonst freue ich mich, andere Möglichkeiten dafür zu betrachten.

Was ich bisher habe:

  -- From the inside out...

  -- Concatinate the users secret, and the number of time its been used
  -- find the SHA1 hash of that string
  -- Turn a 40 byte hex encoding into a 20 byte binary string
  -- keep the first 4 bytes
  -- turn those back into a hex represnetation
  -- convert that into an integer
  -- Throw away the most-significant bit (solves signed/unsigned problems)
  -- Truncate to 6 digits
  -- store into otp
  -- from the otpsecrets table

  select (conv(hex(substr(unhex(sha1(concat(secret, uses))), 1, 4)), 16, 10) & 0x7fffffff) % 1000000
    into otp
    from otpsecrets;

Gibt es eine bessere (effizientere) Art, dies zu tun?

War es hilfreich?

Lösung

Ich habe die Spezifikation nicht gelesen, aber ich denke, Sie müssen zwischen Hex und Binär nicht hin und her konvertieren, daher könnte dies etwas effizienter sein:

SELECT (conv(substr(sha1(concat(secret, uses)), 1, 8), 16, 10) & 0x7fffffff) % 1000000
INTO otp
FROM otpsecrets;

Dies scheint das gleiche Ergebnis wie Ihre Abfrage für einige Beispiele zu geben, die ich getestet habe.

Andere Tipps

Das ist absolut schrecklich, aber es funktioniert mit meinen 6-stelligen OTP-Token. Rufen Sie an:

select HOTP( floor( unix_timestamp()/60), secret ) 'OTP' from SecretKeyTable;

drop function HOTP;
delimiter //
CREATE FUNCTION HOTP(C integer, K BINARY(64)) RETURNS char(6)
BEGIN
    declare i INTEGER;
    declare ipad BINARY(64);
    declare opad BINARY(64);
    declare hmac BINARY(20);
    declare cbin BINARY(8);

    set i = 1;
    set ipad = repeat( 0x36, 64 );
    set opad = repeat( 0x5c, 64 );

    repeat
        set ipad = insert( ipad, i, 1, char( ascii( substr( K, i, 1 ) ) ^ 0x36 ) );
        set opad = insert( opad, i, 1, char( ascii( substr( K, i, 1 ) ) ^ 0x5C ) );
        set i = i + 1;
    until (i > 64) end repeat;

    set cbin = unhex( lpad( hex( C ), 16, '0' ) );
    set hmac = unhex( sha1( concat( opad, unhex( sha1( concat( ipad, cbin ) ) ) ) ) );

    return lpad( (conv(hex(substr( hmac, (ascii( right( hmac, 1 ) ) & 0x0f) + 1, 4 )),16,10) & 0x7fffffff) % 1000000, 6, '0' );
END
//
delimiter ;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top