Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to restore encrypted backup - Bad MAC #8355

Closed
4 tasks done
mike-edel opened this issue Nov 10, 2018 · 122 comments
Closed
4 tasks done

Unable to restore encrypted backup - Bad MAC #8355

mike-edel opened this issue Nov 10, 2018 · 122 comments
Labels

Comments

@mike-edel
Copy link

mike-edel commented Nov 10, 2018


Bug description

Unable to restore signal backup on new phone.
Similar to #7637 but I don't have xposed installed.
Signal stable closing without error after reading 11401 messages.
Signal beta giving error message about incorrect passphrase after reading 11401 messages.
I am certain the passphrase and the backup are correct as they are working fine using https://github.com/xeals/signal-back

Steps to reproduce

  • copy signal backup to new phone
  • open signal
  • enter passphrase
  • wait for messages to import

Actual result:

  • Signal just closing (stable)
  • Error message stating the passphrase is incorrect (beta).

Expected result: Backup is successfully restored.

Screenshots

beta error (in German due to phone language)
_20181110_121218

Device info

Device: Nokia 7 Plus Dual-Sim
Android version: 9
Kernel version: 4.4.146-perf+
Signal version:
Beta: 4.30.2
also tested on stable: 4.29.7

Link to debug log

Working on grabbing a logcat log but struggling with it. Will add through edit.
Logcat for version 4.29.7:

--------- beginning of crash
11-08 22:32:10.330  4472  6987 E AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
11-08 22:32:10.330  4472  6987 E AndroidRuntime: Process: org.thoughtcrime.securesms, PID: 4472
11-08 22:32:10.330  4472  6987 E AndroidRuntime: java.lang.RuntimeException: An error occurred while executing doInBackground()
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at android.os.AsyncTask$3.done(AsyncTask.java:354)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at java.util.concurrent.FutureTask.run(FutureTask.java:271)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:764)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: Caused by: java.lang.NegativeArraySizeException: -1884239691
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readFrame(FullBackupImporter.java:310)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readFrame(FullBackupImporter.java:252)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at org.thoughtcrime.securesms.backup.FullBackupImporter.importFile(FullBackupImporter.java:81)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:394)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:386)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at android.os.AsyncTask$2.call(AsyncTask.java:333)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
11-08 22:32:10.330  4472  6987 E AndroidRuntime: 	... 4 more

logcat for version 4.30.2:

11-10 13:15:20.687 27588 31822 W RegistrationActivity: null
11-10 13:15:20.687 27588 31822 W RegistrationActivity: java.io.IOException: Bad MAC
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readAttachmentTo(FullBackupImporter.java:298)
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at org.thoughtcrime.securesms.backup.FullBackupImporter.processAttachment(FullBackupImporter.java:140)
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at org.thoughtcrime.securesms.backup.FullBackupImporter.importFile(FullBackupImporter.java:87)
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:396)
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:388)
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at android.os.AsyncTask$2.call(AsyncTask.java:333)
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
11-10 13:15:20.687 27588 31822 W RegistrationActivity: 	at java.lang.Thread.run(Thread.java:764)
@dorakas
Copy link

dorakas commented Nov 20, 2018

So basically now coming from #8347 it seems i evolved to this one here. With the latest 4.30.7 on Nexus 6P it finishes after 2 hours my backup and my Pixel3 - 4.30.7 Signal tells me that my password is wrong. Same problem as above. Tried https://github.com/xeals/signal-back and worked with the same file and same password. Since i reached from crashing Signal on Pixel with restoring backup, i think the next Level is succesfully restoring a backup. :D

Pixel 3 - https://debuglogs.org/8afd5e209b77295d13b983b38b06c71fd0cbe32f04e4521f5f5aad5b2f87a4d3

Nexus 6P - https://debuglogs.org/703329cfc7d727fab8c4cc4087552e37cde3d45abd8f88428ef92ea91d3ee583

@sarevok-anchev
Copy link

Same here. Running LineageOS 16.

Interestingly, with the wrong password specified, Signal will immediately claim that the password is incorrect.

With the right password, it reads around 2000 messages and then suddenly has a change of mind and claims that the password is incorrect after all. Seems legit.

***I tried both 4.26.2 and 4.30.8.

4.26.2:

W RegistrationActivity:  at com.google.protobuf.CodedInputStream.pushLimit(CodedInputStream.java:651)
W RegistrationActivity:  at com.google.protobuf.CodedInputStream.readMessage(CodedInputStream.java:307)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.BackupProtos$BackupFrame.<init>(BackupProtos.java:4637)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.BackupProtos$BackupFrame.<init>(BackupProtos.java:4514)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.BackupProtos$BackupFrame$1.parsePartialFrom(BackupProtos.java:4675)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.BackupProtos$BackupFrame$1.parsePartialFrom(BackupProtos.java:4670)
W RegistrationActivity:  at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:141)
W RegistrationActivity:  at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:176)
W RegistrationActivity:  at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:188)
W RegistrationActivity:  at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:193)
W RegistrationActivity:  at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:49)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.BackupProtos$BackupFrame.parseFrom(BackupProtos.java:4937)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readFrame(FullBackupImporter.java:328)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readFrame(FullBackupImporter.java:252)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.FullBackupImporter.importFile(FullBackupImporter.java:81)
W RegistrationActivity:  at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:394)
W RegistrationActivity:  at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:386)
W RegistrationActivity:  at android.os.AsyncTask$2.call(AsyncTask.java:333)
W RegistrationActivity:  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
RegistrationActivity:  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
W RegistrationActivity:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W RegistrationActivity:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W RegistrationActivity:  at java.lang.Thread.run(Thread.java:764)

4.30.8:

