HOTP ve TOTP, bir telefon kimlik doğrulayıcı uygulamasının gösterdiği kodlardır. Her iki fonksiyon da sgcCrypto_OTP içinde bulunur ve HMAC üzerine kuruludur (bkz. Hash'leme ve Mesaj Kimlik Doğrulama).
HOTP (sayaç tabanlı)
Kod, paylaşılan bir gizli değere ve her kullanımda birer birer ilerleyen bir sayaca bağlıdır. İstemci ve sunucu birbiriyle uyumlu kalmalıdır: istemci sunucunun hiç görmediği kodlar üretirse (örneğin ağ bağlantısı olmadan basılan bir düğme), sayaçlar birbirinden uzaklaşır ve istemcinin sonrasında gösterdiği her kod, sunucu yeniden senkronize edene kadar başarısız olur. Bu kayma, TOTP'nin çoğu tüketici kimlik doğrulayıcı kullanımında HOTP'nin yerini almasının ana nedenidir.
function sgcHOTP(const aSecret: TBytes; aCounter: Int64; aDigits: Integer = 6): string;
TOTP (zaman tabanlı)
HOTP'deki sayaç, varsayılan olarak 30 saniye olan sabit adımlara bölünmüş geçerli Unix zamanıyla değiştirilir; bu yüzden istemcinin ve sunucunun yalnızca kabaca senkronize saatlere ihtiyacı vardır, senkronize bir sayaca değil. Her kimlik doğrulayıcı uygulamasının uyguladığı budur.
function sgcTOTP(const aSecret: TBytes; aUnixTime: Int64; aDigits: Integer = 6;
aStep: Integer = 30; aHash: TsgcKDFHash = khSHA1): string;
{ Takes the base32 secret exactly as an authenticator app displays or scans it. }
function sgcTOTP_FromBase32(const aSecretBase32: string; aUnixTime: Int64;
aDigits: Integer = 6; aStep: Integer = 30; aHash: TsgcKDFHash = khSHA1): string;
Bir kodu doğrulama
aWindow, geçerli olandan önceki ve sonraki o kadar adımdan gelen kodları kabul eder; bu, küçük bir saat kaymasını veya kodu yazması yavaş olan bir kullanıcıyı emer. Karşılaştırma dahili olarak sabit zamanlıdır, bu yüzden bir tahminin kaç basamağının doğru olduğunu sızdırmaz.
function sgcTOTP_Verify(const aSecret: TBytes; const aCode: string; aUnixTime: Int64;
aWindow: Integer = 1; aDigits: Integer = 6; aStep: Integer = 30; aHash: TsgcKDFHash = khSHA1): Boolean;
var
oSecret: TBytes;
begin
oSecret := sgcRandomBytes(20);
if sgcTOTP_Verify(oSecret, edtCode.Text, DateTimeToUnix(Now, False)) then
{ accepted };
end;
Bir gizli anahtarı hazırlama (provisioning)
Bir kimlik doğrulayıcı uygulaması, bir otpauth:// URI'sini kodlayan bir QR kodu taranarak kurulur. İçindeki gizli anahtar base32 ile kodlanmıştır (bkz. Cryptography genel bakış sayfasındaki sgcBase32Encode):
var
oSecret: TBytes;
vURI: string;
begin
oSecret := sgcRandomBytes(20);
vURI := 'otpauth://totp/MyApp:user@example.com?secret=' + sgcBase32Encode(oSecret) +
'&issuer=MyApp&digits=6&period=30';
{ render vURI as a QR code for the user to scan }
end;