Извлечь исходный сертификат X.509 из подписанного APK или JAR

У меня есть библиотека MD5-хэшей открытых ключей, используемых для подписи различных банок, и сопоставление с их соответствующими хранилищами ключей, которые мы используем для подписи разных APK. То, что я хотел бы сделать, это определить, какое хранилище ключей было использовано для подписания APK, но без использования проб и ошибок. (К сожалению, многие из наших ключей имеют похожие или идентичные DN.)

Мое решение, потому что я знаю, что META-INF/FOO.RSA(или FOO.DSA) содержит сертификат, должен был извлечь сертификат из файла APK RSA и напрямую вычислить хэш MD5. (Я знаю, что сертификат существует, потому что он доступен для запуска приложения Android, а документация jarsigner говорит мне, что он есть.)

Но я не могу найти какой-либо инструмент, который дает мне фактические байты сертификата. Я могу получить DN и метаданные сертификата, когда я использую jarsigner -verbose -verify -certs my.apk, но это не дает мне байтов.

Ответ 1

Извлеките JAR, затем используйте "openssl" для вывода сертификата:

Итак, предполагая, что "foo.jar" находится в вашем текущем каталоге, сделайте что-то вроде:

mkdir temp
cd temp
jar -xvf ../foo.jar
cd META-INF
openssl pkcs7 -in FOO.RSA -print_certs -inform DER -out foo.cer

Ответ 2

Hexdump FOO.RSA. Последние n байтов являются самой сигнатурой, где n зависит от длины ключа (например, 1024 бит RSA). Если вы подписываете что-то дважды с одним и тем же ключом, вы можете различать файлы .RSA и видеть, что изменяются только последние n байтов; статической частью файла является сертификат, а биты, которые изменяются, являются сигнатурой на хэше FOO.sf. Между сертификатом и подписью может быть разделитель, который также необходимо удалить.