W RegistrationActivity: null
 W RegistrationActivity: java.io.IOException: Bad MAC
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readFrame(FullBackupImporter.java:320)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readFrame(FullBackupImporter.java:252)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.FullBackupImporter.importFile(FullBackupImporter.java:81)
W RegistrationActivity:  at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:396)
W RegistrationActivity:  at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:388)
W RegistrationActivity:  at android.os.AsyncTask$2.call(AsyncTask.java:333)
W RegistrationActivity:  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W RegistrationActivity:  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
W RegistrationActivity:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W RegistrationActivity:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
RegistrationActivity:  at java.lang.Thread.run(Thread.java:764)

I have restored backups (not this specific file) in the past a couple of times with no issues. The only change is that when it worked it was with Android 7.x and now I'm on 9.x. Probably not relevant though.

Clearly, the backup was a) generated by signal itself and b) in good health since signal-back can properly decode it.

@dorakas
Copy link

dorakas commented Nov 23, 2018

9.x. Probably not relevant though.

But maybe this is the relevant part

@mike-edel
Copy link
Author

9.x. Probably not relevant though.

But maybe this is the relevant part

Indeed, seems to be a common thing...

@chainsawbeaver
Copy link

chainsawbeaver commented Nov 26, 2018

Not valid anymore! I had different Signal versions! Sorry for any confusion.

Same problem here with Android 8.1

Signal crashes after it reads the 4000+ Message. So perhaps it is not the same Issue? I cropped my conversations and deleted all media inside signal conversations, but that did not help. I also can open the backup with signal-back (only "umlaute" (ÄÜÖ) are displayed wrong).

@sarevok-anchev
Copy link

^^ There goes the 9.x theory.

@sarevok-anchev
Copy link

By the way, I did not see this issue restoring on LineageOS 15.1 (Android 8.1). Different backup file though (another account).

@sarevok-anchev
Copy link

Actually, it may be possible that the backup was not restored. This was a few weeks ago and my memory is flimsy. Sorry about the spam, not possible to edit comments anymore it seems..

@chainsawbeaver
Copy link

I had different Signal versions! Sorry for any confusion.
So perhaps still a 9/pie issue?

@spospartan104
Copy link

spospartan104 commented Dec 10, 2018

Also experiencing this migrating from Nexus 6 Android 7.1.1 to Moto X4 Android 8.1.0

Decrypts messages (as it is counting the correct number to be restored) Then when it fails it throws Incorrect password. Log cat shows the Bad Mac error as well.

Has anyone found a work around?

Stock Roms (Nexus 6, Moto X4 Android One edition)
Signal 4.30.8 on both as well

@sarevok-anchev
Copy link

Had the chance to day to try on Android 8.1 AOSP.

I zygote  : Deoptimizing void net.sqlcipher.database.SQLiteClosable.releaseReference() due to JIT inline cache
W RegistrationActivity: null
W RegistrationActivity: java.io.IOException: Bad MAC
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readFrame(FullBackupImporter.java:320)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readFrame(FullBackupImporter.java:252)
W RegistrationActivity:  at org.thoughtcrime.securesms.backup.FullBackupImporter.importFile(FullBackupImporter.java:81)
W RegistrationActivity:  at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:396)
W RegistrationActivity:  at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:388)
W RegistrationActivity:  at android.os.AsyncTask$2.call(AsyncTask.java:333)
W RegistrationActivity:  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W RegistrationActivity:  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
W RegistrationActivity:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
W RegistrationActivity:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
W RegistrationActivity:  at java.lang.Thread.run(Thread.java:764)

In one swift strike, it seems that we can rule out the culprit being Android 9 or LineageOS.

Perhaps @moxie0 has something to add at this stage?

@sarevok-anchev
Copy link

This is the very same backup file from last month by the way, which signal-back can perfectly read..

@edaubert
Copy link

Hi,

I also have this issue coming from an Android 7.1.2 and going to an Android 9.0.2

As far as I understand, this seems to be related to #8327

@greyson-signal @elkhadiy can maybe help us as they were the ones involved in #8327

I am using the 4.31.6 version which seems to be corresponding to the master version.
Still I have the issue.

@elkhadiy
Copy link
Contributor

elkhadiy commented Dec 15, 2018

Hi,

Just skimmed through this thread, I'll be back later on to help.

What I can say for now is that before 4.30.2, when restoring a backup, Signal was happily decrypting all messages without checking their message authentication code (MAC). #8327 fixes this check.

Now it seems we are dealing with some corrupt data in the backup. I'll hack together a tool to try and find the offending frames. (I'll keep you guys posted)

EDIT(2018-12-16):

So I'm a little puzzled by the fact that OP can decrypt the backup file with signal-back while he has a Bad MAC error. Are you sure the whole file is decrypted and that it didn't just decrypt the good frames? Could you use my tool : https://github.com/elkhadiy/debruitage ? I made sure to make it explicitly report all bad frames it encounters during the process.

EDIT(2018-12-18): Removed superfluous information irrelevant to the issue at hand.

@edaubert
Copy link

I ran your tool and got the following exception:

Traceback (most recent call last):
  File "/home/royalvein/bin/miniconda/envs/atom/bin/signal-bkp-decrypt", line 11, in <module>
    load_entry_point('signal-backup-manager==0.1.dev1', 'console_scripts', 'signal-bkp-decrypt')()
  File "/home/royalvein/bin/miniconda/envs/atom/lib/python2.7/site-packages/signal_backup_manager/cli.py", line 23, in run
    bkp = SignalBackup(args.backup_file, args.passphrase)
  File "/home/royalvein/bin/miniconda/envs/atom/lib/python2.7/site-packages/signal_backup_manager/signal_backup.py", line 22, in __init__
    + datetime.now().strftime("%Y-%m-%d--%H-%M-%S")
  File "/home/royalvein/bin/miniconda/envs/atom/lib/python2.7/site-packages/fs/osfs.py", line 311, in makedir
    _path = self.validatepath(path)
  File "/home/royalvein/bin/miniconda/envs/atom/lib/python2.7/site-packages/fs/base.py", line 1429, in validatepath
    else "paths must be str (not bytes)"
TypeError: paths must be unicode (not str)
Exception AttributeError: "SignalBackup instance has no attribute 'preference_file'" in <bound method SignalBackup.__del__ of <signal_backup_manager.signal_backup.SignalBackup instance at 0x7f77295e3200>> ignored

