Replies: 1 comment
-
|
This would have to be implemented client side. See FAQs#I have a feature request for the web-vault (or any other client). |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
Add support for Yandex's proprietary OTP scheme (
yaotp), which is not compatible with standard TOTP (RFC 6238). The differences are fundamental: the output is 8 lowercase letters (not digits), the HMAC key is derived by hashingPIN ‖ secretvia SHA-256, and the final code is base-26 encoded. A standard TOTP library cannot produce correct Yandex OTPs without a dedicated implementation.URI Format
Yandex Authenticator exports the following URI scheme when scanning a QR code from Yandex ID:
Real-world example (redacted)
URI field reference
schemeyaotptotp— requires separate parser branchsecretCZJSEQFM2EQCT2CAKPSUSDHZNYpin244277pin_length6len(pin)— validate on importlength8charsalphauid131541563is_pin_saved_by_usertrueCritical:
algorithmandperiodare not present in the URI. Both are fixed and implied:Algorithm Specification
Reference implementation: KeeYaOtp (C#, GPL-3.0).
Full pipeline
key_material = base32_decode(secret)— all bytes of the decoded secretkey_input = PIN_utf8 ‖ key_material(bytes concatenation)key_hash = SHA-256(key_input)key_hash[0] == 0x00:key_hash = key_hash[1:](31 bytes)period = floor(unix_timestamp_utc / 30)as uint64mac = HMAC-SHA256(key=key_hash, msg=period_big_endian_8_bytes)offset = mac[-1] & 0x0F;slice = int64_be(mac[offset:offset+8]) & 0x7FFFFFFFFFFFFFFFotp = base26(slice % 26^8), zero-padded to 8 lowercase lettersComparison with standard RFC 6238 TOTP
totpyaotpSHA-256(PIN_utf8 ‖ decoded_secret)0–9a–z(base-26)Reference Python implementation
Test Vectors
Generated with
secret=CZJSEQFM2EQCT2CAKPSUSDHZNY,pin=244277,step=30.Use a fixed
timestamp(do not calltime.time()) to reproduce these values.00srfywrjz301uklhjvdc170000000056666666bjtoownp170000003056666667aempofsc175000000058333333cgaycunq175000003058333334kkukwufuReproduce with:
URI Parser Requirements
The parser must handle the
yaotpscheme as a separate code path fromtotp/hotp:otpauth://yaotp/and route to the Yandex OTP handler.secret,pin,length,pin_length,charsfields.chars == "alpha"andlength == 8(reject or warn otherwise).len(pin) == int(pin_length).secretandpinas separate fields — never pre-concatenate or bake the PIN into the secret at storage time.algorithmorperiodfields — they are absent from the URI and implied.Secret Storage Schema
PIN and secret must be stored separately so that a PIN change does not require re-enrollment.
Acceptance Criteria
otpauth://yaotp/URI is parsed without error;otpauth://totp/behavior is unchangedSHA-256(PIN_utf8 ‖ base32_decode(secret))with leading-zero-byte strippingfloor(unix_utc / 30)as 8-byte big-endian uint64pinandsecretare stored in separate fields; concatenation occurs only at OTP generation timelen(pin) != pin_lengthtriggers a validation error on import"0000"edge case, leading-zero-byte stripping (mock SHA-256 to return00...), malformed base32References
Beta Was this translation helpful? Give feedback.
All reactions