Allow file decryption with only the files/keys and passwords


it would be great if it was possible to decrypt files when encryption was enabled with just the files and the corresponding keys as well as the (recovery) password. Currently, it is very difficult to restore files when encryption was enabled on the server and one has to restore some of them from a backup. The only viable way as it is now is to restore the whole system on a separate server/vm and then retrieve the files. Simply putting the files/keys in place and run occ to decrypt them won’t do anything.

This should be possible with either the occ tool or some other recovery tool.


Not exactly sure why sharing the admin_manual was supposed to useful. There is no information for retrieving a single file from a single user. Which is what this feature request is asking to support in the future.

ianathompson is right. The occ tool only allows you to decrypt files if the whole Owncloud installation is up and running. And since 8.2 changed the way encryption is done fundamentally there is basically no 3rd-party script available that works. Anyway, this should be available in core and not some 3rd-party script that does not get maintenance as needed.

If one needs to decrypt a few files then the only option is to restore the whole owncloud instance to decrypt them.

I actually try to implement such a process, although this will not be developed as an “inline nextcloud app” (at least not for now…). My starting point is the daily backuped files (from the “data” directory).

My goal is to “get hold of the encrypted file and the administrator’s recovery key. then use the (known) recovery password and have the file decrypted”. Then the decrypted file will be “handed over” to the original user again.

Most of that process is working already for my environment, next step would be the actual decryption.
Currently I am getting an OPENSSL error, when trying to decrypt the “recoverykey” file:

Fatal error: Uncaught Exception: Missing Signature in /…/crypt.php:237

Where could I get some “deep-diving” knowledge of the decryption process?

1 Like

Do you have the code somehwere? Then some of the encryption experts can probably help you out.

You’re of course right, without the code this question sounds a bit stupid, sorry!

I try to use a derivate of …/apps/encryption/lib/crypto/crypt.php
and modify as little as possible (in the end I intend to use the unmodified original library only).

I removed all “namespace” definitions at the top of the library, and replaced all $this-> … method calls by direct function calls. No other changes were nessessary so far.

calling $recoveryKeyDecrypted = decryptPrivateKey($recoveryKeyEncrypted, $recoveryPassword); [codeline 392 in github]
results in the mentioned error message in the method hasSignature [codeline 557 in github]

So it looks like my recoveryKey is expected to have a signature, but actually this is not found in the key…

any ideas?

can you help here @bjoern ?

The signature is created with a key which is a combination of the file-key + file-version + block-number. The version is stored in the file cache table and get’s increased every time the file is updated. So if you just have a backup of the files there is no way to verify the signature again. But it should be possible to ignore the signature and just decrypt the content as it is. Of course this means that you will not notice if someone changed the file on your backup or on your server right before you created the backup.

Thanks Bjoern,
I do actually backup the file-cache database table as well (actually twice, once BEFORE the files are backuped, and once after, so I can verify I have the relevant datarecord for that file - except for the “very” remote chance, that the file gets edited TWICE during the whole backup process).
So let me have a look at the filecache table and see if I can figure out what exactly you mean…
will be back soon with more questions I belief…

OK, lets assume I want to restore the file “Test-fuer-Ruecksicherung.txt” from my “/privat/” folder… In the filecache-table I have this record for it. So what does this record tell me (and where is this “version” incremented)?

The number stored in “encrypted” is the version you need to verify the signature. The best way to get a feeling how this works is to step through the code, beginning here

I thought it would be “encrypted”, thanks for confirming this.
will start “reverseEngineering” as you suggested (and might come back here for help probably). Thanks for your help

I think I am missing something here…

I started to copy all the relevant functions from crypt.php to my own class for now. This allows me to dive into the decryption functionality (without all other requirements).

However, I am still getting this “Missing signature” error from:

What I do not understand is: this function checks for the position of the signature in the encrypted data:

    $meta = substr($catFile, -93);
    $signaturePosition = strpos($meta, '00sig00');

but my “recoveryKey” (and fileKey and userShareKey) is not “plaintext”, but some “HEX encoded string”. So the “strpos” function understandably never finds “00sig00” in this…

Do I have to convert this “back to plaintext” first - and where is this done?

Sorry, if this sounds stupid, but I try to find my way through this code…

Any help would be great

Any ideas would be much appreciated, please.

Sorry no idea, but an existing script (don’t know if it works):

Thanks tflidd, I looked at that script and it seems that arno01 is decoding the key files first from BASE64. I tried this but the result is not nearly useable. So I am afraid I really need some help here…

The “keyfile” for that given file (test file only) looks like this:
Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
Offset (d) 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15

00000000 04 19 3b 95 93 08 51 b3 8f 2d 26 63 d7 e3 1f ec
00000016 cc b8 5b 20 6c 0a d3 7c 7b a4 b5 75 96 99 3a d7
00000032 e5 c2 c9 8f dd fa 1d 28 e5 71 c8 09 f2 8c 9d 14
00000048 62 76 64 19 72 26 a6 40 06 4d 30 c3 81 16 8f 08
00000064 88 04 c6 8c b3 cf 20 4d 44 3c d0 e8 5c 73 5f e1
00000080 56 ac 95 6c 6f bb 5a c1 a5 b0 30 fc 12 95 ea 67
00000096 75 d5 26 01 df f5 07 33 5c 5a 21 91 35 95 8d 38
00000112 ba 0e d2 b1 e0 1b 08 d3 fe 7f 00 4e b2 83 20 d9
00000128 …
00000144 …
00000160 …
00000176 …
00000192 …
00000208 d6 3a d4 db ad 46 4b 11 0f fb ae eb 10 ea 8d 73
00000224 24 61 88 5a 43 10 c4 1f 05 8c 9e 74 b9 eb 20 5a

Of course, the “Offset” rows and the leading “8-digit numbers” are only for readability, and are NOT in the keyfile.
Keyfile starts with “04193b” and ends with “eb205a”!

So how can I decode this into a “plain text private key”??

Bjoern, can you give some assistence please?

@bjoern your assistance is needed

@bjoern : can you give some assistence please?

Here is another tool to decrypt without database: