diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt
index 37b9ac379e285f9814f675d72b8525f40c92cd78..3c530ee06fd79a46e5059179a97a72f86595fd36 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt
@@ -31,6 +31,8 @@ const val MXCRYPTO_ALGORITHM_MEGOLM = "m.megolm.v1.aes-sha2"
  */
 const val MXCRYPTO_ALGORITHM_MEGOLM_BACKUP = "m.megolm_backup.v1.curve25519-aes-sha2"
 
+const val BCRYPT_ALGORITHM_BACKUP = "m.bcrypt"
+
 /**
  * Secured Shared Storage algorithm constant.
  */
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt
index 0d40490c3e6858a290d21c0937d828cb687ce1b1..8cdd69f7ff92cfd8974cafbf8a8e1f4ea30a12b3 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt
@@ -118,6 +118,9 @@ interface KeysBackupService {
                                  progressListener: ProgressListener?,
                                  callback: MatrixCallback<MegolmBackupCreationInfo>)
 
+
+    fun prepareBcryptKeysBackupVersion(userName:String, password: String,
+                                 callback: MatrixCallback<MegolmBackupCreationInfo>)
     /**
      * Delete a keys backup version. It will delete all backed up keys on the server, and the backup itself.
      * If we are backing up to this version. Backup will be stopped.
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/BCryptManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/BCryptManager.kt
new file mode 100644
index 0000000000000000000000000000000000000000..378cc2457917c3c3d63dd3f798dd29e85fb24db0
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/BCryptManager.kt
@@ -0,0 +1,27 @@
+package org.matrix.android.sdk.internal.crypto.keysbackup
+
+import at.favre.lib.crypto.bcrypt.BCrypt
+import java.security.MessageDigest
+
+internal object BCryptManager {
+
+    private const val iterations = 14
+    private const val saltLength = 16
+
+
+    fun generateBcryptPrivateKeyWithPassword(
+        userName: String,
+        password: String
+    ): GeneratePrivateKeyResult {
+        val salt = userName.sha256().substring(0, saltLength).toByteArray()
+        val privateKey = BCrypt.withDefaults().hash(iterations, salt, password.toByteArray())
+        return GeneratePrivateKeyResult(privateKey, salt.toString(), iterations)
+    }
+
+
+    private fun String.sha256(): String = MessageDigest
+        .getInstance("SHA-256")
+        .digest(this.toByteArray())
+        .fold("") { str, it -> str + "%02x".format(it) }
+
+}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt
index 5ea4695da29b4bcf73a372cc338c6b88909db9b2..4dabc4d7352551a8e59dd55dfb54d5e62021fcd0 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt
@@ -28,6 +28,7 @@ import kotlinx.coroutines.withContext
 import org.matrix.android.sdk.api.MatrixCallback
 import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
 import org.matrix.android.sdk.api.auth.data.Credentials
+import org.matrix.android.sdk.api.crypto.BCRYPT_ALGORITHM_BACKUP
 import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
 import org.matrix.android.sdk.api.failure.Failure
 import org.matrix.android.sdk.api.failure.MatrixError
@@ -233,6 +234,57 @@ internal class DefaultKeysBackupService @Inject constructor(
         }
     }
 
+    override fun prepareBcryptKeysBackupVersion(userName:String, password: String,
+                                          callback: MatrixCallback<MegolmBackupCreationInfo>) {
+        cryptoCoroutineScope.launch(coroutineDispatchers.io) {
+            try {
+                val generatePrivateKeyResult = BCryptManager.generateBcryptPrivateKeyWithPassword(userName,password)
+                val signalableBackupAuthData = SignalableMegolmBackupAuthData(
+                        publicKey = generatePrivateKeyResult.privateKey.toString(),
+                        privateKeySalt = generatePrivateKeyResult.salt,
+                        privateKeyIterations = generatePrivateKeyResult.iterations
+                    )
+
+                val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableBackupAuthData.signalableJSONDictionary())
+
+                val signatures = mutableMapOf<String, MutableMap<String, String>>()
+
+                val deviceSignature = objectSigner.signObject(canonicalJson)
+                deviceSignature.forEach { (userID, content) ->
+                    signatures[userID] = content.toMutableMap()
+                }
+
+                // If we have cross signing add signature, will throw if cross signing not properly configured
+                try {
+                    val crossSign = crossSigningOlm.signObject(CrossSigningOlm.KeyType.MASTER, canonicalJson)
+                    signatures[credentials.userId]?.putAll(crossSign)
+                } catch (failure: Throwable) {
+                    // ignore and log
+                    Timber.w(failure, "prepareKeysBackupVersion: failed to sign with cross signing keys")
+                }
+
+                val signedBackupAuthData = MegolmBackupAuthData(
+                    publicKey = signalableBackupAuthData.publicKey,
+                    privateKeySalt = signalableBackupAuthData.privateKeySalt,
+                    privateKeyIterations = signalableBackupAuthData.privateKeyIterations,
+                    signatures = signatures
+                )
+                val creationInfo = MegolmBackupCreationInfo(
+                    algorithm = BCRYPT_ALGORITHM_BACKUP,
+                    authData = signedBackupAuthData,
+                    recoveryKey = generatePrivateKeyResult.privateKey.toString()
+                )
+                uiHandler.post {
+                    callback.onSuccess(creationInfo)
+                }
+            } catch (failure: Throwable) {
+                uiHandler.post {
+                    callback.onFailure(failure)
+                }
+            }
+        }
+    }
+
     override fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo,
                                          callback: MatrixCallback<KeysVersion>) {
         @Suppress("UNCHECKED_CAST")