2016-05-11 3 views
6

У меня есть короткий вопрос: что вызывает этот звонок?Дисплей сертификата для Android

context.getPackageManager().getPackageInfo(context.getPackageName(), GET_SIGNATURES).signatures[0].toByteArray(); 

Я знаю, что он возвращает первый сертификат приложения для приложения, которое находится в папке META-INFCERT.RSA, но что exately это возвращение? Просто байтовый массив, который представляет весь сертификат в виде файла или какого-либо другого байтового массива? Я не очень разбираюсь в структуре сертификатов и данных, которые они содержат, поэтому я действительно не знаю.

Лучшим ответом будет инструкция для openssl с тем, что я получаю возвращаемое значение из приведенной выше строки кода.

+1

«Я не очень разбираюсь в структуре сертификатов и данных, которые они содержат, поэтому у меня нет никакой подсказки». возможно, настало время для вас разобраться в opensl и понять, как создаются сертификаты. – t0mm13b

+0

Я действительно попытался сначала немного понять это и найти «очевидное» решение, но это не сработало. Я решил спросить, потому что мне сейчас не нужны эти знания, и у меня нет стимула копать глубже в этом вопросе. Я просто хочу знать ответ и более или менее краткое объяснение этого материала и, возможно, ссылку на лучшее объяснение. – SkryptX

ответ

0

я, наконец, тестировал себя на андроид симулятор и получил окончательный ответ. На самом деле не сложно понять, как только я понял, что PKCS7 - это просто форма хранилища или, скорее, контейнер для разных типов подписей.

В приложении

Вызов возвращает первую подпись в файле CERT.RSA. Это файл PKCS7, в который входит X.509-сертификат, и из того, что я прочитал, это всегда одна подпись для приложений для Android.

Signature sig = context.getPackageManager().getPackageInfo(context.getPackageName(), GET_SIGNATURES).signatures[0]; 

Это Signature полученный из выше, может быть непосредственно использован для создания рабочего X.509-сертификат, как это (взятое из here):

byte[] rawCert = sig.toByteArray(); 
InputStream certStream = new ByteArrayInputStream(rawCert); 

CertificateFactory certFactory; 
X509Certificate x509Cert; 
try { 
     certFactory = CertificateFactory.getInstance("X509"); 
     x509Cert = (X509Certificate) certFactory.generateCertificate(certStream); 

     //do stuff with your certificate 
} catch(Exception ex) { 
     //handle exception 
} 

В любом другом месте

Если вы иметь сертификат вне вашего собственного приложения для Android и желать того же байтового потока, который предоставляется функцией выше, вы можете сделать то же самое с простой Java-программой, например:

FileInputStream is = new FileInputStream("CERT.RSA"); 
CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
X509Certificate c = (X509Certificate) cf.generateCertificates(is).toArray()[0]; 
byte[] rawCert = c.getEncoded(); 

Этот код сначала считывает файл, создает CertificateFactory, а затем важный шаг это изолировать первый сертификат в pkcs7-контейнере. И тогда c.getEncoded(), наконец, дает то же представление, что и метод выше.

OpenSSL

И последнее, но не в последнюю очередь openssl -command для него (из here):

openssl pkcs7 -inform DER -in CERT.RSA -print_certs -text 

Это даст вам довольно обзор информации, содержащейся и в конце

-----BEGIN CERTIFICATE----- 
... 
-----END CERTIFICATE----- 

блок. Он содержит те же данные, что и выше. Если вы проанализируете содержимое этого блока и декодируете его с помощью base64, он даст вам тот же самый массив байтов, что и в двух верхних примерах.

0
context.getPackageManager().getPackageInfo(context.getPackageName(), GET_SIGNATURES).signatures[0] 

Вернуться к представлению сертификата подписи, связанного с пакетом приложений. Это будет экземпляр класса Signature, как определено в документации here. (Название «Подпись» немного вводит в заблуждение и даже упоминается в самой документации).

context.getPackageManager().getPackageInfo(context.getPackageName(), GET_SIGNATURES).signatures[0].toByteArray(); 

Вернулось бы представление своего байтового массива. т.е.: представление байтового массива файла сертификата.

Добавление к этому сертификату не является чем-то новым, чем текстовый файл, но данные структурированы в общий формат и закодированы. X.509 является одним из наиболее широко используемых форматов. Вы можете найти его here. RFC для сертификата X.509 - here. Сертификаты структурированы таким образом, что их можно легко проверить, если они изменены третьим лицом.

Нет никакой команды openssl, которая напрямую возвращает байт []. Самое близкое, о чем я мог подумать, это команда openssl, которую вы можете использовать для получения текстового представления сертификата.

$ openssl x509 -in <your-certificate> -noout -text 
+0

Не могли бы вы отредактировать свой ответ больше на исходный вопрос и ответить на вопросы явно? Также со ссылкой на openssl для удобства отображения? Если вы сделаете это, я пометю вас как принято :) – SkryptX

+0

Спасибо, сделаю так! –

+0

Привет SkryptX Я добавил ваши изменения! –

0

Член подписей PackageInfo - это просто массив всех подписей, считанных из файла пакета.

public Signature[] signatures; 

Класс android.content.pm.Signature хранит подпись в виде

private final byte[] mSignature; 

Это то, что делает toByteArray():

/** 
* @return the contents of this signature as a byte array. 
*/ 
public byte[] toByteArray() { 
    byte[] bytes = new byte[mSignature.length]; 
    System.arraycopy(mSignature, 0, bytes, 0, mSignature.length); 
    return bytes; 
} 

Поэтому в основном этот код просто обеспечивает вы являетесь массивом байтов подписи, используемой для подписи пакета.

Предполагая CERT.RSA является файл RSA в META-INF папку APK, вы можете получить пакет MD5, SHA1 и SHA256 подписей через:

keytool -printcert -file CERT.RSA 
+0

Изменено ответ на лучшее понимание вопроса – Chebyr

Смежные вопросы