I do not know if it is the expected behavior...
Basically, I clone your project, and follow the readme (pip install...).

However, I did not try signal-back before so i did it at the same time and I was not able to extract my messages and got:

error: failed to open backup file: failed to read headerLengthBytes: EOF

Maybe my issue is not the same after all even if the behavior seems similar (bad mac error + count of messages is good) to @spospartan104

So I try again to import my message and get the exact exception which is not the same as @sarevok-anchev (in term of the line numbers but maybe the version differs)
Here are the logs:

W RegistrationActivity: null
12-19 23:45:39.169  4632  7965 W RegistrationActivity: java.io.IOException: Bad MAC
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readAttachmentTo(FullBackupImporter.java:298)
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at org.thoughtcrime.securesms.backup.FullBackupImporter.processAttachment(FullBackupImporter.java:140)
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at org.thoughtcrime.securesms.backup.FullBackupImporter.importFile(FullBackupImporter.java:87)
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:396)
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:388)
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at android.os.AsyncTask$2.call(AsyncTask.java:333)
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
12-19 23:45:39.169  4632  7965 W RegistrationActivity: 	at java.lang.Thread.run(Thread.java:764)

@elkhadiy
Copy link
Contributor

elkhadiy commented Dec 20, 2018

Oh my bad, that's because it's written in python3 so you can go ahead and pip uninstall signal-backup-manager then pip3 install .

Though signal-back's error message is weird, what's the first 4 bytes of your backup file?

