В чем разница между isInsideSecureHardware() и isUserAuthenticationRequirementEnforcedBySecureHardware()?

Android 6.0+ имеет класс KeyInfo, чтобы получить информацию о ключе, сохраненном в AndroidKeyStore. В классе KeyInfo мы имеем методы isInsideSecureHardware() и isUserAuthenticationRequirementEnforcedBySecureHardware(). Мы также имеем isUserAuthenticationRequired(). Документация , как обычно, отстой.

Основываясь на именах методов и (ограниченной) документации, казалось бы, что isUserAuthenticationRequirementEnforcedBySecureHardware() является просто логическим И из isInsideSecureHardware() и isUserAuthenticationRequired().

Есть ли что-то еще для этого? Если да, то что означает, что требование аутентификации пользователя должно выполняться защищенным оборудованием, помимо того, что ключ находится в защищенном оборудовании?

Ответ 1

isUserAuthenticationRequirementEnforcedBySecureHardware() является просто логическим И из isInsideSecureHardware() и isUserAuthenticationRequired().

Я думаю, что это не так (см. методы ниже), он приходит через key из KeyChain.

Есть ли что-то еще для этого?

KeyInfo.java является классом контейнера для key информации от KeyChain. Независимо от того, привязан ли key к защищенному оборудованию, только один раз, когда был импортирован key.

Чтобы узнать, используйте:

{
    PrivateKey key = ...; // private key from KeyChain

    KeyFactory keyFactory =
        KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
    KeyInfo keyInfo = keyFactory.getKeySpec(key, KeyInfo.class);
    if (keyInfo.isInsideSecureHardware()) 
    {
        // The key is bound to the secure hardware of this Android
    }
}

От KeyInfo.java:

/**
 * Returns {@code true} if the key resides inside secure hardware (e.g., Trusted Execution
 * Environment (TEE) or Secure Element (SE)). Key material of such keys is available in
 * plaintext only inside the secure hardware and is not exposed outside of it.
 */
public boolean isInsideSecureHardware() 
{
    return mInsideSecureHardware;
}

/**
 * Returns {@code true} if the requirement that this key can only be used if the user has been
 * authenticated is enforced by secure hardware (e.g., Trusted Execution Environment (TEE) or
 * Secure Element (SE)).
 *
 * @see #isUserAuthenticationRequired()
 */
public boolean isUserAuthenticationRequirementEnforcedBySecureHardware() 
{
    return mUserAuthenticationRequirementEnforcedBySecureHardware;
}

/**
 * Returns {@code true} if the key is authorized to be used only if the user has been
 * authenticated.
 *
 * <p>This authorization applies only to secret key and private key operations. Public key
 * operations are not restricted.
 *
 * @see #getUserAuthenticationValidityDurationSeconds()
 * @see KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean)
 * @see KeyProtection.Builder#setUserAuthenticationRequired(boolean)
 */
public boolean isUserAuthenticationRequired() 
{
    return mUserAuthenticationRequired;
}

См. также:  KeyStore.java

Ответ 2

isUserAuthenticationRequirementEnforcedBySecureHardware() - это просто логическое И из isInsideSecureHardware() и isUserAuthenticationRequired().

Из данной документации метод isUserAuthenticationRequirementEnforcedBySecureHardware не должен быть логическим И выше двух методов.

Для целей наблюдения вы можете рассмотреть этот вопрос, ответ и комментарии.