Class MFASecretSeal

java.lang.Object
com.iizix.server.security.MFASecretSeal

public final class MFASecretSeal extends Object
The seal of the shared secret of a user's second factor, as it is stored (SignIn L-6; D-24 of the SignIn survey: the secret sealed by the server's own key).

The stored value is the purpose, the user ID and the Base32 secret, sealed through ISensitiveParameterHandler.encodeParameter(String) exactly as EmailVerificationLink and PasswordResetLink seal a link: AES-256-GCM under the installation's key, the GCM tag as the keyed MAC. A copy of the database alone gives no secret. The purpose keeps a value the server sealed for anything else from being taken as a secret, and the user ID keeps the sealed secret of one user from being moved into the row of another.

What the seal depends on. The key is one of the server's keys file (iiziServer.keys); a sealed secret names its key by the fingerprint. A server that has lost that file, or that shares the database with another server and not the keys file, cannot open the secret: the verification codes of the user are then refused as a system failure, while the recovery codes, which are hashed and not sealed, still sign in.

Author:
Christopher Mindus
  • Method Details

    • seal

      public static String seal(ISensitiveParameterHandler keys, long userID, String secret) throws GeneralSecurityException
      Seals the secret of a user.
      Parameters:
      keys - The server's sealing keys.
      userID - The user ID the secret is the secret of.
      secret - The Base32 shared secret.
      Returns:
      The sealed value to store, URL-safe characters only.
      Throws:
      GeneralSecurityException - If the secret cannot be sealed.
      NullPointerException - If keys or secret is null.
      IllegalArgumentException - If the secret is empty or holds a line break.
    • open

      public static String open(ISensitiveParameterHandler keys, long userID, String sealed) throws GeneralSecurityException
      Opens the sealed secret of a user.

      The value is opened with the server's keys, which fails for a value sealed by another server, for one altered anywhere and for anything that is not a sealed value at all; the content must then carry the purpose and the user ID given. The exception of a refusal never carries the content.

      Parameters:
      keys - The server's sealing keys.
      userID - The user ID of the row the value was read from.
      sealed - The sealed value as stored.
      Returns:
      The Base32 shared secret.
      Throws:
      GeneralSecurityException - If the value is missing, was not sealed by this server, was altered, was sealed for another purpose or for another user.
      NullPointerException - If keys is null.