~$ echo $(( 16#$(xxd -p -l 4 signal-yyyy-mm-dd-hh-mm-ss.backup) ))

@edaubert
Copy link

Well... My bads...

The file I get to run the command was corrupted.

I redownload it and now there is no error with signal-back and your tool.
However there still the Bad Mac exception on android.

echo $(( 16#$(xxd -p -l 4 signal-yyyy-mm-dd-hh-mm-ss.backup) ))

gives me 54 with the non corrupted file.

@elkhadiy
Copy link
Contributor

Are you sure Signal tries to restore from the file you checked?

For example you only have that one in /sdcard/Signal/Backups/?

@edaubert
Copy link

Yep I try with 2 different backups but each time, only one backup was available in this folder.

@edaubert
Copy link

Hi,

Well today, I choose to reset my phone because I mess with it to do some tests with multiple apps.
And I choose to retry the installatio of Signal and the import of my backup and everything worked fine.

I don't know what was the cause of this issue but it seems resolved for me after the reset.

Anyway thanks for the help. Signal is really a cool app and I missed it !

@sarevok-anchev
Copy link

@elkhadiy I tried your tool and there's an error:

Bad frame @ file offset 645847
Raw Frame data:
b'\xd1\x0e\xd7\xc8\xcc\t\xd0/\x06/\xe5#\xb6\xcbo2:\xab\xfc\xa4]\x1e\xc3\x8e\xf4!C\xdd"\xd1\x15\xd3<\xa6\xea\xca\xeb\x9c$\xc5\n\x01\x12\x83v\x0eC\x0c\x14\xccq\xba\x96#\x123d\x98\xe4\x82\xb4m\xd3/\xa1\x15\xa2\xef1\xa4\r\xdd\x9d\xf3\x17$\x87\x0c\x9d\x11\n\xf3A\x16_\xf7i\x81\xf2NKQ\xd5Zd<\x05\t.k\x03\xa5X\xb5gN\x04\x0cF\xf8\xb2\xbd\x92\xed(\xe5.\xb7@\xad\xdcM\xbe\xd5*m5\xbfeM}\x07\x10t>\xada\x1b\x8b\xe2\x15\x91oE\xbb\xf8\xa9\xa8E8z\xc4\xca\x87{\x82X_di\xcf\xb9\xad\xec\xb9=\xf13\x11\xfc<\xf9i;\xd8sx\x83\xe3\x8b:r6\xadX\x1d\xac2\xed@\xba\xbc\xc0`\xb0\x9d\x07\xc7\xab\xe6j\xf0#`\x9e\x10\x18\x12\xcc\xf8)\xb5\xdeC\xba'
Attempting to build frame obj:
Traceback (most recent call last):
  File "/home/user/.local/bin/signal-bkp-decrypt", line 11, in <module>
    load_entry_point('signal-backup-manager==0.1.dev1', 'console_scripts', 'signal-bkp-decrypt')()
  File "/home/user/.local/lib/python3.6/site-packages/signal_backup_manager/cli.py", line 23, in run
    bkp = SignalBackup(args.backup_file, args.passphrase)
  File "/home/user/.local/lib/python3.6/site-packages/signal_backup_manager/signal_backup.py", line 50, in __init__
    for frame in self.__get_backup_frames():
  File "/home/user/.local/lib/python3.6/site-packages/signal_backup_manager/signal_backup.py", line 130, in __get_backup_frames
    frame.ParseFromString(plaintext)
google.protobuf.message.DecodeError: Error parsing message

Note that:

  1. This is the only backup file in /sdcard/Signal/Backups, so I'm 100% sure it's the one Signal is attempting to use.

  2. Signal-back can decrypt the backup: signal-back check $filename result is Backup looks okay from here.

  3. Earlier you said: What I can say for now is that before 4.30.2, when restoring a backup, Signal was happily decrypting all messages without checking their message authentication code (MAC). #8327 fixes this check. .. however I've attempted to restore with 4.29.7 it's not possible either. I do remember having restored this backup with previous versions, but a) I don't remember which version and b) of course the backup file has changed since then, and therein might lie the problem.

I must say it's a little bit frustrating that the option to set a very long passphrase and encrypt the app data was removed in previous versions, I never lost a single backup that way over the years, now I'm forced to relay on the signal backup functionality, which apparently in certain unknown circumstances creates corrupted backups, and it's already the second time I'm losing data.

Personally I brought more than 100 people into Signal over the years, and now I can't reach any of them for more than a month because of this bug.

A bit offtopic, but I needed to vent - I had a good grip on backup flow, now need to rely on a dumbed down version, and it's the second time that it screws my data up. Not good.

Anyway..

Let's look towards a possible solution.

Can you offer some guidance on what the best next steps are from this position?

I don't want to lose the conversation history yet again, and since there's roughly a month and a half of undelivered messages now, I would like to keep the same encryption keys so that they get delivered (eventually).

The error must be in some corrupted attachment. signal-back has (on quick glance) all of the messages. It would be way less catastrophic to lose some attachments rather than lose the whole conversation history.

Nevertheless, signal-back can recover a lot of images and audio from this supposedly corrupted backup. Maybe even all of them - I wouldn't know.

Is it possible to make signal ignore a corrupted attachment rather than abort the backup in an all-or-nothing fashion?

Perhaps even have an option to ignore such errors altogether (at the users' peril) ?

How about extending your tool to ignore the errors and discard the file/message in question, and outputting a new backup file minus the "bad frames" ? That could be a fast solution to get signal going quickly again.

What do you think @elkhadiy?

@elkhadiy
Copy link
Contributor

elkhadiy commented Jan 2, 2019

Oh yeah sorry I derped in my tool, forgot to catch the potential frame construction exception.

Signal-back can decrypt the backup: signal-back check $filename result is Backup looks okay from here.

Hmmm weird... I'll try and see what he does (but I'm not that good with golang).

however I've attempted to restore with 4.29.7 it's not possible either.

Yeah pretty sure you won't restore from this backup with the current state of affairs since at least this frame seems to be pretty borked, if protobuf can't parse it...

Is it possible to make signal ignore a corrupted attachment rather than abort the backup in an all-or-nothing fashion?
How about extending your tool to ignore the errors and discard the file/message in question, and outputting a new backup file minus the "bad frames" ? That could be a fast solution to get signal going quickly again.

Yep, was thinking about proposing this in the app's backup restore process. Something flexible that would report bad messages or attachments and restores anyway...
I'll put together something that'll analyse the database entries and reports what is most likely missing (sms/mms entry or attachment and maybe even its filename I think)

I was also planning on writing a module that rebuilds the backup using the same passphrase anyway for a friend of mine that wants to import his Facebook messenger history. Pretty sure we can fix your backup file!

I'll get back to you hopefully very soon.

@sarevok-anchev
Copy link

Beautiful, thank you.

@mike-edel
Copy link
Author

@elkhadiy Thanks for the tool - was struggling a bit to get it working on Windows. Been a while since I ran stuff in a shell. Getting some odd errors:
Bad frame @ file offset 76 Raw Frame data: b'\xf3EaU' Attempting to build frame obj:

Full console output:
signal-bkp-decrypt.exe -b c:/signal-2018-11-08-22-04-02.backup -p '040871752236135417905193908720' Bad frame @ file offset 76 Raw Frame data: b'\xf3EaU' Attempting to build frame obj: Traceback (most recent call last): File "C:\Users\mikee\AppData\Local\Programs\Python\Python37-32\Scripts\signal-bkp-decrypt-script.py", line 11, in <module> load_entry_point('signal-backup-manager==0.1.dev1', 'console_scripts', 'signal-bkp-decrypt')() File "c:\users\mikee\appdata\local\programs\python\python37-32\lib\site-packages\signal_backup_manager\cli.py", line 23, in run bkp = SignalBackup(args.backup_file, args.passphrase) File "c:\users\mikee\appdata\local\programs\python\python37-32\lib\site-packages\signal_backup_manager\signal_backup.py", line 50, in __init__ for frame in self.__get_backup_frames(): File "c:\users\mikee\appdata\local\programs\python\python37-32\lib\site-packages\signal_backup_manager\signal_backup.py", line 130, in __get_backup_frames frame.ParseFromString(plaintext) File "c:\users\mikee\appdata\local\programs\python\python37-32\lib\site-packages\google\protobuf\message.py", line 185, in ParseFromString self.MergeFromString(serialized) File "c:\users\mikee\appdata\local\programs\python\python37-32\lib\site-packages\google\protobuf\internal\python_message.py", line 1083, in MergeFromString if self._InternalParse(serialized, 0, length) != length: File "c:\users\mikee\appdata\local\programs\python\python37-32\lib\site-packages\google\protobuf\internal\python_message.py", line 1109, in InternalParse new_pos = local_SkipField(buffer, new_pos, end, tag_bytes) File "c:\users\mikee\appdata\local\programs\python\python37-32\lib\site-packages\google\protobuf\internal\decoder.py", line 850, in SkipField return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end) File "c:\users\mikee\appdata\local\programs\python\python37-32\lib\site-packages\google\protobuf\internal\decoder.py", line 799, in _SkipGroup new_pos = SkipField(buffer, pos, end, tag_bytes) File "c:\users\mikee\appdata\local\programs\python\python37-32\lib\site-packages\google\protobuf\internal\decoder.py", line 850, in SkipField return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end) File "c:\users\mikee\appdata\local\programs\python\python37-32\lib\site-packages\google\protobuf\internal\decoder.py", line 782, in _SkipFixed64 raise _DecodeError('Truncated message.') google.protobuf.message.DecodeError: Truncated message.

Don't know what to make of it to be honest. And no idea whether signal-back does actually decrypt the whole thing. I ended up getting a huge xml file though.

@sarevok-anchev
Copy link

Any updates @elkhadiy ?

@unDocUMeantIt
Copy link

i'm also seeing this on a friend's phone, trying to restore a fresh backup from an old phone on a new one.

@elkhadiy your tool is great, and indeed it complains about a corrupted frame. could it be extended to re-encrypt the backup to a new file with all corrupted frames dropped?

@JamesHarrison
Copy link

I've just seen this on my phone; I was unable to send (#8602) and figured a reinstall would probably do the trick, but I'm unable to restore my messages. Fairly chunky backup at 60,000 messages. Can't get debruitage to run on my desktop as Ubuntu doesn't have the fts5 extension for sqlite packaged, but will try again on Arch later. Having Signal ignore (with some kind of message) corrupt MAC frames would be the ideal outcome, I think - losing 60,000 messages for one glitch isn't fabulous.

@bepaald
Copy link

bepaald commented Feb 23, 2019

Just wanted to let you guys know, I'm working on this. I've been able to decrypt (and interpret) the backup data for a long time and just started working on reencryption last week and making good progress.

I think a lot of the past messages shouldn't be in this github issue as they do not relate to any bug in Signal (supporting corrupted backups would be a feature request). The only possible bug here is that signal pops up a wrong password error when a bad Mac is encountered, while I think a 'file corrupted' popup would be way more likely if it happens any time after the first frame is decoded. So, if I have something to test for you, I will create a thread on the forum and post a link here. Note it might take a long time (think months) , as I sometimes don't have spare time for an extended period.

Also, I do not know how Signal handles backups with frames missing, so there are no guarantees this will work. Frames are not necessarily independent things (attachment data belongs to an entry in the 'part' database, which belongs to an entry in the 'mms' database. The restoration might for all I know still fail if one of those frames is missing. Also, random corruption in a random location might result in anything, that is, if you're unlucky, a single bit flipped might make not just one frame, but all following frames unreadable.

Anyway, I didn't intend for this message to get this long. Just wanted to let you know, a tool is coming though it might be a while.

@unDocUMeantIt
Copy link

The only possible bug here is that signal pops up a wrong password error when a bad Mac is encountered, while I think a 'file corrupted' popup would be way more likely if it happens any time after the first frame is decoded.

we were able to reliably reproduce 'corrupted' files. no matter how often we made new backups on the one phone, they always turn out to be corrupted on the other one. i wouldn't rule out the possibility that signal's backup routine has a hidden issue leading to corrupted frames in backups which triggered it, and the restore problems are merely a symptom.

@JamesHarrison
Copy link

I'd +1 that suggestion, @unDocUMeantIt - my phone has dozens of GB free, backups were allowed to complete fully onto internal storage with no sleep/screenlock, and restore attempts likewise. I can't think of any potential source for corruption of the backup other than in creation by Signal.

If the error is caused because the contents themselves are also being checked during restore, but in normal operation such corrupted contents are tolerated, then the behaviour should be modified to catch what would cause corruption at "point of entry" to storage and abort then, and to permit restore behaviour to ignore those corrupt frames on restoration.

@bepaald
Copy link

bepaald commented Aug 22, 2019

@abstractThought I'm not sure what you mean. In normal operation, all (unencrypted) data only lives in memory, but I suppose you could imagine some malware exists that gets to it, but I'd say it's far more likely that type of malware exists for android and is looking for the signal app, than for PC looking for my program. Personally, I actually trust my PC more than I do my phone.

@santa-klaus I have some initial backup merging support. It works on the small files I tried, but definitely needs testing. Are you interested in trying? The method is a little involved as it actually turned out to be quite a difficult procedure.

Example, click to open if you dare... ;)

Assuming a current backup current.backup and an old one source.backup. First you need to get a list of threads from the old backup:

[~/programming/signalbackup-tools] $ ./signalbackup-tools --listthreads source.backup 871668681636341580140408145422 
IV: (hex:) e3 1c c6 5c 46 e3 b6 62 ff a7 95 40 e6 99 f9 eb (size: 16)
SALT: (hex:) 35 6a 55 bc 80 e9 da dd 2c ed 28 e2 da 22 f4 b8 3b e3 5d 44 2b 94 18 3e d0 6a 6f e3 79 d9 5d 1f (size: 32)
BACKUPKEY: (hex:) 3e 91 7a 80 66 9f 6b 1f a9 77 b1 3e fb 10 ae 15 b2 b4 69 7f 99 ad 40 16 57 61 00 ce cc 8e d0 cc (size: 32)
CIPHERKEY: (hex:) 69 67 67 1b d7 51 41 84 33 88 6b 1e 3b 21 e9 96 6e f7 f0 0d 61 ec 64 6e 44 29 97 3e df 49 83 26 (size: 32)
MACKEY: (hex:) 0b 30 c9 d3 56 6b 8c 81 f3 f5 bb cf 1d b4 ed 57 66 dc c8 72 11 58 04 42 07 db b8 a1 61 62 2e c3 (size: 32)
COUNTER: 3810313820
Reading backup file...
FRAME 93 (100.0%)... Read entire backup file...
done!
----------------------------------------------------------------------------------------------------------
| _id | recipient_ids                  | snippet                        | COALESCE(recipient_prefer[...] |
----------------------------------------------------------------------------------------------------------
| 1   | +161765XXXXX                   | <#> Your Signal verificat[...] | (NULL)                         |
| 2   | __textsecure_group__!a2c3[...] | Ok                             | devgroup                       |
| 3   | +316474XXXXX                   | Last msg                       | Master Phone                   |
| 4   | +316836XXXXX                   | Ok                             | Devphone Red                   |
----------------------------------------------------------------------------------------------------------

Then, you can import a selection of threads from the source file into your current backup and export to a new backup file. Expect tons of output (I really need to clean that up sometime):

[~/programming/signalbackup-tools] $ ./signalbackup-tools --importthreads 2,3,4 --source source.backup --sourcepassword 871668681636341580140408145422 --output merged.backup --opassword 000000000000000000000000000000 current.backup 420676745407910020904427069666
IV: (hex:) e2 dd c7 b0 d7 c1 81 01 6b db f8 24 47 98 5c 35 (size: 16)
SALT: (hex:) 47 a8 83 be 1f 9f d7 a4 db 6c 82 bd c4 d2 e9 4b 5e 90 d7 fd a4 98 81 4a 62 f1 0e d6 e5 52 f7 ee (size: 32)
BACKUPKEY: (hex:) b1 59 c2 ec ce cf dc de 37 6f bd af 15 79 06 c7 30 c4 56 3f 5f 60 f8 74 67 34 90 7b a5 c5 44 2b (size: 32)
CIPHERKEY: (hex:) 69 12 52 65 c2 5d 96 e0 26 dc 46 6c 95 92 18 f0 e7 69 31 7d 07 f7 ce 7e 4d 74 76 10 d1 78 da d8 (size: 32)
MACKEY: (hex:) 37 4c bc 18 c2 93 47 60 67 63 0d 81 24 65 9e ab 55 a3 c6 17 fb 95 26 2e 4a 68 e8 aa 5c a5 0b 7e (size: 32)
COUNTER: 3806185392
Reading backup file...
FRAME 88 (100.0%)... Read entire backup file...
done!
Importing thread 2 from source file: source.backup
IV: (hex:) e3 1c c6 5c 46 e3 b6 62 ff a7 95 40 e6 99 f9 eb (size: 16)
SALT: (hex:) 35 6a 55 bc 80 e9 da dd 2c ed 28 e2 da 22 f4 b8 3b e3 5d 44 2b 94 18 3e d0 6a 6f e3 79 d9 5d 1f (size: 32)
BACKUPKEY: (hex:) 3e 91 7a 80 66 9f 6b 1f a9 77 b1 3e fb 10 ae 15 b2 b4 69 7f 99 ad 40 16 57 61 00 ce cc 8e d0 cc (size: 32)
CIPHERKEY: (hex:) 69 67 67 1b d7 51 41 84 33 88 6b 1e 3b 21 e9 96 6e f7 f0 0d 61 ec 64 6e 44 29 97 3e df 49 83 26 (size: 32)
MACKEY: (hex:) 0b 30 c9 d3 56 6b 8c 81 f3 f5 bb cf 1d b4 ed 57 66 dc c8 72 11 58 04 42 07 db b8 a1 61 62 2e c3 (size: 32)
COUNTER: 3810313820
Reading backup file...
FRAME 93 (100.0%)... Read entire backup file...
done!
Deleting messages not belonging to requested thread(s) from 'sms'
Deleting messages not belonging to requested thread(s) from 'mms'
Deleting attachment entries from 'part' not belonging to remaining mms entries
Deleting other threads from 'thread'...
Dealing with thread id: 2
  Updating msgcount
  Setting last msg date
  Updating snippet
  Updating snippet type
Deleting removed groups...
Delete others from 'identities'
Deleting group receipts entries from deleted messages...
Deleting drafts from deleted threads...
Adjusting indexes in tables...
Compacting table: sms
Compacting table: mms
Compacting table: part
Compacting table: recipient_preferences
Compacting table: groups
Compacting table: identities
Compacting table: group_receipts
Compacting table: drafts
Found existing thread for this recipient in target database, merging into thread 5
Importing statements from source table 'sms'...4 entries...
Importing statements from source table 'mms'...3 entries...
Importing statements from source table 'part'...0 entries...
Importing statements from source table 'drafts'...0 entries...
Importing statements from source table 'push'...0 entries...
Importing statements from source table 'group_receipts'...6 entries...
Importing statements from source table 'sticker'...0 entries...
Importing statements from source table 'job_spec'...0 entries...
Importing statements from source table 'constraint_spec'...0 entries...
Importing statements from source table 'dependency_spec'...0 entries...
Importing thread 3 from source file: source.backup
IV: (hex:) e3 1c c6 5c 46 e3 b6 62 ff a7 95 40 e6 99 f9 eb (size: 16)
SALT: (hex:) 35 6a 55 bc 80 e9 da dd 2c ed 28 e2 da 22 f4 b8 3b e3 5d 44 2b 94 18 3e d0 6a 6f e3 79 d9 5d 1f (size: 32)
BACKUPKEY: (hex:) 3e 91 7a 80 66 9f 6b 1f a9 77 b1 3e fb 10 ae 15 b2 b4 69 7f 99 ad 40 16 57 61 00 ce cc 8e d0 cc (size: 32)
CIPHERKEY: (hex:) 69 67 67 1b d7 51 41 84 33 88 6b 1e 3b 21 e9 96 6e f7 f0 0d 61 ec 64 6e 44 29 97 3e df 49 83 26 (size: 32)
MACKEY: (hex:) 0b 30 c9 d3 56 6b 8c 81 f3 f5 bb cf 1d b4 ed 57 66 dc c8 72 11 58 04 42 07 db b8 a1 61 62 2e c3 (size: 32)
COUNTER: 3810313820
Reading backup file...
FRAME 93 (100.0%)... Read entire backup file...
done!
Deleting messages not belonging to requested thread(s) from 'sms'
Deleting messages not belonging to requested thread(s) from 'mms'
Deleting attachment entries from 'part' not belonging to remaining mms entries
Deleting other threads from 'thread'...
Dealing with thread id: 3
  Updating msgcount
  Setting last msg date
  Updating snippet
  Updating snippet type
Deleting removed groups...
Delete others from 'identities'
Deleting group receipts entries from deleted messages...
Deleting drafts from deleted threads...
Adjusting indexes in tables...
Compacting table: sms
Compacting table: mms
Compacting table: part
Compacting table: recipient_preferences
Compacting table: groups
Compacting table: identities
Compacting table: group_receipts
Compacting table: drafts
Found existing thread for this recipient in target database, merging into thread 6
Importing statements from source table 'sms'...5 entries...
Importing statements from source table 'mms'...1 entries...
Importing statements from source table 'part'...1 entries...
Importing statements from source table 'drafts'...0 entries...
Importing statements from source table 'push'...0 entries...
Importing statements from source table 'group_receipts'...0 entries...
Importing statements from source table 'sticker'...0 entries...
Importing statements from source table 'job_spec'...0 entries...
Importing statements from source table 'constraint_spec'...0 entries...
Importing statements from source table 'dependency_spec'...0 entries...
Importing thread 4 from source file: source.backup
IV: (hex:) e3 1c c6 5c 46 e3 b6 62 ff a7 95 40 e6 99 f9 eb (size: 16)
SALT: (hex:) 35 6a 55 bc 80 e9 da dd 2c ed 28 e2 da 22 f4 b8 3b e3 5d 44 2b 94 18 3e d0 6a 6f e3 79 d9 5d 1f (size: 32)
BACKUPKEY: (hex:) 3e 91 7a 80 66 9f 6b 1f a9 77 b1 3e fb 10 ae 15 b2 b4 69 7f 99 ad 40 16 57 61 00 ce cc 8e d0 cc (size: 32)
CIPHERKEY: (hex:) 69 67 67 1b d7 51 41 84 33 88 6b 1e 3b 21 e9 96 6e f7 f0 0d 61 ec 64 6e 44 29 97 3e df 49 83 26 (size: 32)
MACKEY: (hex:) 0b 30 c9 d3 56 6b 8c 81 f3 f5 bb cf 1d b4 ed 57 66 dc c8 72 11 58 04 42 07 db b8 a1 61 62 2e c3 (size: 32)
COUNTER: 3810313820
Reading backup file...
FRAME 93 (100.0%)... Read entire backup file...
done!
Deleting messages not belonging to requested thread(s) from 'sms'
Deleting messages not belonging to requested thread(s) from 'mms'
Deleting attachment entries from 'part' not belonging to remaining mms entries
Deleting other threads from 'thread'...
Dealing with thread id: 4
  Updating msgcount
  Setting last msg date
  Updating snippet
  Updating snippet type
Deleting removed groups...
Delete others from 'identities'
Deleting group receipts entries from deleted messages...
Deleting drafts from deleted threads...
Adjusting indexes in tables...
Compacting table: sms
Compacting table: mms
Compacting table: part
Compacting table: recipient_preferences
Compacting table: groups
Compacting table: identities
Compacting table: group_receipts
Compacting table: drafts
Importing statements from source table 'sms'...4 entries...
Importing statements from source table 'mms'...0 entries...
Importing statements from source table 'part'...0 entries...
Importing statements from source table 'thread'...1 entries...
Importing statements from source table 'identities'...0 entries...
Importing statements from source table 'drafts'...0 entries...
Importing statements from source table 'push'...0 entries...
Importing statements from source table 'groups'...0 entries...
Importing statements from source table 'recipient_preferences'...0 entries...
Importing statements from source table 'group_receipts'...0 entries...
Importing statements from source table 'sticker'...0 entries...
Importing statements from source table 'job_spec'...0 entries...
Importing statements from source table 'constraint_spec'...0 entries...
Importing statements from source table 'dependency_spec'...0 entries...
Exporting backup to 'merged.backup'
Writing HeaderFrame...
Writing DatabaseVersionFrame...
Writing SqlStatementFrame(s)...
  Dealing with table 'sms'... 25/25 entries...done
  Dealing with table 'mms'... 7/7 entries...done
  Dealing with table 'part'... 2/2 entries...done
  Dealing with table 'thread'... 7/7 entries...done
  Dealing with table 'identities'... 3/3 entries...done
  Dealing with table 'drafts'... 0/0 entries...
  Dealing with table 'push'... 0/0 entries...
  Dealing with table 'groups'... 1/1 entries...done
  Dealing with table 'recipient_preferences'... 4/4 entries...done
  Dealing with table 'group_receipts'... 8/8 entries...done
  Dealing with table 'sticker'... 0/0 entries...
  Dealing with table 'job_spec'... 1/1 entries...done
  Dealing with table 'constraint_spec'... 0/0 entries...
  Dealing with table 'dependency_spec'... 0/0 entries...
Writing SharedPrefFrame(s)...
Writing EndFrame...
Done!

The program automatically tries to determine into which thread of the current db the old messages should be inserted. This might fail if contact have changed numbers or if one of the backups has a contact with a country code (+316.....) and the other omits it (06....).

@oneof3holes
Copy link

@bepaald been fighting with coinbase to release my dust without me sending in a pic of my ID. Finally happened, didn't want you to think I forgot about you. Thank you again.

@bepaald
Copy link

bepaald commented Sep 13, 2019

@oneof3holes O wow, thanks! I thought you had just decided against it (which would have been fine of course), but this is cool. I really appreciate it. Thanks again!

@santa-klaus
Copy link

@bepaald I am sorry, I got drowned in work. I might have some more time to try things in October and would like to do it. Also, my phone broke, so I will probably have a good reason to merge backups soon. I'll let you know when I get around to do some testing.

@bepaald
Copy link

bepaald commented Sep 25, 2019

@santa-klaus Absolutely not a problem of course. However, just a heads up: I was looking at the source of the 4.48 beta that is currently out and it will change the internal sql database in such a way that it will certainly break my current merging code.

I do plan to rewrite the code to be able to merge backups, but there is no telling how long it will take me. Also, it might take even longer (if ever) to get to a point where I can merge an old style db into a new one which would probably also be a use case after your current install updates to 4.48.

Obviously, you don't have to do it if you don't want to or don't have time, but I just wanted to warn you that the window of opportunity might be closing.

@santa-klaus
Copy link

santa-klaus commented Sep 25, 2019 via email

@alpha1
Copy link

alpha1 commented Oct 22, 2019

Same issue, android 10. Adding my info and a screen cast in case it helps any.

Actual result: I have followed Signal's instructions on backing up and restoring a backup. I am moving from a OnePlus 5t to a OnePlus 7t, both using Signal beta, latest. When I type in the wrong backup code, it fails to restore the backup, which is expected, but when I type in the right code, it proceeds to loop through all messages and then throw a toast error saying "Incorrect backup passphrase", and does not import the backup.

Expected result: Backup would restore messages

Screenshots

Screencast: https://imgur.com/a/TirPqVa

Device info

Device: OnePlus 7t (HD1905)
Android version: 10
Signal version: 4.49.7 (beta)

Link to debug log

https://debuglogs.org/3bb67a2279313eb2d71a190b82d949b32684407fb8371d9bdae64cf00b06ea52

@alpha1
Copy link

alpha1 commented Oct 23, 2019

I'll add to this, I had almost 70,000 messages, and when I trimmed conversations to 15,000 messages, I removed around 20,000 total messages, and then the import worked. So it's something with the contents of the message themselves, perhaps that attachment issue mentioned above.

@dcormier
Copy link

dcormier commented Oct 26, 2019

I am having the same issue. I have some 19K+ messages in a backup file that's about 2GB. I've made very sure the passphrase is correct. These were my steps:

  1. On the source phone, started from scratch by:
    1. Turning off backups
    2. Ensuring they were all deleted
    3. Turning backups back on
    4. Tapped on the passphrase to copy it
    5. Pasted it into my password manager
    6. Creating a new backup
  2. Moved the backup file to the new phone
  3. Copied the passphrase from my password manager to Signal on the new phone to restore the backup.

Signal almost immediately stops and pops up a toast that says "Incorrect backup passphrase".

Using signal-back's check option with the passphrase says "Backup looks okay from here."

@rba7sp
Copy link

rba7sp commented Oct 27, 2019

I have the same issue. :(

10-27 18:12:51.188 11228 12084 W RegistrationActivity: null 10-27 18:12:51.188 11228 12084 W RegistrationActivity: java.io.IOException: Bad MAC 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at org.thoughtcrime.securesms.backup.FullBackupImporter$BackupRecordInputStream.readAttachmentTo(FullBackupImporter.java:289) 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at org.thoughtcrime.securesms.backup.FullBackupImporter.processAttachment(FullBackupImporter.java:134) 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at org.thoughtcrime.securesms.backup.FullBackupImporter.importFile(FullBackupImporter.java:81) 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:383) 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at org.thoughtcrime.securesms.RegistrationActivity$2.doInBackground(RegistrationActivity.java:376) 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at android.os.AsyncTask$2.call(AsyncTask.java:333) 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at java.util.concurrent.FutureTask.run(FutureTask.java:266) 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 10-27 18:12:51.188 11228 12084 W RegistrationActivity: at java.lang.Thread.run(Thread.java:764)

@alan-signal
Copy link
Contributor

alan-signal commented Oct 29, 2019

@dcormier Make sure all 30 digits are there. When pasting a passphrase containing spaces, the last 5 digits can be left off.

Either copy the digits without spaces, or manually add those last 5.

@dcormier
Copy link

dcormier commented Oct 30, 2019

Make sure all 30 digits are there. When pasting a passphrase containing spaces, the last 5 digits can be left off.

Either copy the digits without spaces, or manually add those last 5.

I'll try that later, but perhaps the app should handle that differently? Seems like a UX problem. Maybe the app should accept the pasted value and remove the whitespace internally? Or try it both ways (with the pasted whitespace included and then with it removed)?

greyson-signal added a commit that referenced this issue Nov 1, 2019
Instead of aborting the entire backup restore.

Related to #8355
@alan-signal
Copy link
Contributor

alan-signal commented Nov 27, 2019

For those of you who are in a situation where you still have your old (broken) backup and would like to try to restore it, I've has made an experimental branch that has been able to restore these broken backups (or at least what we think they look like).

You can reach out to me at alan@signal.org. I can get you a release-signed build of this branch and we can see if that fixes the problem.

Alternatively, if you’re competent at Android development, the source for the fix is at: https://github.com/signalapp/Signal-Android/tree/alan/backup-restoration where the procedure would be to restore the bad backup using that branch, make a new backup, then get back on official releases and restore once more with the new backup.

A debug log from successful or failed attempts to restore the bad backup (either using that branch or an officially signed build of it from Greyson) would be very useful.

@travisterrell
Copy link

travisterrell commented Dec 2, 2020

I see this is still open, but no new comments in a year or so, so hoping to find out about the current status. I'm experiencing the same problem, and my online searching has yielded some other users with the issue, but no solution. Passphrase definitely entered correctly (as mentioned elsewhere, the behavior is different than when entered incorrectly--the counter increases as it loops through the old messages until eventually stopping with the invalid passphrase error.)

@alan-signal It looks like the branch you had created for users to workaround this problem is now gone (though at a year old, I'm not positive it would've imported messages from a newer version of Signal?) I'm a developer (though not Android), so I shouldn't be completely useless at figuring things out if there were a version I could make work. FWIW, there are definitely loads of attachments of many different file types--which I'm willing to lose if that's what it were to take. Also, here's a link to logcat output, though I don't see anything relevant myself.

I'm really hoping to get this resolved, as the backup contains almost 20k messages that I actually need to reference somewhat often. Worst case scenario, I suppose I can leave Signal with its backed up messages on my old device to reference when needed, but that really seems non-ideal. Anyway,

@spospartan104
Copy link

@travisterrell I had this problem before; my issue was much like someone said above and their was a borked multimedia file in an old message (signal message not a carrier mms, but carrier could be a similar issue)

I can't get on to my main system today (moving) But I may be able to dig up the application that was mentioned here as those links have expired. #8355 (comment)

Alternatively you can use the media view in a few different of your larger conversations to see if there are any broken files (could just be blacked out images as thumbnails)

@bepaald
Copy link

bepaald commented Dec 3, 2020

@spospartan104 (and @travisterrell): the program is here: https://github.com/bepaald/signalbackup-tools

I do believe however that the app is a lot more tolerant of bad attachments in the backup these days, so if it fails to import the backup file, the damage to the file might be bigger than you would hope.

My program should still be able to get all information that is in the backup out of it and into a new, working backup, but it is by no means guaranteed to be an automated process anymore, it often requires some custom coding. Let me know if I can help. And please forgive any slow response from me, I have some busy work periods sometimes, especially this time of year.

@travisterrell
Copy link

travisterrell commented Dec 3, 2020 via email

@spospartan104
Copy link

@bepaald With the save again; :)

@stale
Copy link

stale bot commented Jan 27, 2022

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests