How can I dump the signature of an Android App Bundle? - jarsigner

I'm switching my CI process from producing APK files to App Bundles. One stage in my pipeline will, after producing the signed binary, dump the signature and validate the signature on the APK to make sure it's signed properly before continuing.
> apksigner verify --print-certs my-signed-binary.apk
Signer #1 certificate DN: CN=<NAME>, OU=<GROUP>, O=<COMPANY>, L=<CITY>, ST=<STATE>, C=<COUNTRY>
Signer #1 certificate SHA-256 digest: <DIGEST1>
Signer #1 certificate SHA-1 digest: <DIGEST2>
Signer #1 certificate MD5 digest: <DIGEST3>
Is there an equivalent to dump the signature on the overall App Bundle once it's been produced?
I tried using jarsigner, but ended up with hundreds of lines of output.
> jarsigner -verbose -verify -certs my-signed-binary.aab
...
smk 12 Wed Dec 31 16:00:00 PST 1969 base/assets.pb
>>> Signer
X.509, CN=<NAME>, OU=<GROUP>, O=<ORGANIZATION>, L=<CITY>, ST=<STATE>, C=<COUNTRY> (myapp)
[certificate is valid from 5/31/13 1:27 PM to 10/16/40 1:27 PM]
smk 85 Wed Dec 31 16:00:00 PST 1969 base/native.pb
>>> Signer
X.509, CN=<NAME>, OU=<GROUP>, O=<ORGANIZATION>, L=<CITY>, ST=<STATE>, C=<COUNTRY> (myapp)
[certificate is valid from 5/31/13 1:27 PM to 10/16/40 1:27 PM]
smk 2075002 Wed Dec 31 16:00:00 PST 1969 base/resources.pb
>>> Signer
X.509, CN=<NAME>, OU=<GROUP>, O=<ORGANIZATION>, L=<CITY>, ST=<STATE>, C=<COUNTRY> (myapp)
[certificate is valid from 5/31/13 1:27 PM to 10/16/40 1:27 PM]
542451 Tue Jan 01 00:00:00 PST 1980 META-INF/MYAPP.SF
1390 Tue Jan 01 00:00:00 PST 1980 META-INF/MYAPP.RSA
s k 542352 Tue Jan 01 00:00:00 PST 1980 META-INF/MANIFEST.MF
>>> Signer
X.509, CN=<NAME>, OU=<GROUP>, O=<ORGANIZATION>, L=<CITY>, ST=<STATE>, C=<COUNTRY> (myapp)
[certificate is valid from 5/31/13 1:27 PM to 10/16/40 1:27 PM]
s = signature was verified
m = entry is listed in manifest
k = at least one certificate was found in keystore
i = at least one certificate was found in identity scope
- Signed by "CN=<NAME>, OU=<GROUP>, O=<ORGANIZATION>, L=<CITY>, ST=<STATE>, C=<COUNTRY>"
Digest algorithm: SHA-256
Signature algorithm: SHA256withRSA, 2048-bit key
jar verified.
Is the very last part of this ("Signed by...") the signature of the overall App Bundle? Is there an easier way to get the signature of the App Bundle than hacking this output with sed?

I used keytool and I think it produces correct results
keytool -printcert -jarfile my-signed-binary.aab

Related

What does CN stand for in a mobile app apk signature information?

In https://learn.microsoft.com/en-us/xamarin/android/deploy-test/signing/keystore-signature?tabs=windows, it gives an example of the signature information:
Alias name: androiddebugkey
Creation date: Aug 19, 2014
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Android Debug, O=Android, C=US
Issuer: CN=Android Debug, O=Android, C=US
Serial number: 53f3b126
Valid from: Tue Aug 19 13:18:46 PDT 2014 until: Sun Nov 15 12:18:46 PST 2043
Certificate fingerprints:
MD5: 27:78:7C:31:64:C2:79:C6:ED:E5:80:51:33:9C:03:57
SHA1: 00:E5:8B:DA:29:49:9D:FC:1D:DA:E7:EE:EE:1A:8A:C7:85:E7:31:23
SHA256: 21:0D:73:90:1D:D6:3D:AB:4C:80:4E:C4:A9:CB:97:FF:34:DD:B4:42:FC:
08:13:E0:49:51:65:A6:7C:7C:90:45
Signature algorithm name: SHA1withRSA
Version: 3
Regarding "Owner: CN=Android Debug, O=Android, C=US", O may stand for organisation, and C may stand for country.
What does CN stand for?
"CN" stands for "Common Name".
See https://docs.oracle.com/cd/E24191_01/common/tutorials/authz_cert_attributes.html for the list of all attributes of the certificate.
In Android, the CN does not have any particular significance so you can put whatever string you want, but if that certificate is used for SSL, there are some requirements: https://www.ssl.com/faqs/common-name/

