We already have an SPI for authenticators, which allows you to create
custom authenticators without modifying Keycloak code. The code
in validCredentials pre-dates the authenticator SPI.
On 15 June 2016 at 16:46, Mitya <mitya(a)cargosoft.ru> wrote:
I'm not quite following the problem. You can encode the
secret/key
using Base32. In fact this Keycloak already stores the secret as a Base32
encoded string. We don't strictly support hardware tokens at the moment as
there's no way to specify the secret, but you can probably do that through
the admin endpoints.
Yep, I've already done it (via custom realm resources, since there is no
SPI for custom *admin* resources yet).
To be accurate: KeyCloak *stores* HOTP secrets as plain strings, but
transfers them to phones as Base32. For example:
s7hAVBHOOPvAnTa3w4mh - this is what is stored in the database (plain
string)
OM3W QQKW IJEE 6T2Q OZAW 4VDB GN3T I3LI - this is printed out to be
entered into FreeOTP / Google Authenticator
When authenticating, the plain string is converted to bytes and used as a
secret for HmacOTP. Since storage type is String/VARCHAR, such a secret is
limited to printable characters.
My intention was to use the KeyCloak's standard HOTP authenticator to
validate OTPs generated by hardware tokens. Unfortunately, tokens that
I'm working with (namely Aladdin eToken PASS) are programmed with seeds
that contain arbitrary bytes, and therefore they cannot be stored into
Credential's "value" field.
But now it turns out that I'll have to implement custom authenticator
either way. Thus, I'll just store seeds as hex string and decode them in my
authenticator before calling HmacOTP. I'll probably use different
credential type, ex., "hotp+", in order not to mess up with KeyCloak OTP.
By the way, do you think having a SPI for credential types could be a good
idea (custom/proprietary OTP algorithms; custom storage format, like in my
case)? At the moment, all the supported credential types (password,
HOTP/TOTP etc.) are hardcoded
into org.keycloak.models.utils.CredentialValidation. If we had a SPI, it
would become possible to add new types without modifying KeyCloak code -
and all the code that
uses context.getSession().users().validCredentials(...) could make use of
new credential types.
Cheers,
Mitya
On 13 June 2016 at 20:14, Mitya <mitya(a)cargosoft.ru> wrote:
The current KeyCloak HOTP implementation assumes that a HOTP key (aka
seed, aka initialization vector) is stored as string, and thus contains
only printable characters. However, the HOTP standard (RFC 4226)
doesn't impose any restrictions on key material; any arbitrary byte
array is acceptable.
Moreover, many hardware HOTP tokens are pre-programmed at the factory,
and do contain non-printable seeds. Even though KeyCloak doesn't
support hardware tokens out of the box, developers could implement it
by extending KeyCloak and employing existing algorithms. Unfortunately,
the existing convention (to store HOTP seeds as printable strings)
makes this impossible.
For the "password" credential type, the "value" field is already
stored
as Base64. I think "hotp" credentials could also be stored as Base64 or
hex; another option would be to store the "value" field as BLOB (like
it's already done for the "salt" field).
I think I could produce a PR for this, I only need to know which
scenario is preferred.
Cheers,
Mitya
_______________________________________________
keycloak-dev mailing list
keycloak-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-dev