In order to verify the signature of a ROM ZIP file on a PC, two things are required:
- The public key from the ROM creator (can be extracted from
/system/etc/security/otacerts.zip if the creator is the same e.g. in case of updating stock ROM).
- A tool to extract the certificate from the comment (footer) of the ZIP file and verify its signature key against the ROM developer's public key.
There are multiple tools available to perform the second step, including the one officially provided by LineageOS:
update_verifier.py <pubkey> /path/to/zip_file
I had a vague notion that custom ROM ZIP files contain the standard JAR signatures block (which is also the case with APK signature scheme v1). So the standard
jarsigner -verify command could be used to verify the integrity of a self-signed JAR/ZIP file (that it hasn't been tempered with since created), though not the authenticity of the source (which requires the root certificate, as is the case with AVB).
But a deeper look into TWRP source code indicates that it's using the same signature verification mechanism used in stock recovery for OTA ZIP file verification (source code here) i.e. verifying the authority of the ZIP file's creator against prebuilt public keys stored in
signapk.jar is used at the time of compilation to sign both APKs (apksigner is called) and OTA ZIP files. The same tool adds the "signed by SignApk" message you noticed in ZIP file.
/res/keys/ directory in recovery must contain the public keys from all ROM creators in order to verify their ZIP files, which doesn't seem practical. Stock recovery contains only OEM's public key(s) while custom recovery most probably contains test keys from the official SDK. And that's why we often face the infamous "ZIP signature verification failed" message for ROMs and other flashable ZIP files.
On non-A/B devices the OTA package (if not manually downloaded by the user) is also verified before booting to recovery mode. In this case prebuilt keys from
otacerts.zip are used for verification (source code here). But with A/B updates recovery is not involved at all (
/res/keys/ no more exists since Android 10) and package might not be verified even once (if doing "streaming updates", some more details in this answer).
So keeping these points in view, the verification mechanism used in recovery doesn't seem to be of much importance. In order to verify the authenticity of a ROM, better would be to simply do a checksum verification of the downloaded file if possible, like LineageOS provides SHA256 hashes with their downloadable ZIP files.