diff --git a/.gitmodules b/.gitmodules
index 03c4d7ef34b5640eb308541e82e4614d49fcf9e4..59b125caeb0d14f34a1a16aef03af39004e78cd9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,3 @@
-[submodule "lib/sdk-php"]
-	path = lib/sdk-php
-	url = https://github.com/privacyidea/sdk-php.git
-	branch = master
\ No newline at end of file
+[submodule "www/js/webauthn-client"]
+	path = www/js/webauthn-client
+	url = https://github.com/privacyidea/webauthn-client.git
\ No newline at end of file
diff --git a/composer.json b/composer.json
index ccdf66e3f960cf4d2a29a802e90b95276b06d111..b033507dcc0bd3094aefbc74e9a8321527d83019 100644
--- a/composer.json
+++ b/composer.json
@@ -4,6 +4,7 @@
     "type": "simplesamlphp-module",
     "license": "AGPL-3.0",
     "require": {
-        "simplesamlphp/composer-module-installer": "~1.0"
+        "simplesamlphp/composer-module-installer": "~1.0",
+        "privacyidea/privacyidea-php-client": "dev-master"
     }
 }
diff --git a/dictionaries/privacyidea.translation.json b/dictionaries/privacyidea.translation.json
index d13f73dad44ef99f198018caafdc1b976c90dd3a..c388577d542a33b5e5b9a04dc4cd0385f0bef787 100644
--- a/dictionaries/privacyidea.translation.json
+++ b/dictionaries/privacyidea.translation.json
@@ -1,53 +1,87 @@
 {
 	"header": {
+		"cs": "Přihlášení systémem privacyIDEA",
 		"de": "Anmelden gegen privacyIDEA",
 		"nl": "Authenticeer tegen privacyIDEA"
 	},
 	"login_title": {
+		"cs": "Vložte své uživatelské jméno a heslo",
 		"de": "Bitte geben Sie Ihren Nutzernamen und Passwort ein",
 		"nl": "Vul uw gebruikersnaam en wachtwoord in."
 	},
 	"password_otp": {
+		"cs": "Heslo + jednorázový kód",
 		"de": "Password + OTP",
 		"nl": "Wachtwoord + OTP"
 	},
 	"password": {
+		"cs": "Heslo",
 		"de": "Password",
 		"nl": "Wachtwoord"
 	},
 	"otp": {
+		"cs": "Jednorázový kód",
 		"de": "Einmalpasswort",
 		"nl": "OTP"
 	},
 	"login_title_challenge": {
+		"cs": "Vložte jednorázový kód",
 		"de": "Bitte geben Sie Ihr Einmalpasswort ein",
 		"nl": "Vul je eenmalige wachtwoord in."
 	},
 	"otp_extra_text": {
+		"cs": "Vložte své heslo a jednorázový kód",
 		"de": "Bitte geben Sie Ihr Password und Ihr Einmalpasswort ein",
 		"nl": "Vul je wachtwoord en eenmalige wachtwoord (OTP) in."
 	},
 	"login_text_challenge": {
+		"cs": "Vložený PIN nebo heslo jsou správné, nyní použijte druhou metodu ověření.",
 		"de": "Sie haben die korrekte PIN, bzw. das korrekte Passwort eingegeben. Aber nun müssen Sie noch Ihren zweiten Faktor nutzen.",
 		"nl": "U heeft het de juiste PIN of wachtwoord ingegegeven. Geef nu ook uw tweede factor in."
 	},
 	"scanTokenQR": {
+		"cs": "Naskenujte tento QR kód aplikací pro TOTP (např. Google Authenticator nebo privacyIDEA Authenticator) a zobrazený kód vložte níže.",
 		"de": "Scannen Sie den QR-Code mit einer App, wie dem Google Authenticator oder privacyIDEA Authenticator und geben Sie den angezeigten Code unten ein.",
 		"nl": "Scan deze QR-code met een app zoals Google Authenticator of privacyIDEA Authenticator en geef de getoonde code in."
 	},
 	"chal_resp_message": {
+		"cs": "Potvrďte jedním z následujících tokenů: ",
 		"de": "Bitte bestätigen Sie mit einem der folgenden Token: ",
 		"nl": "Bevestig met één van deze tokens: "
 	},
 	"enroll_u2f": {
+		"cs": "Použijte svůj U2F autentikátor pro dokončení registrace.",
 		"de": "Bitte nutzen Sie Ihr U2F-Gerät, um das Ausrollen fertigzustellen.",
 		"nl": "Gebruik uw u2f-toestel om de aanmelding verder te zetten."
 	},
 	"u2fNotWorking": {
+		"cs": "U2F není k dispozici.",
 		"de": "U2F funktioniert momentan nicht.",
 		"nl": "U2F werkt momenteel niet."
 	},
+	"alternate_login_options": {
+		"cs": "Další možnosti přihlášení:"
+	},
+	"alert_webauthn_insecure_context": {
+		"cs": "Není možné použít autentizaci WebAuthn, protože neodpovídá bezpečnostní kontext."
+	},
+	"alert_webauthn_unavailable": {
+		"cs": "Načtení WebAuthn knihovny se nezdařilo. Zkuste to znovu nebo použijte jiný token."
+	},
+	"alert_webAuthnSignRequest_error": {
+		"cs": "Chyba při podepisování WebAuthnSignRequest:"
+	},
+	"alert_u2f_insecure_context": {
+		"cs": "Není možné použít autentizaci U2F, protože neodpovídá bezpečnostní kontext."
+	},
+	"alert_u2f_unavailable": {
+		"cs": "Načtení U2F knihovny se nezdařilo. Zkuste to znovu nebo použijte jiný token."
+	},
+	"alert_U2FSignRequest_error": {
+		"cs": "Chyba při podepisování U2FSignRequest:"
+	},
 	"tryAgain": {
+		"cs": "Zkusit znovu",
 		"de": "Nochmal versuchen",
 		"nl": "Probeer opnieuw"
 	}
diff --git a/docs/privacyidea.md b/docs/privacyidea.md
index 6e4e125ac11bb3a0089a9cd243120675017387e6..fda83bf5500dc5153b9f66837d2455c0f5afe06b 100644
--- a/docs/privacyidea.md
+++ b/docs/privacyidea.md
@@ -83,8 +83,8 @@ You need to add the authentication source 'privacyidea' to
     /**
      * Set custom hints for the OTP and password fields
      */
-    'otpFieldHint' => 'OTP'
-    'passFieldHint' => 'Password'
+    'otpFieldHint' => 'OTP',
+    'passFieldHint' => 'Password',
 
     /*
      * This is the translation from privacyIDEA attribute names to 
diff --git a/lib/Auth/Process/PrivacyideaAuthProc.php b/lib/Auth/Process/PrivacyideaAuthProc.php
index 7cd39d3d9c8ffc2835051ead4bd57f17573b2ba4..3973599a7df0686d1fdeec2e668e039eded0bcd9 100644
--- a/lib/Auth/Process/PrivacyideaAuthProc.php
+++ b/lib/Auth/Process/PrivacyideaAuthProc.php
@@ -1,5 +1,9 @@
 <?php
 
+use PrivacyIdea\PHPClient\PIBadRequestException;
+use PrivacyIdea\PHPClient\PILog;
+use PrivacyIdea\PHPClient\PrivacyIDEA;
+
 /**
  * This authentication processing filter allows you to add a second step
  * authentication against privacyIDEA
@@ -8,9 +12,6 @@
  * @author Jean-Pierre Höhmann <jean-pierre.hoehmann@netknights.it>
  * @author Lukas Matusiewicz <lukas.matusiewicz@netknights.it>
  */
-
-require_once((dirname(__FILE__, 3)) . '/sdk-php/src/SDK-Autoloader.php');
-
 class sspmod_privacyidea_Auth_Process_PrivacyideaAuthProc extends SimpleSAML_Auth_ProcessingFilter implements PILog
 {
     /* @var array This contains the authproc configuration which is set in metadata */
diff --git a/lib/Auth/Source/AuthSourceLoginHandler.php b/lib/Auth/Source/AuthSourceLoginHandler.php
index fda0c934b41643ba31ff43d1097f28a89d2b7f0a..300cc7c53290aa4c682c1de0ae73bc2d1b1faae6 100644
--- a/lib/Auth/Source/AuthSourceLoginHandler.php
+++ b/lib/Auth/Source/AuthSourceLoginHandler.php
@@ -1,5 +1,7 @@
 <?php
 
+use PrivacyIdea\PHPClient\PIResponse;
+
 /**
  * This is the helper class for PrivacyideaAuthSource.php
  */
diff --git a/lib/Auth/Source/PrivacyideaAuthSource.php b/lib/Auth/Source/PrivacyideaAuthSource.php
index e781b9565d868bd28f6d54305a569ab7f3f64198..861ce083c6657fe45e9195de8bbf000c4ebbe878 100644
--- a/lib/Auth/Source/PrivacyideaAuthSource.php
+++ b/lib/Auth/Source/PrivacyideaAuthSource.php
@@ -1,8 +1,9 @@
 <?php
 
-const DEFAULT_UID_KEYS = array("username", "surname", "email", "givenname", "mobile", "phone", "realm", "resolver");
+use PrivacyIdea\PHPClient\PILog;
+use PrivacyIdea\PHPClient\PrivacyIDEA;
 
-require_once((dirname(__FILE__, 3)) . '/sdk-php/src/SDK-Autoloader.php');
+const DEFAULT_UID_KEYS = array("username", "surname", "email", "givenname", "mobile", "phone", "realm", "resolver");
 
 /**
  * privacyidea authentication module.
diff --git a/lib/Auth/utils.php b/lib/Auth/utils.php
index 52518844a798b8bf32f27f3a937b4934b120bc64..1a4eea24b18535ebe8c3dce38e153203e857b092 100644
--- a/lib/Auth/utils.php
+++ b/lib/Auth/utils.php
@@ -1,6 +1,7 @@
 <?php
 
-require_once((dirname(__FILE__, 2)) . '/sdk-php/src/SDK-Autoloader.php');
+use PrivacyIdea\PHPClient\PIResponse;
+use PrivacyIdea\PHPClient\PrivacyIDEA;
 
 class sspmod_privacyidea_Auth_utils
 {
@@ -38,11 +39,13 @@ class sspmod_privacyidea_Auth_utils
             if ($state['privacyidea:privacyidea']['authenticationMethod'] === "authsource")
             {
                 $username = $state['privacyidea:privacyidea']['username'];
-            } else
+            }
+            else
             {
                 $username = $state["Attributes"][$serverConfig['uidKey']][0];
             }
-        } else
+        }
+        else
         {
             $username = $formParams['username'];
         }
@@ -67,25 +70,29 @@ class sspmod_privacyidea_Auth_utils
             if ($pi->pollTransaction($transactionID))
             {
                 $result = $pi->validateCheck($username, "", $transactionID);
-            } else
+            }
+            else
             {
                 SimpleSAML_Logger::debug("privacyIDEA: PUSH not confirmed yet");
             }
 
-        } elseif ($formParams['mode'] == "u2f")
+        }
+        elseif ($formParams['mode'] == "u2f")
         {
             $u2fSignResponse = $formParams['u2fSignResponse'];
 
             if (empty($u2fSignResponse))
             {
                 SimpleSAML_Logger::error("Incomplete data for U2F authentication: u2fSignResponse is missing!");
-            } else
+            }
+            else
             {
 //                SimpleSAML_Logger::info("U2F MODE.");
                 $result = $pi->validateCheckU2F($username, $transactionID, $u2fSignResponse);
             }
 
-        } elseif ($formParams['mode'] == "webauthn")
+        }
+        elseif ($formParams['mode'] == "webauthn")
         {
             $origin = $formParams['origin'];
             $webAuthnSignResponse = $formParams['webAuthnSignResponse'];
@@ -93,12 +100,14 @@ class sspmod_privacyidea_Auth_utils
             if (empty($origin) || empty($webAuthnSignResponse))
             {
                 SimpleSAML_Logger::error("Incomplete data for WebAuthn authentication: WebAuthnSignResponse or Origin is missing!");
-            } else
+            }
+            else
             {
 //                SimpleSAML_Logger::info("WEBAUTHN MODE.");
                 $result = $pi->validateCheckWebAuthn($username, $transactionID, $webAuthnSignResponse, $origin);
             }
-        } else
+        }
+        else
         {
 //            SimpleSAML_Logger::info("OTP MODE.");
             // Call validate/check endpoint adding parameters and eventually transaction ID
@@ -132,7 +141,8 @@ class sspmod_privacyidea_Auth_utils
             $state['privacyidea:privacyidea:ui']['message'] = $result->messages;
             $state['privacyidea:privacyidea:ui']['webAuthnSignRequest'] = $result->webAuthnSignRequest();
             $state['privacyidea:privacyidea:ui']['u2fSignRequest'] = $result->u2fSignRequest();
-        } elseif ($result->value)
+        }
+        elseif ($result->value)
         {
             SimpleSAML_Logger::debug("privacyIDEA: User authenticated successfully!");
 
@@ -141,12 +151,14 @@ class sspmod_privacyidea_Auth_utils
                 SimpleSAML_Auth_State::saveState($state, 'privacyidea:privacyidea');
                 SimpleSAML_Auth_ProcessingChain::resumeProcessing($state);
             }
-        } elseif (!empty($result->errorCode))
+        }
+        elseif (!empty($result->errorCode))
         {
             SimpleSAML_Logger::error("PrivacyIDEA server: Error code: " . $result->errorCode . ", Error message: " . $result->errorMessage);
             $state['privacyidea:privacyidea']['errorCode'] = $result->errorCode;
             $state['privacyidea:privacyidea']['errorMessage'] = $result->errorMessage;
-        } else
+        }
+        else
         {
             SimpleSAML_Logger::error("privacyIDEA: Wrong OTP.");
             $state['privacyidea:privacyidea']['errorMessage'] = "You have entered incorrect OTP. Please try again or use another token.";
@@ -206,11 +218,13 @@ class sspmod_privacyidea_Auth_utils
             if ($config['enabledKey'] === false || $state['enabledKey'] === false)
             {
                 return true;
-            } else
+            }
+            else
             {
                 return false;
             }
-        } else
+        }
+        else
         {
             return false;
         }
diff --git a/lib/sdk-php b/lib/sdk-php
deleted file mode 160000
index f3f1505a725bd85547ff50d467602bbbeadaf871..0000000000000000000000000000000000000000
--- a/lib/sdk-php
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit f3f1505a725bd85547ff50d467602bbbeadaf871
diff --git a/templates/loginform.php b/templates/loginform.php
index 5ca87381d9ad200b6f48d5811ea901c83bbf954a..43567b1e34ebf7b96df405af5481467940851ae9 100644
--- a/templates/loginform.php
+++ b/templates/loginform.php
@@ -156,15 +156,20 @@ if ($this->data['errorCode'] !== NULL)
 
                                 <strong id="message"><?php echo $this->data['message'] ?></strong>
 
+                                <br><br>
                                 <label for="otp" class="sr-only">
                                     <?php echo $this->t('{privacyidea:privacyidea:otp}'); ?>
                                 </label>
+
+                                
+
                                 <input id="otp" name="otp" tabindex="1" type="password" value="" class="text"
                                        placeholder="<?php echo htmlspecialchars($otpHint, ENT_QUOTES) ?>"/>
-                                <br>
+                                <br><br>
                                 <input id="submitButton" tabindex="1" class="rc-button rc-button-submit" type="submit"
                                        name="Submit"
                                        value="<?php echo htmlspecialchars($this->t('{login:login_button}'), ENT_QUOTES) ?>"/>
+                                <br><br>
 
                                 <!-- Hidden input which store the info about changes for future use in backend-->
                                 <input id="mode" type="hidden" name="mode" value="<?php echo $this->data['mode'] ?>"/>
@@ -245,13 +250,17 @@ if ($this->data['errorCode'] !== NULL)
                 </div> <!-- form-panel -->
 
                 <div id="AlternateLoginOptions" class="groupMargin">
-                    <h3><?php echo $this->t('{privacyidea:privacyidea:alternate_login_options}'); ?></h3>
+
+                    <h3><label><?php echo $this->t('{privacyidea:privacyidea:alternate_login_options}'); ?></label></h3>
+                    <br>
+
                     <!-- Alternate Login Options-->
                     <input id="useWebAuthnButton" name="useWebAuthnButton" type="button" value="WebAuthn"/>
                     <input id="usePushButton" name="usePushButton" type="button" value="Push"/>
                     <input id="useOTPButton" name="useOTPButton" type="button" value="OTP"/>
                     <input id="useU2FButton" name="useU2FButton" type="button" value="U2F"/>
                 </div>
+                <br>
             </form>
 
             <?php
@@ -277,7 +286,7 @@ if (!empty($this->data['links']))
 }
 ?>
 
-    <script src="<?php echo htmlspecialchars(SimpleSAML_Module::getModuleUrl('privacyidea/js/webauthn.js'), ENT_QUOTES) ?>">
+    <script src="<?php echo htmlspecialchars(SimpleSAML_Module::getModuleUrl('privacyidea/js/webauthn-client/pi-webauthn.js'), ENT_QUOTES) ?>">
     </script>
 
     <script src="<?php echo htmlspecialchars(SimpleSAML_Module::getModuleUrl('privacyidea/js/u2f-api.js'), ENT_QUOTES) ?>">
@@ -307,4 +316,4 @@ if (!empty($this->data['links']))
 
 <?php
 $this->includeAtTemplateBase('includes/footer.php');
-?>
+?>
\ No newline at end of file
diff --git a/www/js/webauthn-client b/www/js/webauthn-client
new file mode 160000
index 0000000000000000000000000000000000000000..504b4a50537ba18a475e9c2c9efb11698a00ad8a
--- /dev/null
+++ b/www/js/webauthn-client
@@ -0,0 +1 @@
+Subproject commit 504b4a50537ba18a475e9c2c9efb11698a00ad8a