⚠️ This issue respects the following points: ⚠️
Bug description
Alright, time to possibly give something back to the community.
How this came to be: I have by accident identified a few files that would not download from my nextcloud, log said "Bad Signature". So I went looking and found a huge number of files that had this issue. Needless to say that my backups do not go far enough for "correct" files so I needed to dig in.
My Nextcloud instance is at least 10 major versions old, so it was always upgraded along the way.
I have encountered an apparent backwards-compatibility issue in Nextcloud's encryption handling of older AES-256-CTR encrypted files.
The files are fully decryptable and structurally intact, but current Nextcloud rejects the final block with Bad Signature.
For the affected files:
Encryption version: 1
Cipher: AES-256-CTR
Encoding: legacy Base64
Header: signed:true
Every physical block decrypts successfully.
Blocks before the final block have signatures matching the legacy signature calculation.
The final block has a signature matching legacy + end.
The current signature calculation does not match the stored signatures.
The failure therefore appears deterministic and related to the legacy block-signature format/position handling rather than damaged ciphertext.
The files were originally encrypted years ago and have subsequently been accessed through newer Nextcloud versions. I do not know the exact Nextcloud version that originally created them.
Reproduction
One affected file:
/user/files/trading/onvista/025-agb.pdf
Physical encrypted file:
545832 bytes
Encrypted data after the 8192-byte header:
537640 bytes
Physical blocks:
66
Nextcloud file version:
1
Cipher:
AES-256-CTR
Header:
HBEGIN:oc_encryption_module:OC_DEFAULT_MODULE:cipher:AES-256-CTR:signed:true:HEND
The corresponding 32-byte file key is:
89f40a506cdca288d83045d73b957a4073ac9cb7cc1e95d06006bbe1f388bac4
Key SHA-256:
cd1eb792f1922ae9542337ad340f418b58e9c7691287766a55ff6d377eaeead5
The key is included here solely to make this particular encrypted test file reproducible. It is a file-specific encryption key, not a server/master secret.
Observed signature behaviour
For blocks 0–64:
stored signature == legacy calculation
stored signature != current calculation
stored signature != legacy + end calculation
For final block 65:
stored signature == legacy + end calculation
stored signature != current calculation
stored signature != current + end calculation
stored signature != legacy calculation
Example, block 65:
Stored:
459984b3925e06f951c137c022e1e8c6595e10c417453e754890dde4d099accf
Current:
4b6a1588ac4e20c394589fb9e3203ff14eef68bd487e134b654dbb91eb84c870
Current + end:
3b8b7606ad056f9ab527b2897c4ebfd0d46061888d2e495c6856daed0ffc5daa
Legacy:
0b111673b7f4a6f4df03afe77cf45c7cdf330315e3854664d692383a604404d0
Legacy + end:
459984b3925e06f951c137c022e1e8c6595e10c417453e754890dde4d099accf
This is an exact match for legacy_end.
Decryption result
All 66 physical blocks decrypt successfully using the file key and AES-256-CTR:
Blocks: 66
Current signature OK: 0
Current signature BAD: 66
Legacy signature OK: 65
Legacy+end signature OK: 1
Decrypt OK: 66
Decrypt FAILED: 0
Plaintext recovered: 398477 bytes
The recovered plaintext size is exactly the expected file size from Nextcloud's file metadata:
398477 bytes
The recovered PDF is structurally valid and opens correctly.
Second/third affected files
This is not isolated to one file.
ZIP
/user/files/Homeday_immocation_Preisatlas.zip
File key SHA-256:
5679a7d008ab95702e1f23f23d4b9664c4bbd46d89f95e86a81aa2cffdd0b6ee
Version: 1
Cipher: AES-256-CTR
Blocks: 552
Legacy signatures:
551 OK
Legacy+end:
1 OK
Current signatures:
0 OK
552 BAD
Decrypt:
552/552 OK
The recovered ZIP passes ZipArchive validation and contains 8 entries.
JPEG
/user/files/AT6/2017_06_10/2017.06.10-10.06.21-iPhone SE-IMG_9874.JPG
File key SHA-256:
674d4b5ca5c391ddcb16b24162d4642e01be765073eecf2f3e2759d3bf621f10
Version: 1
Cipher: AES-256-CTR
Blocks: 487
Legacy signatures:
486 OK
Legacy+end:
1 OK
Current signatures:
0 OK
487 BAD
Decrypt:
487/487 OK
The recovered JPEG is also valid.
Why I think this is a compatibility issue
The important observation is the consistency across unrelated files:
normal blocks -> legacy signature
final block -> legacy + "end" signature
while the current Nextcloud implementation expects a different signature calculation.
This occurs regardless of whether the file is a PDF, ZIP, or JPEG.
The encrypted data itself appears intact because every block decrypts successfully and the recovered plaintext has the expected size/content.
This makes random corruption of the final block unlikely.
It also appears unlikely that the problem is simply an incorrect file key: the legacy signatures reproduce exactly for the blocks.
Potential impact
This could affect files encrypted with an older version of the encryption app and subsequently accessed/decrypted after an encryption-format/signature implementation change.
In my case, Nextcloud's normal decryption fails with:
OCP\Encryption\Exceptions\GenericEncryptionException
Bad Signature
and stops at the final block.
With signature verification bypassed, Nextcloud's own Crypt::symmetricDecryptFileContent() successfully decrypts every block.
Therefore the underlying encrypted data remains recoverable, but normal Nextcloud decryption fails.
Environment
Current Nextcloud installation:
php occ status
- installed: true
- version: 34.0.3.2
- versionstring: 34.0.3
- edition:
- maintenance: true
- needsDbUpgrade: false
- productname: Nextcloud
- extendedSupport: false
Encryption app version:
PHP version:
8.3.29
OpenSSL version:
OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)
Original encryption/Nextcloud version:
Unknown; files may originate from a significantly older Nextcloud installation.
Relevant source behaviour
The investigation was performed against Nextcloud's OCA\Encryption\Crypto\Crypt implementation.
The important distinction appears to be the construction of the signature input for:
normal blocks
final blocks
legacy format
current format
The reproducibility above suggests that an older signature format was used when these files were written, but the current implementation does not recognize that format correctly.
Request
Could someone familiar with the encryption format confirm whether this is an expected legacy-format compatibility case or a regression?
In particular, I would like to establish:
Which historical Nextcloud/encryption-app version generated the legacy / legacy_end signature format.
Whether version 1 files using that format are expected to remain readable by current Nextcloud.
Whether the current implementation intentionally dropped support for this signature variant.
If not, whether the final-block handling should recognize the legacy ...end signature.
Whether existing files can be migrated/re-signed safely without decrypting and re-encrypting the entire file.
I can provide the complete forensic audit output, including per-block signatures, calculated values, block lengths, plaintext hashes, and the exact test scripts used to reproduce the behaviour
audit-test4.php
Steps to reproduce
Unsure how to repro as this has happened automatically without my doing, but I can provide the files and database entries that make decryption unsuccessful.
Expected behavior
files decrypt normally.
Nextcloud Server version
34
Operating system
Other
PHP engine version
PHP 8.3
Web server
Apache (supported)
Database engine version
MySQL
Is this bug present after an update or on a fresh install?
None
Are you using the Nextcloud Server Encryption module?
Encryption is Enabled
What user-backends are you using?
Configuration report
Nextcloud is in maintenance mode, only AppAPI commands are loaded.
Commands provided by other apps are unavailable.
{
"system": {
"instanceid": "***REMOVED SENSITIVE VALUE***",
"passwordsalt": "***REMOVED SENSITIVE VALUE***",
"secret": "***REMOVED SENSITIVE VALUE***",
"trusted_domains": [
***REMOVED SENSITIVE VALUE***"
],
"datadirectory": "***REMOVED SENSITIVE VALUE***",
"dbtype": "mysql",
"version": "34.0.3.2",
"overwrite.cli.url": "http:\/\/***REMOVED SENSITIVE VALUE***"",
"dbname": "***REMOVED SENSITIVE VALUE***",
"dbhost": "***REMOVED SENSITIVE VALUE***",
"dbport": "",
"dbtableprefix": "oc_",
"mysql.utf8mb4": true,
"dbuser": "***REMOVED SENSITIVE VALUE***",
"dbpassword": "***REMOVED SENSITIVE VALUE***",
"installed": true,
"tempdirectory": "\/www\/htdocs\/***REMOVED SENSITIVE VALUE***"_extra\/tmp",
"mail_smtpmode": "smtp",
"mail_sendmailmode": "smtp",
"mail_smtptimeout": 30,
"maintenance": true,
"theme": "",
"loglevel": 2,
"encryption.legacy_format_support": false,
"encryption.key_storage_migrated": false,
"encryption_skip_signature_check": false,
"mail_from_address": "***REMOVED SENSITIVE VALUE***",
"mail_domain": "***REMOVED SENSITIVE VALUE***",
"mail_smtpauth": 1,
"mail_smtphost": "***REMOVED SENSITIVE VALUE***",
"mail_smtpport": "587",
"mail_smtpname": "***REMOVED SENSITIVE VALUE***",
"mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
"mail_smtpsecure": "tls",
"default_phone_region": "DE",
"maintenance_window_start": 1,
"app_install_overwrite": []
}
}
List of activated Apps
Nextcloud is in maintenance mode, only AppAPI commands are loaded.
Commands provided by other apps are unavailable.
Enabled:
- activity: 7.0.0
- admin_audit: 1.24.0
- app_api: 34.0.0
- appstore: 1.0.0
- bruteforcesettings: 7.0.0
- circles: 34.0.0
- cloud_federation_api: 1.18.0
- comments: 1.24.0
- contactsinteraction: 1.15.0
- dav: 1.40.0
- encryption: 2.22.0
- federatedfilesharing: 1.24.0
- federation: 1.24.0
- files: 2.6.0
- files_accesscontrol: 5.0.0
- files_downloadlimit: 5.2.0
- files_lock: 34.0.1
- files_pdfviewer: 7.0.0-dev.0
- files_reminders: 1.7.0
- files_sharing: 1.26.0
- files_versions: 1.27.0
- firstrunwizard: 7.0.0-dev.0
- forms: 5.3.5
- logreader: 7.0.0
- lookup_server_connector: 1.22.0
- nextcloud_announcements: 6.0.0
- notifications: 7.0.0-dev.1
- oauth2: 1.22.0
- office: 1.0.0
- password_policy: 6.0.0-dev.0
- photos: 7.0.0
- privacy: 6.0.0-dev.1
- profile: 1.3.0
- provisioning_api: 1.24.0
- related_resources: 5.0.0-dev.0
- serverinfo: 6.0.0
- settings: 1.17.0
- sharebymail: 1.24.0
- support: 6.0.0
- survey_client: 6.0.0-dev.0
- suspicious_login: 12.0.0-dev.0
- systemtags: 1.24.0
- text: 8.0.0
- theming: 2.9.0
- twofactor_backupcodes: 1.23.0
- twofactor_totp: 16.0.0
- updatenotification: 1.24.0
- user_status: 1.14.0
- viewer: 7.0.0-dev.0
- weather_status: 1.14.0
- webhook_listeners: 1.6.0
- workflowengine: 2.16.0
Disabled:
- dashboard: 7.14.0 (installed 7.1.0)
- files_external: 1.26.0
- files_rightclick: 0.15.1 (installed 1.6.0)
- files_trackdownloads: 1.11.0 (installed 1.11.0)
- files_trashbin: 1.24.0 (installed 1.24.0)
- recommendations: 7.0.0 (installed 4.0.0)
- testing: 1.23.0
- twofactor_nextcloud_notification: 8.0.0
- user_ldap: 1.25.0
Nextcloud Signing status
No errors have been found.
Nextcloud Logs
{"reqId":"apuYjRlhhobM3WHNm_0scQAAxw4","level":3,"time":"2026-09-05T04:20:29+00:00","remoteAddr":"94.31.114.15","user":"user","app":"webdav","method":"GET","url":"/remote.php/dav/files/user/trading/onvista/025-agb.pdf","scriptName":"/remote.php","message":"Bad Signature","userAgent":"Mozilla/5.0 (iOS) Nextcloud-iOS/34.1.4","version":"34.0.3.2","exception":{"Exception":"OCP\\Encryption\\Exceptions\\GenericEncryptionException","Message":"Bad Signature","Code":0,"Trace":[{"file":"/www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Crypt.php","line":433,"function":"checkSignature","class":"OCA\\Encryption\\Crypto\\Crypt","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Encryption.php","line":324,"function":"symmetricDecryptFileContent","class":"OCA\\Encryption\\Crypto\\Crypt","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/www/htdocs/wxxxxxxxx/cloud/lib/private/Files/Stream/Encryption.php","line":470,"function":"decrypt","class":"OCA\\Encryption\\Crypto\\Encryption","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/www/htdocs/wxxxxxxxx/cloud/lib/private/Files/Stream/Encryption.php","line":265,"function":"readCache","class":"OC\\Files\\Stream\\Encryption","type":"->","args":[]},{"function":"stream_read","class":"OC\\Files\\Stream\\Encryption","type":"->","args":[6728]},{"file":"/www/htdocs/wxxxxxxxx/cloud/3rdparty/icewind/streams/src/Wrapper.php","line":54,"function":"fread","args":[null,8192]},{"file":"/www/htdocs/wxxxxxxxx/cloud/3rdparty/icewind/streams/src/CallbackWrapper.php","line":94,"function":"stream_read","class":"Icewind\\Streams\\Wrapper","type":"->","args":[8192]},{"function":"stream_read","class":"Icewind\\Streams\\CallbackWrapper","type":"->","args":[8192]},{"file":"/www/htdocs/wxxxxxxxx/cloud/3rdparty/sabre/http/lib/Sapi.php","line":108,"function":"stream_copy_to_stream","args":[null,null,530037]},{"file":"/www/htdocs/wxxxxxxxx/cloud/3rdparty/sabre/dav/lib/DAV/Server.php","line":490,"function":"sendResponse","class":"Sabre\\HTTP\\Sapi","type":"::","args":[{"__class__":"Sabre\\HTTP\\Response"}]},{"file":"/www/htdocs/wxxxxxxxx/cloud/apps/dav/lib/Connector/Sabre/Server.php","line":215,"function":"invokeMethod","class":"Sabre\\DAV\\Server","type":"->","args":[{"__class__":"Sabre\\HTTP\\Request"},{"__class__":"Sabre\\HTTP\\Response"}]},{"file":"/www/htdocs/wxxxxxxxx/cloud/apps/dav/lib/Server.php","line":433,"function":"start","class":"OCA\\DAV\\Connector\\Sabre\\Server","type":"->","args":[]},{"file":"/www/htdocs/wxxxxxxxx/cloud/apps/dav/appinfo/v2/remote.php","line":25,"function":"exec","class":"OCA\\DAV\\Server","type":"->","args":[]},{"file":"/www/htdocs/wxxxxxxxx/cloud/remote.php","line":152,"args":["/www/htdocs/wxxxxxxxx/cloud/apps/dav/appinfo/v2/remote.php"],"function":"require_once"}],"File":"/www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Crypt.php","Line":457,"Hint":"Bad Signature","message":"Bad Signature","exception":"{\"class\":\"OCP\\Encryption\\Exceptions\\GenericEncryptionException\",\"message\":\"Bad Signature\",\"code\":0,\"file\":\"/www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Crypt.php:457\",\"trace\":\"#0 /www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Crypt.php(433): OCA\\Encryption\\Crypto\\Crypt->checkSignature('phtgkvtFdMDcExF...', '\\x89\\xF4\\nPl\\xDC\\xA2\\x88\\xD80E\\xD7;\\x95z...', '459984b3925e06f...')\\n#1 /www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Encryption.php(324): OCA\\Encryption\\Crypto\\Crypt->symmetricDecryptFileContent('phtgkvtFdMDcExF...', '\\x89\\xF4\\nPl\\xDC\\xA2\\x88\\xD80E\\xD7;\\x95z...', 'AES-256-CTR', 1, 65, false)\\n#2 /www/htdocs/wxxxxxxxx/cloud/lib/private/Files/Stream/Encryption.php(470): OCA\\Encryption\\Crypto\\Encryption->decrypt('phtgkvtFdMDcExF...', 65)\\n#3 /www/htdocs/wxxxxxxxx/cloud/lib/private/Files/Stream/Encryption.php(265): OC\\Files\\Stream\\Encryption->readCache()\\n#4 [internal function]: OC\\Files\\Stream\\Encryption->stream_read(6728)\\n#5 /www/htdocs/wxxxxxxxx/cloud/3rdparty/icewind/streams/src/Wrapper.php(54): fread(Resource id #1148, 8192)\\n#6 /www/htdocs/wxxxxxxxx/cloud/3rdparty/icewind/streams/src/CallbackWrapper.php(94): Icewind\\Streams\\Wrapper->stream_read(8192)\\n#7 [internal function]: Icewind\\Streams\\CallbackWrapper->stream_read(8192)\\n#8 /www/htdocs/wxxxxxxxx/cloud/3rdparty/sabre/http/lib/Sapi.php(108): stream_copy_to_stream(Resource id #1152, Resource id #1159, 530037)\\n#9 /www/htdocs/wxxxxxxxx/cloud/3rdparty/sabre/dav/lib/DAV/Server.php(490): Sabre\\HTTP\\Sapi::sendResponse(Object(Sabre\\HTTP\\Response))\\n#10 /www/htdocs/wxxxxxxxx/cloud/apps/dav/lib/Connector/Sabre/Server.php(215): Sabre\\DAV\\Server->invokeMethod(Object(Sabre\\HTTP\\Request), Object(Sabre\\HTTP\\Response))\\n#11 /www/htdocs/wxxxxxxxx/cloud/apps/dav/lib/Server.php(433): OCA\\DAV\\Connector\\Sabre\\Server->start()\\n#12 /www/htdocs/wxxxxxxxx/cloud/apps/dav/appinfo/v2/remote.php(25): OCA\\DAV\\Server->exec()\\n#13 /www/htdocs/wxxxxxxxx/cloud/remote.php(152): require_once('/www/htdocs/w00...')\\n#14 {main}\"}","CustomMessage":"Bad Signature"}}
Additional info
No response
Bug description
Alright, time to possibly give something back to the community.
How this came to be: I have by accident identified a few files that would not download from my nextcloud, log said "Bad Signature". So I went looking and found a huge number of files that had this issue. Needless to say that my backups do not go far enough for "correct" files so I needed to dig in.
My Nextcloud instance is at least 10 major versions old, so it was always upgraded along the way.
I have encountered an apparent backwards-compatibility issue in Nextcloud's encryption handling of older AES-256-CTR encrypted files.
The files are fully decryptable and structurally intact, but current Nextcloud rejects the final block with Bad Signature.
For the affected files:
Encryption version: 1
Cipher: AES-256-CTR
Encoding: legacy Base64
Header: signed:true
Every physical block decrypts successfully.
Blocks before the final block have signatures matching the legacy signature calculation.
The final block has a signature matching legacy + end.
The current signature calculation does not match the stored signatures.
The failure therefore appears deterministic and related to the legacy block-signature format/position handling rather than damaged ciphertext.
The files were originally encrypted years ago and have subsequently been accessed through newer Nextcloud versions. I do not know the exact Nextcloud version that originally created them.
Reproduction
One affected file:
/user/files/trading/onvista/025-agb.pdfPhysical encrypted file:
545832 bytes
Encrypted data after the 8192-byte header:
537640 bytes
Physical blocks:
66
Nextcloud file version:
1
Cipher:
AES-256-CTR
Header:
HBEGIN:oc_encryption_module:OC_DEFAULT_MODULE:cipher:AES-256-CTR:signed:true:HEND
The corresponding 32-byte file key is:
89f40a506cdca288d83045d73b957a4073ac9cb7cc1e95d06006bbe1f388bac4
Key SHA-256:
cd1eb792f1922ae9542337ad340f418b58e9c7691287766a55ff6d377eaeead5
The key is included here solely to make this particular encrypted test file reproducible. It is a file-specific encryption key, not a server/master secret.
Observed signature behaviour
For blocks 0–64:
stored signature == legacy calculation
stored signature != current calculation
stored signature != legacy + end calculation
For final block 65:
stored signature == legacy + end calculation
stored signature != current calculation
stored signature != current + end calculation
stored signature != legacy calculation
Example, block 65:
Stored:
459984b3925e06f951c137c022e1e8c6595e10c417453e754890dde4d099accf
Current:
4b6a1588ac4e20c394589fb9e3203ff14eef68bd487e134b654dbb91eb84c870
Current + end:
3b8b7606ad056f9ab527b2897c4ebfd0d46061888d2e495c6856daed0ffc5daa
Legacy:
0b111673b7f4a6f4df03afe77cf45c7cdf330315e3854664d692383a604404d0
Legacy + end:
459984b3925e06f951c137c022e1e8c6595e10c417453e754890dde4d099accf
This is an exact match for legacy_end.
Decryption result
All 66 physical blocks decrypt successfully using the file key and AES-256-CTR:
Blocks: 66
Current signature OK: 0
Current signature BAD: 66
Legacy signature OK: 65
Legacy+end signature OK: 1
Decrypt OK: 66
Decrypt FAILED: 0
Plaintext recovered: 398477 bytes
The recovered plaintext size is exactly the expected file size from Nextcloud's file metadata:
398477 bytes
The recovered PDF is structurally valid and opens correctly.
Second/third affected files
This is not isolated to one file.
ZIP
/user/files/Homeday_immocation_Preisatlas.zipFile key SHA-256:
5679a7d008ab95702e1f23f23d4b9664c4bbd46d89f95e86a81aa2cffdd0b6ee
Version: 1
Cipher: AES-256-CTR
Blocks: 552
Legacy signatures:
551 OK
Legacy+end:
1 OK
Current signatures:
0 OK
552 BAD
Decrypt:
552/552 OK
The recovered ZIP passes ZipArchive validation and contains 8 entries.
JPEG
/user/files/AT6/2017_06_10/2017.06.10-10.06.21-iPhone SE-IMG_9874.JPGFile key SHA-256:
674d4b5ca5c391ddcb16b24162d4642e01be765073eecf2f3e2759d3bf621f10
Version: 1
Cipher: AES-256-CTR
Blocks: 487
Legacy signatures:
486 OK
Legacy+end:
1 OK
Current signatures:
0 OK
487 BAD
Decrypt:
487/487 OK
The recovered JPEG is also valid.
Why I think this is a compatibility issue
The important observation is the consistency across unrelated files:
normal blocks -> legacy signature
final block -> legacy + "end" signature
while the current Nextcloud implementation expects a different signature calculation.
This occurs regardless of whether the file is a PDF, ZIP, or JPEG.
The encrypted data itself appears intact because every block decrypts successfully and the recovered plaintext has the expected size/content.
This makes random corruption of the final block unlikely.
It also appears unlikely that the problem is simply an incorrect file key: the legacy signatures reproduce exactly for the blocks.
Potential impact
This could affect files encrypted with an older version of the encryption app and subsequently accessed/decrypted after an encryption-format/signature implementation change.
In my case, Nextcloud's normal decryption fails with:
OCP\Encryption\Exceptions\GenericEncryptionException
Bad Signature
and stops at the final block.
With signature verification bypassed, Nextcloud's own Crypt::symmetricDecryptFileContent() successfully decrypts every block.
Therefore the underlying encrypted data remains recoverable, but normal Nextcloud decryption fails.
Environment
Current Nextcloud installation:
php occ status
Encryption app version:
PHP version:
8.3.29
OpenSSL version:
OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)
Original encryption/Nextcloud version:
Unknown; files may originate from a significantly older Nextcloud installation.
Relevant source behaviour
The investigation was performed against Nextcloud's OCA\Encryption\Crypto\Crypt implementation.
The important distinction appears to be the construction of the signature input for:
normal blocks
final blocks
legacy format
current format
The reproducibility above suggests that an older signature format was used when these files were written, but the current implementation does not recognize that format correctly.
Request
Could someone familiar with the encryption format confirm whether this is an expected legacy-format compatibility case or a regression?
In particular, I would like to establish:
Which historical Nextcloud/encryption-app version generated the legacy / legacy_end signature format.
Whether version 1 files using that format are expected to remain readable by current Nextcloud.
Whether the current implementation intentionally dropped support for this signature variant.
If not, whether the final-block handling should recognize the legacy ...end signature.
Whether existing files can be migrated/re-signed safely without decrypting and re-encrypting the entire file.
I can provide the complete forensic audit output, including per-block signatures, calculated values, block lengths, plaintext hashes, and the exact test scripts used to reproduce the behaviour
audit-test4.php
Steps to reproduce
Unsure how to repro as this has happened automatically without my doing, but I can provide the files and database entries that make decryption unsuccessful.
Expected behavior
files decrypt normally.
Nextcloud Server version
34
Operating system
Other
PHP engine version
PHP 8.3
Web server
Apache (supported)
Database engine version
MySQL
Is this bug present after an update or on a fresh install?
None
Are you using the Nextcloud Server Encryption module?
Encryption is Enabled
What user-backends are you using?
Configuration report
List of activated Apps
Nextcloud is in maintenance mode, only AppAPI commands are loaded. Commands provided by other apps are unavailable. Enabled: - activity: 7.0.0 - admin_audit: 1.24.0 - app_api: 34.0.0 - appstore: 1.0.0 - bruteforcesettings: 7.0.0 - circles: 34.0.0 - cloud_federation_api: 1.18.0 - comments: 1.24.0 - contactsinteraction: 1.15.0 - dav: 1.40.0 - encryption: 2.22.0 - federatedfilesharing: 1.24.0 - federation: 1.24.0 - files: 2.6.0 - files_accesscontrol: 5.0.0 - files_downloadlimit: 5.2.0 - files_lock: 34.0.1 - files_pdfviewer: 7.0.0-dev.0 - files_reminders: 1.7.0 - files_sharing: 1.26.0 - files_versions: 1.27.0 - firstrunwizard: 7.0.0-dev.0 - forms: 5.3.5 - logreader: 7.0.0 - lookup_server_connector: 1.22.0 - nextcloud_announcements: 6.0.0 - notifications: 7.0.0-dev.1 - oauth2: 1.22.0 - office: 1.0.0 - password_policy: 6.0.0-dev.0 - photos: 7.0.0 - privacy: 6.0.0-dev.1 - profile: 1.3.0 - provisioning_api: 1.24.0 - related_resources: 5.0.0-dev.0 - serverinfo: 6.0.0 - settings: 1.17.0 - sharebymail: 1.24.0 - support: 6.0.0 - survey_client: 6.0.0-dev.0 - suspicious_login: 12.0.0-dev.0 - systemtags: 1.24.0 - text: 8.0.0 - theming: 2.9.0 - twofactor_backupcodes: 1.23.0 - twofactor_totp: 16.0.0 - updatenotification: 1.24.0 - user_status: 1.14.0 - viewer: 7.0.0-dev.0 - weather_status: 1.14.0 - webhook_listeners: 1.6.0 - workflowengine: 2.16.0 Disabled: - dashboard: 7.14.0 (installed 7.1.0) - files_external: 1.26.0 - files_rightclick: 0.15.1 (installed 1.6.0) - files_trackdownloads: 1.11.0 (installed 1.11.0) - files_trashbin: 1.24.0 (installed 1.24.0) - recommendations: 7.0.0 (installed 4.0.0) - testing: 1.23.0 - twofactor_nextcloud_notification: 8.0.0 - user_ldap: 1.25.0Nextcloud Signing status
Nextcloud Logs
{"reqId":"apuYjRlhhobM3WHNm_0scQAAxw4","level":3,"time":"2026-09-05T04:20:29+00:00","remoteAddr":"94.31.114.15","user":"user","app":"webdav","method":"GET","url":"/remote.php/dav/files/user/trading/onvista/025-agb.pdf","scriptName":"/remote.php","message":"Bad Signature","userAgent":"Mozilla/5.0 (iOS) Nextcloud-iOS/34.1.4","version":"34.0.3.2","exception":{"Exception":"OCP\\Encryption\\Exceptions\\GenericEncryptionException","Message":"Bad Signature","Code":0,"Trace":[{"file":"/www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Crypt.php","line":433,"function":"checkSignature","class":"OCA\\Encryption\\Crypto\\Crypt","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Encryption.php","line":324,"function":"symmetricDecryptFileContent","class":"OCA\\Encryption\\Crypto\\Crypt","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/www/htdocs/wxxxxxxxx/cloud/lib/private/Files/Stream/Encryption.php","line":470,"function":"decrypt","class":"OCA\\Encryption\\Crypto\\Encryption","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/www/htdocs/wxxxxxxxx/cloud/lib/private/Files/Stream/Encryption.php","line":265,"function":"readCache","class":"OC\\Files\\Stream\\Encryption","type":"->","args":[]},{"function":"stream_read","class":"OC\\Files\\Stream\\Encryption","type":"->","args":[6728]},{"file":"/www/htdocs/wxxxxxxxx/cloud/3rdparty/icewind/streams/src/Wrapper.php","line":54,"function":"fread","args":[null,8192]},{"file":"/www/htdocs/wxxxxxxxx/cloud/3rdparty/icewind/streams/src/CallbackWrapper.php","line":94,"function":"stream_read","class":"Icewind\\Streams\\Wrapper","type":"->","args":[8192]},{"function":"stream_read","class":"Icewind\\Streams\\CallbackWrapper","type":"->","args":[8192]},{"file":"/www/htdocs/wxxxxxxxx/cloud/3rdparty/sabre/http/lib/Sapi.php","line":108,"function":"stream_copy_to_stream","args":[null,null,530037]},{"file":"/www/htdocs/wxxxxxxxx/cloud/3rdparty/sabre/dav/lib/DAV/Server.php","line":490,"function":"sendResponse","class":"Sabre\\HTTP\\Sapi","type":"::","args":[{"__class__":"Sabre\\HTTP\\Response"}]},{"file":"/www/htdocs/wxxxxxxxx/cloud/apps/dav/lib/Connector/Sabre/Server.php","line":215,"function":"invokeMethod","class":"Sabre\\DAV\\Server","type":"->","args":[{"__class__":"Sabre\\HTTP\\Request"},{"__class__":"Sabre\\HTTP\\Response"}]},{"file":"/www/htdocs/wxxxxxxxx/cloud/apps/dav/lib/Server.php","line":433,"function":"start","class":"OCA\\DAV\\Connector\\Sabre\\Server","type":"->","args":[]},{"file":"/www/htdocs/wxxxxxxxx/cloud/apps/dav/appinfo/v2/remote.php","line":25,"function":"exec","class":"OCA\\DAV\\Server","type":"->","args":[]},{"file":"/www/htdocs/wxxxxxxxx/cloud/remote.php","line":152,"args":["/www/htdocs/wxxxxxxxx/cloud/apps/dav/appinfo/v2/remote.php"],"function":"require_once"}],"File":"/www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Crypt.php","Line":457,"Hint":"Bad Signature","message":"Bad Signature","exception":"{\"class\":\"OCP\\Encryption\\Exceptions\\GenericEncryptionException\",\"message\":\"Bad Signature\",\"code\":0,\"file\":\"/www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Crypt.php:457\",\"trace\":\"#0 /www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Crypt.php(433): OCA\\Encryption\\Crypto\\Crypt->checkSignature('phtgkvtFdMDcExF...', '\\x89\\xF4\\nPl\\xDC\\xA2\\x88\\xD80E\\xD7;\\x95z...', '459984b3925e06f...')\\n#1 /www/htdocs/wxxxxxxxx/cloud/apps/encryption/lib/Crypto/Encryption.php(324): OCA\\Encryption\\Crypto\\Crypt->symmetricDecryptFileContent('phtgkvtFdMDcExF...', '\\x89\\xF4\\nPl\\xDC\\xA2\\x88\\xD80E\\xD7;\\x95z...', 'AES-256-CTR', 1, 65, false)\\n#2 /www/htdocs/wxxxxxxxx/cloud/lib/private/Files/Stream/Encryption.php(470): OCA\\Encryption\\Crypto\\Encryption->decrypt('phtgkvtFdMDcExF...', 65)\\n#3 /www/htdocs/wxxxxxxxx/cloud/lib/private/Files/Stream/Encryption.php(265): OC\\Files\\Stream\\Encryption->readCache()\\n#4 [internal function]: OC\\Files\\Stream\\Encryption->stream_read(6728)\\n#5 /www/htdocs/wxxxxxxxx/cloud/3rdparty/icewind/streams/src/Wrapper.php(54): fread(Resource id #1148, 8192)\\n#6 /www/htdocs/wxxxxxxxx/cloud/3rdparty/icewind/streams/src/CallbackWrapper.php(94): Icewind\\Streams\\Wrapper->stream_read(8192)\\n#7 [internal function]: Icewind\\Streams\\CallbackWrapper->stream_read(8192)\\n#8 /www/htdocs/wxxxxxxxx/cloud/3rdparty/sabre/http/lib/Sapi.php(108): stream_copy_to_stream(Resource id #1152, Resource id #1159, 530037)\\n#9 /www/htdocs/wxxxxxxxx/cloud/3rdparty/sabre/dav/lib/DAV/Server.php(490): Sabre\\HTTP\\Sapi::sendResponse(Object(Sabre\\HTTP\\Response))\\n#10 /www/htdocs/wxxxxxxxx/cloud/apps/dav/lib/Connector/Sabre/Server.php(215): Sabre\\DAV\\Server->invokeMethod(Object(Sabre\\HTTP\\Request), Object(Sabre\\HTTP\\Response))\\n#11 /www/htdocs/wxxxxxxxx/cloud/apps/dav/lib/Server.php(433): OCA\\DAV\\Connector\\Sabre\\Server->start()\\n#12 /www/htdocs/wxxxxxxxx/cloud/apps/dav/appinfo/v2/remote.php(25): OCA\\DAV\\Server->exec()\\n#13 /www/htdocs/wxxxxxxxx/cloud/remote.php(152): require_once('/www/htdocs/w00...')\\n#14 {main}\"}","CustomMessage":"Bad Signature"}}Additional info
No response