Unable to validate client certificate with Akka HTTP server (Play Framework)

I am trying to set up an HTTPS server with client certificate authentication using the Play Framework (2.7). But the client authentication always fails with unable to find valid certification path to requested target.
The client certificate is signed by a custom certificate authority that uses a self-signed certificate. In my setup, this custom CA is the only CA that the server should trust.
In application.conf I added the following configuration to set up the HTTPS server and to replace the default trust store with the custom CA certificate.
play {
server {
https {
keyStore {
path = "/path/to/store",
password = "password",
type = "PKCS12"
}
needClientAuth = true
}
}
}
ssl-config {
trustManager = {
stores = [
{ type = "PEM", path = "path/to/ca/certificate" }
]
}
}
With debug enabled, when the application is initializing, I see the custom CA certificate is loaded :
adding as trusted cert:
Subject: EMAILADDRESS=ca#mydomain.com, CN=CustAuth, O=MyOrg, L=City, ST=12345, C=FR
Issuer: EMAILADDRESS=ca#mydomain.com, CN=CustAuth, O=MyOrg, L=City, ST=12345, C=FR
Valid from Wed Jul 06 15:38:40 CEST 2005 until Tue Jul 01 15:38:40 CEST 2025
However, I also see the following lines a little further in the logs :
trustStore is: /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts
trustStore type is : jks
trustStore provider is :
init truststore
I did not expect nor want the server to use the default JRE trust store. How can I completely disable it ?
Anyway, that should not stop the server to authenticate correctly the client - unless the trust store gets completely overridden (I hope that is not the case but I haven't proven it so far).
When the client connects, I see in the logs that its certificate is correctly read :
chain [0] = [
Subject: EMAILADDRESS=devnull#mydomain.com, CN=My User, OU="User#41183", O=MyOrg, C=FR
Validity: [From: Thu Jan 11 10:17:12 CET 2018, To: Tue Jan 10 10:17:12 CET 2023]
Issuer: EMAILADDRESS=ca#mydomain.com, CN=CustAuth, O=MyOrg, L=City, ST=12345, C=FR
]
chain [1] = [
Subject: EMAILADDRESS=ca#mydomain.com, CN=CustAuth, O=MyOrg, L=City, ST=12345, C=FR
Validity: [From: Wed Jul 06 15:38:40 CEST 2005, To: Tue Jul 01 15:38:40 CEST 2025]
Issuer: EMAILADDRESS=ca#mydomain.com, CN=CustAuth, O=MyOrg, L=City, ST=12345, C=FR
]
The client issuer matches the previously loaded custom CA certificate. However, the following error is thrown :
application-akka.actor.default-dispatcher-2, fatal error: 46: General SSLEngine problem
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
What do I miss or what am I doing wrong ?
Edit : I noticed that if I import the custom CA certificate into the default trust store, the authentication is working.
Edit 2 : seems to be linked to the default implementation of the SSL engine provider :
2019-04-08 13:21:46 +0200 [DEBUG] from play.core.server.ssl.DefaultSSLEngineProvider in application-akka.actor.default-dispatcher-3 - Using default trust store for client side CA verification
Custom SSL engine provider must be set, see docs since DefaultSSLEngineProvider supports only play.server.https.trustStore.noCaVerification = (true|false) and fallback to default JVM trust store.
Don't be confused with some log messages and better debug the app. Your CA is loaded but to other SSL context than you need.
I had slightly different problem and ended up with overriding JVM cacerts because Play config does not provide me configuration I need.

CodeSigning results in 'Code Integrity completed validating page hashes. Status 0xc0000428.'

I have been attemping to code sign a dll using a code signing certiticate I have purchased from Comodo. The intention for the signing is to be verifiable via the kernel signing policy. However, in the the EventLog explaining that there are CodeIntegrity errors relating to per-page image hashes not being able to be found.
Below is a summary I what I am doing, if you could please provide advice on where I have gone wrong, or where to look next that would be greatly appreciated.
I have signed a previously signed dll for the sake of testing using the following commands, the result is the same if I used a newly built dll.
"C:\WinDDK\7600.16385.1\bin\amd64\SignTool.exe" sign /v /ph /ac "addtrustexternalcaroot_kmod.crt" /f css-certificate.pfx /p <password> /t http://timestamp.verisign.com/scripts/timstamp.dll VBoxVRDP.dll
The output is as follows
The following certificate was selected:
Issued to: S4 Technology
Issued by: COMODO RSA Code Signing CA
Expires: Wed Nov 11 15:59:59 2015
SHA1 hash: 0161DC2D8757B886E626B25B1770C72B789BAF02
Cross certificate chain (using machine store):
Issued to: Microsoft Code Verification Root
Issued by: Microsoft Code Verification Root
Expires: Sat Nov 01 05:54:03 2025
SHA1 hash: 8FBE4D070EF8AB1BCCAF2A9D5CCAE7282A2C66B3
Issued to: AddTrust External CA Root
Issued by: Microsoft Code Verification Root
Expires: Tue Aug 15 12:36:30 2023
SHA1 hash: A75AC657AA7A4CDFE5F9DE393E69EFCAB659D250
Issued to: COMODO RSA Certification Authority
Issued by: AddTrust External CA Root
Expires: Sat May 30 02:48:38 2020
SHA1 hash: F5AD0BCC1AD56CD150725B1C866C30AD92EF21B0
Issued to: COMODO RSA Code Signing CA
Issued by: COMODO RSA Certification Authority
Expires: Mon May 08 15:59:59 2028
SHA1 hash: B69E752BBE88B4458200A7C0F4F5B3CCE6F35B47
Issued to: S4 Technology
Issued by: COMODO RSA Code Signing CA
Expires: Wed Nov 11 15:59:59 2015
SHA1 hash: 0161DC2D8757B886E626B25B1770C72B789BAF02
Done Adding Additional Store
Successfully signed and timestamped: VBoxVRDP.dll
Number of files successfully Signed: 1
Number of warnings: 0
Number of errors: 0
I now validate the signing using the following command
"C:\WinDDK\7600.16385.1\bin\amd64\SignTool.exe" verify /v /ph /kp VBoxVRDP.dll
The output is as follows
Verifying: VBoxVRDP.dll
Hash of file (sha1): 41909BD87A05CF3E61BBEF7B9DD4C4A8B6E4B2A1
Signing Certificate Chain:
Issued to: AddTrust External CA Root
Issued by: AddTrust External CA Root
Expires: Sat May 30 02:48:38 2020
SHA1 hash: 02FAF3E291435468607857694DF5E45B68851868
Issued to: COMODO RSA Certification Authority
Issued by: AddTrust External CA Root
Expires: Sat May 30 02:48:38 2020
SHA1 hash: F5AD0BCC1AD56CD150725B1C866C30AD92EF21B0
Issued to: COMODO RSA Code Signing CA
Issued by: COMODO RSA Certification Authority
Expires: Mon May 08 15:59:59 2028
SHA1 hash: B69E752BBE88B4458200A7C0F4F5B3CCE6F35B47
Issued to: S4 Technology
Issued by: COMODO RSA Code Signing CA
Expires: Wed Nov 11 15:59:59 2015
SHA1 hash: 0161DC2D8757B886E626B25B1770C72B789BAF02
The signature is timestamped: Mon Dec 15 10:05:37 2014
Timestamp Verified by:
Issued to: Thawte Timestamping CA
Issued by: Thawte Timestamping CA
Expires: Thu Dec 31 15:59:59 2020
SHA1 hash: BE36A4562FB2EE05DBB3D32323ADF445084ED656
Issued to: Symantec Time Stamping Services CA - G2
Issued by: Thawte Timestamping CA
Expires: Wed Dec 30 15:59:59 2020
SHA1 hash: 6C07453FFDDA08B83707C09B82FB3D15F35336B1
Issued to: Symantec Time Stamping Services Signer - G4
Issued by: Symantec Time Stamping Services CA - G2
Expires: Tue Dec 29 15:59:59 2020
SHA1 hash: 65439929B67973EB192D6FF243E6767ADF0834E4
Cross Certificate Chain:
Issued to: Microsoft Code Verification Root
Issued by: Microsoft Code Verification Root
Expires: Sat Nov 01 05:54:03 2025
SHA1 hash: 8FBE4D070EF8AB1BCCAF2A9D5CCAE7282A2C66B3
Issued to: AddTrust External CA Root
Issued by: Microsoft Code Verification Root
Expires: Tue Aug 15 12:36:30 2023
SHA1 hash: A75AC657AA7A4CDFE5F9DE393E69EFCAB659D250
Issued to: COMODO RSA Certification Authority
Issued by: AddTrust External CA Root
Expires: Sat May 30 02:48:38 2020
SHA1 hash: F5AD0BCC1AD56CD150725B1C866C30AD92EF21B0
Issued to: COMODO RSA Code Signing CA
Issued by: COMODO RSA Certification Authority
Expires: Mon May 08 15:59:59 2028
SHA1 hash: B69E752BBE88B4458200A7C0F4F5B3CCE6F35B47
Issued to: S4 Technology
Issued by: COMODO RSA Code Signing CA
Expires: Wed Nov 11 15:59:59 2015
SHA1 hash: 0161DC2D8757B886E626B25B1770C72B789BAF02
Embedded page hashes:
0x00000000 7B54C3ABC3FC7DA85CB40074D653DFB36DF8E0F9
<...>
0x00071a00 0000000000000000000000000000000000000000
Successfully verified: VBoxVRDP.dll
Number of files successfully Verified: 1
Number of warnings: 0
Number of errors: 0
So it all looks good, however, I have noted when looking at the properties of dll via Explorer, but I end up with a CodeIntegrity errors in the EventLog.
Code Integrity is unable to verify the image integrity of the file <...>\VBoxVRDP.dll because the set of per-page image hashes could not be found on the system.
When I look at the Verbose logs of CodeIntegrity I see the following Verbose events
Code Integrity started validating page hashes of <...>\VBoxVRDP.dll file.
Code Integrity completed validating page hashes. Status 0xc0000428.
From what I can tell 0xc0000428 is Windows cannot verify the digital signature of this file, which seems to imply I am missing something somewhere, but I for the life of me cannot figure out exactly what it is I need to do.
Windows support for SHA2 on Win 7 seems to be problematic at present. https://technet.microsoft.com/en-us/library/security/2949927.aspx
There is a fix but note "Revision V2.0 (October 17, 2014): Removed Download Center links for Microsoft security update 2949927. Microsoft recommends that customers experiencing issues uninstall this update. Microsoft is investigating behavior associated with this update, and will update the advisory when more information becomes available."

keytool -list shows different aliases for p12 keystore, depending on whether you provide the password

Really weird behaviour on a particular p12 file.
If I run
keytool -list -storetype pkcs12 -keystore my_debug_keystore.p12 -storepass debug
keytool -v -list -storetype pkcs12 -keystore my_debug_keystore.p12 -storepass debug
I get,
Alias name: 1
Creation date: Aug 17, 2014
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=sixminute, OU=, O=, C=IE
Issuer: CN=sixminute, OU=, O=, C=IE
Serial number: xxxxxxxxxxxxxxxxx
Valid from: Wed Nov 07 13:34:40 GMT 2012 until: Sun Nov 08 13:34:40 GMT 2037
Certificate fingerprints:
MD5: xxxxxxxxxxxxxxxxx
SHA1: xxxxxxxxxxxxxxxxx
Signature algorithm name: SHA1withRSA
Version: 3
and
Your keystore contains 1 entry
1, Aug 17, 2014, PrivateKeyEntry,
Certificate fingerprint (MD5): xxxxxxxxxxxxxxxxx
However, if I don't provide the password in the commands,
keytool -list -storetype pkcs12 -keystore my_debug_keystore.p12
keytool -v -list -storetype pkcs12 -keystore my_debug_keystore.p12
the output is different,
Alias name: 2
Creation date: Aug 17, 2014
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=sixminute, OU=, O=, C=IE
Issuer: CN=sixminute, OU=, O=, C=IE
Serial number: 2d36623161363935353a31336165303361636133313a2d38303030
Valid from: Wed Nov 07 13:34:40 GMT 2012 until: Sun Nov 08 13:34:40 GMT 2037
Certificate fingerprints:
MD5: xxxxxxxxxxxxxxxxx
SHA1: xxxxxxxxxxxxxxxxx
Signature algorithm name: SHA1withRSA
Version: 3
and
Your keystore contains 1 entry
2, Aug 17, 2014, PrivateKeyEntry,
Certificate fingerprint (MD5): xxxxxxxxxxxxxxxxx
Specifically a different alias for the same key (the MD5 and SHA1 are still the same for the keys).
Any idea at all why this would be the case?
Aliases are not quite a PKCS 12 concept. There is a Friendly Name attribute but it is very optional. So I would guess that Java is just making up the Alias names it reports. No idea why it would be different though, as the safe bag order should be the same.

Why does certificate signed with MD5WithRSA show SHA1 fingerprint?

When run keytool on a .RSA file for an Android APK I see the following:
Serial number: 4a9c4610
Valid from: Mon Aug 31 14:52:16 PDT 2009 until: Sun Sep 25 14:52:16 PDT 2050
Certificate fingerprints:
MD5: 3F:AD:02:4F:2D:CB:E3:EE:69:3C:96:F3:50:F8:E3:76
SHA1: 8A:3C:4B:26:2D:72:1A:CD:49:A4:BF:97:D5:21:31:99:C8:6F:A2:B9
Signature algorithm name: MD5withRSA
Version: 1
Why does it show both SHA1 and MD5 fingerprints even though the algorithm name seems to suggest MD5?
If the question is better answered by me reading some introductory article on this topic, feel free to point me to it.
The fingerprint is simply a hash of parts of the certificate data. It's not related to the hash used in the signature mechanism, so it doesn't have to be MD5.