Time-based one-time password algorithm: Difference between revisions

m
syntax highlighting fixup automation
(Added Wren)
m (syntax highlighting fixup automation)
Line 31:
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Security.Cryptography;
 
Line 92:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Caché ObjectScript}}==
 
<langsyntaxhighlight lang="cos">
Class Utils.Security [ Abstract ]
{
Line 182:
 
}
</syntaxhighlight>
</lang>
{{out|Example}}
<pre>
Line 200:
=={{header|Go}}==
A slightly [https://github.com/gwwfps/onetime/pull/1 fixed] version of a [https://github.com/gwwfps/onetime package by Zitao Zhang] (released under a [https://github.com/gwwfps/onetime/blob/master/LICENSE simplified BSD license]).
<langsyntaxhighlight lang="go">// Package onetime provides a library for one-time password generation,
// implementing the HOTP and TOTP algorithms as specified by IETF RFC-4226
// and RFC-6238.
Line 273:
p[0] &= 0x7f
return p
}</langsyntaxhighlight>
{{out|Example use}}
(in a format that gets put into the [https://godoc.org/github.com/dchapes/onetime generated documentation])
<langsyntaxhighlight lang="go">package onetime
 
import (
Line 314:
var code = otp.TOTP(secret)
fmt.Println(code)
}</langsyntaxhighlight>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">using CodecBase
using SHA
 
Line 355:
sleep(15)
end
</langsyntaxhighlight>{{out}}
<pre>
656601
Line 372:
Note that due to the interface of the hash function in module “std/sha1”, we have chosen to work with sequences of characters rather than sequences of bytes. The other way is of course possible, but maybe less convenient.
 
<langsyntaxhighlight Nimlang="nim">import endians, math, sequtils, std/sha1, times
 
type
Line 470:
 
echo "Google authenticator:"
exampleAuthenticator()</langsyntaxhighlight>
 
{{out}}
Line 480:
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight Perllang="perl"># 20200704 added Perl programming solution
 
use strict;
Line 493:
for ( my $t = 2177452800 ; $t < 2177452919 ; $t += 13 ) {
print "At ", scalar gmtime $t, " : ", $oath->totp( $message, $t ), "\n" ;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 511:
{{trans|Perl}}
Note the byte ordering of hmac (etc) is suspect and may change, hence bmap below
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.1"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- sha1.e added</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">sha1</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
Line 544:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"At %s : %06d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">totp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">message</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 561:
=={{header|PicoLisp}}==
Using the <tt>sha1</tt> function defined at ''[[SHA-1#PicoLisp]]'':
<langsyntaxhighlight PicoLisplang="picolisp">(load "sha1.l")
 
(de hmac ("Fun" Msg Key)
Line 614:
(test
(cdr L)
(totp (mapcar char (chop "12345678901234567890")) (car L) 8) ) )</langsyntaxhighlight>
 
=={{header|Racket}}==
This includes BASE32 encoding, token based authentication and other such stuff.
 
<langsyntaxhighlight lang="racket">#lang racket
(require (only-in web-server/stuffers/hmac-sha1 HMAC-SHA1))
 
Line 762:
(base32-encode-bytes #"Super Secret Password Key 88!")
=> #"KN2XAZLSEBJWKY3SMV2CAUDBONZXO33SMQQEWZLZEA4DQII="
))</langsyntaxhighlight>
 
{{out}}
Line 780:
(formerly Perl 6)
This is a minimal attempt that covers only the "Time-based" part of the requirement.
<syntaxhighlight lang="raku" perl6line># Reference:
# https://github.com/retupmoca/P6-Digest-HMAC
 
Line 803:
say totp $message, DateTime.new(now);
}
</syntaxhighlight>
</lang>
{{out}}
<pre>Deterministic output at 2039-01-01T00:00:00Z with fixed checks,
Line 824:
This TOTP/HOTP module clocks in small by taking advantage of [https://core.tcl.tk/tcllib/doc/trunk/embedded/www/toc.html tcllib's] existing hashing and base32 modules.
 
<syntaxhighlight lang="tcl">
<lang Tcl>
# rfc6238 contains examples of hotp with 8-digit modulus and sha1/sha256/sha512 hmac
#
Line 895:
}
assert {{306281 553572 304383} eq [google 1400000000]}
}</langsyntaxhighlight>
 
=={{header|Wren}}==
Line 904:
{{libheader|Wren-srandom}}
As Wren-cli currently has no way of determining the Unix time, this needs to be input as a command line parameter so we can track it from there.
<langsyntaxhighlight lang="ecmascript">import "os" for Process
import "./long" for ULong
import "./crypto" for Bytes, Sha1, Sha256, Hmac
Line 980:
var randKey = List.filled(32, null)
for (i in 0..31) randKey[i] = alphabet[SRandom.int(32)]
System.print(otp.totp(randKey.join().bytes.toList))</langsyntaxhighlight>
 
{{out}}
Line 997:
Uses the MsgHash dll, which includes SHA-1, SHA-256 hashes and HMAC routines for SHA-* and MD5.
{{trans|Go}}
<langsyntaxhighlight lang="zkl">var [const] MsgHash = Import.lib("zklMsgHash");
// OneTimePassword stores the configuration values relevant to HOTP/TOTP calculations.
Line 1,033:
fcn totp(secret){ hotp(secret, steps(Time.Clock.time())) }
fcn steps(now) { (now - baseTime)/timeStep } // elapsed time chunked
} // OneTimePassword</langsyntaxhighlight>
Note: MsgHash hashes return a string by default, they can also return the hash as bytes. Ditto the HMAC routines, it is the third parameter. So, to create a hmac that returns bytes, use (eg) MsgHash.extra.hmacSHA1.fp2(False), this creates a partial application (closure) of the hmac using SHA-1 fixing the third parameter as False.
{{out|Example uses}}
<langsyntaxhighlight lang="zkl">fcn example_simple{
// Simple 6-digit HOTP code:
secret := "SOME_SECRET";
Line 1,061:
code := otp.totp(secret);
println(code) //-->eg 707355416
}();</langsyntaxhighlight>
{{out|Example use}}
Showing how to sync with changes over time. A six digit OTP w/MD5 changing every 17 seconds. Latency can effect the result when totp is called at a time boundary, so a retry may be required.
<langsyntaxhighlight lang="zkl">fcn overTime{
secret,ts:= "SOME_SECRET",17;
otp := OneTimePassword(6,ts,Time.Clock.time(),MsgHash.extra.hmacMD5.fp2(False));
Line 1,074:
Atomic.sleep(10);
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,091:
{{out|HMAC code}}
The MsgHash HMAC routines are pretty simple (the hash code is C), included here for completeness:
<langsyntaxhighlight lang="zkl">// https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
fcn hmac(key,msg,hashFcn,asString){
blkSz,H,Hx := 64,hashFcn.fp1(1,Data()), (asString and hashFcn or H);
Line 1,104:
fcn hmacSHA1( key,msg,asString=True){ hmac(key,msg,MsgHash.SHA1, asString) }
fcn hmacSHA256(key,msg,asString=True){ hmac(key,msg,MsgHash.SHA256,asString) }
fcn hmacMD5( key,msg,asString=True){ hmac(key,msg,Utils.MD5.calc,asString) }</langsyntaxhighlight>
10,333

edits