diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt
index 6edc4ce1bfc13a6d94b5924234ad29e1a46a0e0c..8df09af8ffafd6d9552386dc904678db695ca0f8 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt
@@ -19,4 +19,8 @@ object SubmissionConstants {
     val REGISTRATION_TOKEN_URL = "$VERSIONED_VERIFICATION_CDN_URL/$REGISTRATION_TOKEN"
     val TEST_RESULT_URL = "$VERSIONED_VERIFICATION_CDN_URL/$TEST_RESULT"
     val TAN_REQUEST_URL = "$VERSIONED_VERIFICATION_CDN_URL/$TAN"
+
+    const val MAX_QR_CODE_LENGTH = 150
+    const val MAX_GUID_LENGTH = 80
+    const val GUID_SEPARATOR = '?'
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt
index d8f6e09debf07b86cbd8394b677744797ae8ab38..a521fd889a30a356a5b905d3a111868d73d3d201 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt
@@ -70,17 +70,20 @@ object SubmissionService {
         )
     }
 
-    /**
-     * extracts the GUID from [scanResult]. Returns null if it does not match the required pattern
-     */
-    fun extractGUID(scanResult: String): String? {
-        val potentialGUID = scanResult.substringAfterLast("?", "")
-        return if (potentialGUID.isEmpty())
-            null
-        else
-            potentialGUID
+    fun containsValidGUID(scanResult: String): Boolean {
+        if (scanResult.length > SubmissionConstants.MAX_QR_CODE_LENGTH ||
+            scanResult.count { it == SubmissionConstants.GUID_SEPARATOR } != 1
+        )
+            return false
+
+        val potentialGUID = extractGUID(scanResult)
+
+        return !(potentialGUID.isEmpty() || potentialGUID.length > SubmissionConstants.MAX_GUID_LENGTH)
     }
 
+    fun extractGUID(scanResult: String): String =
+        scanResult.substringAfterLast(SubmissionConstants.GUID_SEPARATOR, "")
+
     fun storeTestGUID(guid: String) = LocalData.testGUID(guid)
 
     fun deleteTestGUID() {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt
index 22b63d2d9bb3d827f9d70225c4d0677354dbb239..c18d49a015360e7b4747526b6a323afe69dd88cc 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt
@@ -10,21 +10,13 @@ class SubmissionTanViewModel : ViewModel() {
 
     companion object {
         private val TAG: String? = SubmissionTanViewModel::class.simpleName
-
-        private const val TAN_LENGTH = 7
-        private val EXCLUDED_TAN_CHARS = listOf('0', 'O', 'I', '1')
-        private val VALID_TAN_CHARS =
-            ('a'..'z')
-                .plus('A'..'Z')
-                .plus('0'..'9')
-                .minus(EXCLUDED_TAN_CHARS)
     }
 
     val tan = MutableLiveData<String?>(null)
 
     val isValidTanFormat =
         Transformations.map(tan) {
-            it != null && it.length == TAN_LENGTH && it.all { c -> VALID_TAN_CHARS.contains(c) }
+            it != null && it.length == TanConstants.MAX_LENGTH
         }
 
     fun storeTeletan() {
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b6be13be81def6ec21f396f0b89f278cdeb9fd6a
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt
@@ -0,0 +1,6 @@
+package de.rki.coronawarnapp.ui.submission
+
+object TanConstants {
+    const val MAX_LENGTH = 7
+    val ALPHA_NUMERIC_CHARS = ('a'..'z').plus('A'..'Z').plus('0'..'9')
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt
index d1a251846533df73987b224954ebc59757d4869c..70cc48b6833364f5303cc7d9d7549f2962e58e7f 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt
@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.ui.submission
 
 import android.content.Context
 import android.os.Handler
+import android.text.InputFilter
 import android.util.AttributeSet
 import android.view.inputmethod.InputMethodManager
 import android.widget.FrameLayout
@@ -22,6 +23,15 @@ class TanInput(context: Context, attrs: AttributeSet) : FrameLayout(context, att
         private const val KEYBOARD_TRIGGER_DELAY = 100L
     }
 
+    private val whitespaceFilter =
+        InputFilter { source, _, _, _, _, _ -> source.filter { !it.isWhitespace() } }
+    private val alphaNumericFilter = InputFilter { source, _, _, _, _, _ ->
+        source.filter {
+            TanConstants.ALPHA_NUMERIC_CHARS.contains(it)
+        }
+    }
+    private val lengthFilter = InputFilter.LengthFilter(TanConstants.MAX_LENGTH)
+
     var listener: ((String?) -> Unit)? = null
 
     private var tan: String? = null
@@ -29,6 +39,8 @@ class TanInput(context: Context, attrs: AttributeSet) : FrameLayout(context, att
     init {
         inflate(context, R.layout.view_tan_input, this)
 
+        tan_input_edittext.filters = arrayOf(whitespaceFilter, alphaNumericFilter, lengthFilter)
+
         // register listener
         tan_input_edittext.doOnTextChanged { text, _, _, _ -> updateTan(text) }
         setOnClickListener { showKeyboard() }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt
index e11b0c577f2ced767c9ea732ac430550e8225f6e..de2bb9f5066be22b2fe90cd43af268fde93c8df7 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt
@@ -43,8 +43,8 @@ class SubmissionViewModel : ViewModel() {
         executeRequestWithState(SubmissionRepository::refreshUIState, _uiStateState)
 
     fun validateAndStoreTestGUID(scanResult: String) {
-        val guid = SubmissionService.extractGUID(scanResult)
-        if (guid != null) {
+        if (SubmissionService.containsValidGUID(scanResult)) {
+            val guid = SubmissionService.extractGUID(scanResult)
             SubmissionService.storeTestGUID(guid)
             _scanStatus.value = ScanStatus.SUCCESS
         } else {
diff --git a/Corona-Warn-App/src/main/res/values/integers.xml b/Corona-Warn-App/src/main/res/values/integers.xml
deleted file mode 100644
index 92946c0300b8e1b29406a31cb354488e3ee17a5a..0000000000000000000000000000000000000000
--- a/Corona-Warn-App/src/main/res/values/integers.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<resources>
-    <integer name="submission_tan_length">7</integer>
-</resources>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml
index 0c76b91ea02df883d2a761e17c29a407d4701258..a432847122a6688184292273818607f3a2764f71 100644
--- a/Corona-Warn-App/src/main/res/values/strings.xml
+++ b/Corona-Warn-App/src/main/res/values/strings.xml
@@ -575,7 +575,7 @@
     <!-- XHED: Page title for TAN submission pge -->
     <string name="submission_tan_title">TAN Eingabe</string>
     <!-- YTXT: Body text for the tan submission page -->
-    <string name="submission_tan_body">Die TAN ist 7-stellig und Groß- und Kleinschreibung muss nicht beachtet werden.</string>
+    <string name="submission_tan_body">Die TAN ist 7-stellig und Groß- und Kleinschreibung muss beachtet werden.\n\nGeben Sie bitte die Ihnen mitgeteilte TAN ein:</string>
     <!-- XBUT: Submit TAN button -->
     <string name="submission_tan_button_text">Weiter</string>
 
diff --git a/Corona-Warn-App/src/main/res/values/styles.xml b/Corona-Warn-App/src/main/res/values/styles.xml
index d520458a6634dfe737b3583cb0f49c77ddb55902..285842c941ed470778d627f6579b51f3755c3ced 100644
--- a/Corona-Warn-App/src/main/res/values/styles.xml
+++ b/Corona-Warn-App/src/main/res/values/styles.xml
@@ -238,7 +238,6 @@
         <item name="android:alpha">0</item>
         <item name="android:background">@null</item>
         <item name="android:inputType">textPassword</item>
-        <item name="android:maxLength">@integer/submission_tan_length</item>
         <item name="android:singleLine">true</item>
     </style>
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt
index ed2a111ce2ac1afc9406a23de54c672464b10a62..2d2b758bba3dcca74c0cdc311bd1bfd6b27c0a5b 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt
@@ -1,25 +1,33 @@
 package de.rki.coronawarnapp.service.submission
 
 import org.hamcrest.CoreMatchers.equalTo
-import org.hamcrest.CoreMatchers.nullValue
 import org.hamcrest.MatcherAssert.assertThat
 import org.junit.Test
 
 class SubmissionServiceTest {
 
     @Test
-    fun extractGUID() {
+    fun containsValidGUID() {
         // valid
         val guid = "123456-12345678-1234-4DA7-B166-B86D85475064"
         assertThat(
-            SubmissionService.extractGUID("https://bs-sd.de/covid-19/?$guid"),
-            equalTo(guid)
+            SubmissionService.containsValidGUID("https://bs-sd.de/covid-19/?$guid"),
+            equalTo(true)
         )
 
         // invalid
         assertThat(
-            SubmissionService.extractGUID("https://no-guid-here"),
-            nullValue()
+            SubmissionService.containsValidGUID("https://no-guid-here"),
+            equalTo(false)
+        )
+    }
+    
+    @Test
+    fun extractGUID() {
+        val guid = "123456-12345678-1234-4DA7-B166-B86D85475064"
+        assertThat(
+            SubmissionService.extractGUID("https://bs-sd.de/covid-19/?$guid"),
+            equalTo(guid)
         )
     }
 }