diff --git a/src/Entity/UserSystem/WebauthnKey.php b/src/Entity/UserSystem/WebauthnKey.php
index 5a6b70010..abb77a966 100644
--- a/src/Entity/UserSystem/WebauthnKey.php
+++ b/src/Entity/UserSystem/WebauthnKey.php
@@ -52,7 +52,7 @@ class WebauthnKey extends BasePublicKeyCredentialSource implements TimeStampable
 
     #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
     protected ?\DateTimeInterface $last_time_used = null;
-    
+
     public function getName(): string
     {
         return $this->name;
diff --git a/src/Security/TwoFactor/WebauthnKeyLastUseTwoFactorProvider.php b/src/Security/TwoFactor/WebauthnKeyLastUseTwoFactorProvider.php
new file mode 100644
index 000000000..5d67e36f9
--- /dev/null
+++ b/src/Security/TwoFactor/WebauthnKeyLastUseTwoFactorProvider.php
@@ -0,0 +1,106 @@
+<?php
+/*
+ * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
+ *
+ *  Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published
+ *  by the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+declare(strict_types=1);
+
+
+namespace App\Security\TwoFactor;
+
+use App\Entity\UserSystem\WebauthnKey;
+use Doctrine\ORM\EntityManagerInterface;
+use Jbtronics\TFAWebauthn\Services\UserPublicKeyCredentialSourceRepository;
+use Jbtronics\TFAWebauthn\Services\WebauthnProvider;
+use Scheb\TwoFactorBundle\Security\TwoFactor\AuthenticationContextInterface;
+use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\TwoFactorFormRendererInterface;
+use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\TwoFactorProviderInterface;
+use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
+use Symfony\Component\DependencyInjection\Attribute\Autowire;
+use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
+
+/**
+ * This class decorates the Webauthn TwoFactorProvider and adds additional logic which allows us to set a last used date
+ * on the used webauthn key, which can be viewed in the user settings.
+ */
+#[AsDecorator('jbtronics_webauthn_tfa.two_factor_provider')]
+class WebauthnKeyLastUseTwoFactorProvider implements TwoFactorProviderInterface
+{
+
+    public function __construct(
+        #[AutowireDecorated]
+        private TwoFactorProviderInterface $decorated,
+        private EntityManagerInterface $entityManager,
+        #[Autowire(service: 'jbtronics_webauthn_tfa.user_public_key_source_repo')]
+        private UserPublicKeyCredentialSourceRepository $publicKeyCredentialSourceRepository,
+        #[Autowire(service: 'jbtronics_webauthn_tfa.webauthn_provider')]
+        private WebauthnProvider $webauthnProvider,
+    )
+    {
+    }
+
+    public function beginAuthentication(AuthenticationContextInterface $context): bool
+    {
+        return $this->decorated->beginAuthentication($context);
+    }
+
+    public function prepareAuthentication(object $user): void
+    {
+        $this->decorated->prepareAuthentication($user);
+    }
+
+    public function validateAuthenticationCode(object $user, string $authenticationCode): bool
+    {
+        //Try to extract the used webauthn key from the code
+        $webauthnKey = $this->getWebauthnKeyFromCode($authenticationCode);
+
+        //Perform the actual validation like normal
+        $tmp = $this->decorated->validateAuthenticationCode($user, $authenticationCode);
+
+        //Update the last used date of the webauthn key, if the validation was successful
+        if($tmp && $webauthnKey !== null) {
+            $webauthnKey->updateLastTimeUsed();
+            $this->entityManager->flush();
+        }
+
+        return $tmp;
+    }
+
+    public function getFormRenderer(): TwoFactorFormRendererInterface
+    {
+        return $this->decorated->getFormRenderer();
+    }
+
+    private function getWebauthnKeyFromCode(string $authenticationCode): ?WebauthnKey
+    {
+        $publicKeyCredentialLoader = $this->webauthnProvider->getPublicKeyCredentialLoader();
+
+        //Try to load the public key credential from the code
+        $publicKeyCredential = $publicKeyCredentialLoader->load($authenticationCode);
+
+        //Find the credential source for the given credential id
+        $publicKeyCredentialSource = $this->publicKeyCredentialSourceRepository->findOneByCredentialId($publicKeyCredential->rawId);
+
+        //If the credential source is not an instance of WebauthnKey, return null
+        if(!($publicKeyCredentialSource instanceof WebauthnKey)) {
+            return null;
+        }
+
+        return $publicKeyCredentialSource;
+    }
+}
\ No newline at end of file
diff --git a/templates/helper.twig b/templates/helper.twig
index f6de89d6a..b6cf2dbe0 100644
--- a/templates/helper.twig
+++ b/templates/helper.twig
@@ -230,4 +230,12 @@
         {% endfor %}
         </tbody>
     </table>
-{% endmacro parameters_table %}
\ No newline at end of file
+{% endmacro parameters_table %}
+
+{% macro format_date_nullable(datetime) %}
+    {% if datetime is null %}
+        <i>{% trans %}datetime.never{% endtrans %}</i>
+    {% else %}
+        {{ datetime|format_datetime }}
+    {% endif %}
+{% endmacro %}
\ No newline at end of file
diff --git a/templates/users/_2fa_settings.html.twig b/templates/users/_2fa_settings.html.twig
index 2b7f9c4c0..80392c175 100644
--- a/templates/users/_2fa_settings.html.twig
+++ b/templates/users/_2fa_settings.html.twig
@@ -1,5 +1,7 @@
 {# @var user \App\Entity\UserSystem\User #}
 
+{% import "helper.twig" as helper %}
+
 <div class="card mt-4">
     <div class="card-header">
         <i class="fa fa-shield-alt fa-fw" aria-hidden="true"></i>
@@ -124,6 +126,7 @@
                                 <th>#</th>
                                 <th>{% trans %}tfa_u2f.keys.name{% endtrans %}</th>
                                 <th>{% trans %}tfa_u2f.keys.added_date{% endtrans %}</th>
+                                <th>{% trans %}api_tokens.last_time_used{% endtrans %}</th>
                                 <th></th>
                             </tr>
                             </thead>
@@ -133,6 +136,7 @@
                                     <td>{{ loop.index }} <b>(U2F)</b></td>
                                     <td>{{ key.name }}</td>
                                     <td>{{ key.addedDate | format_datetime }}</td>
+                                    <td></td> {# For legacy keys no last time use date is saved #}
                                     <td><button type="submit" class="btn btn-danger btn-sm" name="key_id" value="{{ key.id }}"><i class="fas fa-trash-alt fa-fw"></i> {% trans %}tfa_u2f.key_delete{% endtrans %}</button></td>
                                 </tr>
                             {% endfor %}
@@ -141,6 +145,7 @@
                                     <td>{{ loop.index }} <b>(WebAuthn)</b></td>
                                     <td>{{ key.name }}</td>
                                     <td>{{ key.addedDate | format_datetime }}</td>
+                                    <td>{{ helper.format_date_nullable(key.lastTimeUsed) }}</td>
                                     <td><button type="submit" class="btn btn-danger btn-sm" name="webauthn_key_id" value="{{ key.id }}"><i class="fas fa-trash-alt fa-fw"></i> {% trans %}tfa_u2f.key_delete{% endtrans %}</button></td>
                                 </tr>
                             {% endfor %}
diff --git a/templates/users/_api_tokens.html.twig b/templates/users/_api_tokens.html.twig
index de8771dbe..4c7c83e8a 100644
--- a/templates/users/_api_tokens.html.twig
+++ b/templates/users/_api_tokens.html.twig
@@ -1,12 +1,6 @@
 {# @var user \App\Entity\UserSystem\User #}
 
-{% macro format_date(datetime) %}
-    {% if datetime is null %}
-        <i>{% trans %}datetime.never{% endtrans %}</i>
-    {% else %}
-        {{ datetime|format_datetime }}
-    {% endif %}
-{% endmacro %}
+{% import "helper.twig" as helper %}
 
 <div class="card mt-4">
     <div class="card-header">
@@ -48,15 +42,15 @@
                                 <small class="text-muted">{% trans%}api_token.ends_with{% endtrans%} ...<i>{{ api_token.lastTokenChars }}</i></small></td>
                             <td>{{ api_token.level.translationKey|trans }}</td>
                             <td>
-                                {{ _self.format_date(api_token.validUntil) }}
+                                {{ helper.format_date_nullable(api_token.validUntil) }}
                                 {% if api_token.valid %}
                                     <span class="badge bg-success badge-success">{% trans %}api_token.valid{% endtrans %}</span>
                                 {% else %}
                                     <span class="badge bg-warning badge-warning">{% trans %}api_token.expired{% endtrans %}</span>
                                 {% endif %}
                             </td>
-                            <td>{{ _self.format_date(api_token.addedDate) }}</td>
-                            <td>{{ _self.format_date(api_token.lastTimeUsed) }}</td>
+                            <td>{{ helper.format_date_nullable(api_token.addedDate) }}</td>
+                            <td>{{ helper.format_date_nullable(api_token.lastTimeUsed) }}</td>
                             <td>
                                 <button type="submit" class="btn btn-danger btn-sm" name="token_id"
                                         value="{{ api_token.id }}" {% if not is_granted('@api.manage_tokens') %}disabled="disabled"{% endif %}>