diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle
index b6d471b6ce16d2a6fb54c2b96d5446cf281d028d..146ca2e4b8175e844d913450a30ae3d94519a1b4 100644
--- a/Corona-Warn-App/build.gradle
+++ b/Corona-Warn-App/build.gradle
@@ -40,8 +40,8 @@ android {
         applicationId 'de.rki.coronawarnapp'
         minSdkVersion 23
         targetSdkVersion 29
-        versionCode 47
-        versionName "1.5.0"
+        versionCode 48
+        versionName "1.5.1"
 
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt
index 99a10696c70e8c606c401de795f3b686418ce689..dc90f38b4cc4d9daacf006ed8cc8296f64f29f54 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/TimeVariables.kt
@@ -33,8 +33,10 @@ object TimeVariables {
     /**
      * The maximal runtime of a transaction
      * In milliseconds
+     * Stay below 10min with this timeout!
+     * We only 10min background execution time via WorkManager.
      */
-    private const val TRANSACTION_TIMEOUT = 180000L
+    private const val TRANSACTION_TIMEOUT = 8 * 60 * 1000L
 
     /**
      * Getter function for [TRANSACTION_TIMEOUT]
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt
index db82cafc9c5b7084710bd046145f62b75eb560dd..d08f8aa4f3081d61263d85dc552ac002bb0ec473 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt
@@ -66,7 +66,7 @@ class MainFragment : Fragment(R.layout.fragment_main) {
         if (errorResetTool.isResetNoticeToBeShown) {
             RecoveryByResetDialogFactory(this).showDialog(
                 detailsLink = R.string.errors_generic_text_catastrophic_error_encryption_failure,
-                onDismiss = {
+                onPositive = {
                     errorResetTool.isResetNoticeToBeShown = false
                 }
             )
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/errors/RecoveryByResetDialogFactory.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/errors/RecoveryByResetDialogFactory.kt
index da52bb3e6e5ceb049fee5dc6cdd0eec93fed6c8b..c8804aaad1d50729150f7a593bea8d8c80356665 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/errors/RecoveryByResetDialogFactory.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/errors/RecoveryByResetDialogFactory.kt
@@ -14,17 +14,20 @@ class RecoveryByResetDialogFactory(private val fragment: Fragment) {
 
     fun showDialog(
         @StringRes detailsLink: Int,
-        onDismiss: () -> Unit
+        onPositive: () -> Unit
     ) {
-        AlertDialog.Builder(context)
+        val dialog = AlertDialog.Builder(context)
             .setTitle(R.string.errors_generic_headline)
             .setMessage(R.string.errors_generic_text_catastrophic_error_recovery_via_reset)
             .setCancelable(false)
-            .setOnDismissListener { onDismiss() }
-            .setNeutralButton(R.string.errors_generic_button_negative) { _, _ ->
-                ExternalActionHelper.openUrl(fragment, context.getString(detailsLink))
+            .setNeutralButton(R.string.errors_generic_button_negative, null)
+            .setPositiveButton(R.string.errors_generic_button_positive) { _, _ ->
+                onPositive()
             }
-            .setPositiveButton(R.string.errors_generic_button_positive) { _, _ -> }
-            .show()
+            .create()
+        dialog.show()
+        dialog.getButton(AlertDialog.BUTTON_NEUTRAL)?.setOnClickListener {
+            ExternalActionHelper.openUrl(fragment, context.getString(detailsLink))
+        }
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptionErrorResetTool.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptionErrorResetTool.kt
index de29ea8f6815868e084d7e29fc6da8f74729620f..af80cfb1f152fc30ec5ffde942f0acc5b4a53aab 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptionErrorResetTool.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/security/EncryptionErrorResetTool.kt
@@ -71,8 +71,8 @@ class EncryptionErrorResetTool @Inject constructor(
         }
         isResetWindowConsumed = true
 
-        val keyException = error.causes().singleOrNull { it is GeneralSecurityException }
-        if (keyException == null) {
+        val keyException = error.causes().lastOrNull()
+        if (keyException == null || keyException !is GeneralSecurityException) {
             Timber.v("Error has no GeneralSecurityException as cause -> no reset.")
             return false
         }
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/TimeVariablesTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/TimeVariablesTest.kt
index 4055ddf1fb9875c2d340e257cfb13c91c5843a4b..4b46519654961026b9e13fea1bfc934cb4d899e2 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/TimeVariablesTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/TimeVariablesTest.kt
@@ -16,7 +16,7 @@ class TimeVariablesTest {
 
     @Test
     fun getTransactionTimeout() {
-        Assert.assertEquals(TimeVariables.getTransactionTimeout(), 180000L)
+        Assert.assertEquals(TimeVariables.getTransactionTimeout(), 480000L)
     }
 
     @Test
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/security/EncryptionResetToolTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/security/EncryptionResetToolTest.kt
index 7daab4ac94863c9880ca2387accf09aec4a4710b..d420042e18ea6ef9d24234156ff96c8244f3dbe2 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/security/EncryptionResetToolTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/security/EncryptionResetToolTest.kt
@@ -14,7 +14,9 @@ import org.junit.jupiter.api.Test
 import testhelpers.BaseIOTest
 import testhelpers.preferences.MockSharedPreferences
 import java.io.File
+import java.io.IOException
 import java.security.GeneralSecurityException
+import java.security.KeyException
 import java.security.KeyStoreException
 
 class EncryptionResetToolTest : BaseIOTest() {
@@ -169,6 +171,86 @@ class EncryptionResetToolTest : BaseIOTest() {
         }
     }
 
+    @Test
+    fun `nested exception may have the same base exception type, ie GeneralSecurityException`() {
+        // https://github.com/corona-warn-app/cwa-app-android/issues/642#issuecomment-712188157
+        createMockFiles()
+
+        createInstance().tryResetIfNecessary(
+            KeyException( // subclass of GeneralSecurityException
+                "Permantly failed to instantiate encrypted preferences",
+                SecurityException(
+                    "Could not decrypt key. decryption failed",
+                    GeneralSecurityException("decryption failed")
+                )
+            )
+        ) shouldBe true
+
+        encryptedPrefsFile.exists() shouldBe false
+        encryptedDatabaseFile.exists() shouldBe false
+
+        mockPreferences.dataMapPeek.apply {
+            this["ea1851.reset.performedAt"] shouldNotBe null
+            this["ea1851.reset.windowconsumed"] shouldBe true
+            this["ea1851.reset.shownotice"] shouldBe true
+        }
+    }
+
+    @Test
+    fun `exception check does not care about the first exception type`() {
+        createMockFiles()
+
+        createInstance().tryResetIfNecessary(
+            CwaSecurityException(
+                KeyException( // subclass of GeneralSecurityException
+                    "Permantly failed to instantiate encrypted preferences",
+                    SecurityException(
+                        "Could not decrypt key. decryption failed",
+                        GeneralSecurityException("decryption failed")
+                    )
+                )
+            )
+        ) shouldBe true
+
+        encryptedPrefsFile.exists() shouldBe false
+        encryptedDatabaseFile.exists() shouldBe false
+
+        mockPreferences.dataMapPeek.apply {
+            this["ea1851.reset.performedAt"] shouldNotBe null
+            this["ea1851.reset.windowconsumed"] shouldBe true
+            this["ea1851.reset.shownotice"] shouldBe true
+        }
+    }
+
+    @Test
+    fun `exception check DOES care about the most nested exception`() {
+        createMockFiles()
+
+        createInstance().tryResetIfNecessary(
+            CwaSecurityException(
+                KeyException( // subclass of GeneralSecurityException
+                    "Permantly failed to instantiate encrypted preferences",
+                    SecurityException(
+                        "Could not decrypt key. decryption failed",
+                        GeneralSecurityException(
+                            "decryption failed",
+                            IOException("I am unexpeted")
+                        )
+                    )
+                )
+            )
+        ) shouldBe false
+
+        encryptedPrefsFile.exists() shouldBe true
+        encryptedDatabaseFile.exists() shouldBe true
+
+        mockPreferences.dataMapPeek.apply {
+            this["ea1851.reset.performedAt"] shouldBe null
+            this["ea1851.reset.windowconsumed"] shouldBe true
+            this["ea1851.reset.shownotice"] shouldBe null
+        }
+    }
+
     @Test
     fun `we want only a specific type of GeneralSecurityException`() {
         createMockFiles()