2013-07-09 3 views
2

Как проверить, соответствует ли подпись моего приложения сигнатуре сертификата, который я использовал для его подписания?Как проверить, что приложение было подписано моим сертификатом?

Это, как я должен быть в состоянии получить сертификаты отпечатков пальцев:

public String getCertificateFingerprint() throws NameNotFoundException, CertificateException, NoSuchAlgorithmException { 
     PackageManager pm = context.getPackageManager(); 
     String packageName =context.getPackageName(); 

     int flags = PackageManager.GET_SIGNATURES; 

     PackageInfo packageInfo = null; 

     packageInfo = pm.getPackageInfo(packageName, flags); 
     Signature[] signatures = packageInfo.signatures; 

     byte[] cert = signatures[0].toByteArray(); 

     InputStream input = new ByteArrayInputStream(cert); 

     CertificateFactory cf = null; 
     cf = CertificateFactory.getInstance("X509"); 

     X509Certificate c = null; 
     c = (X509Certificate) cf.generateCertificate(input); 

     MessageDigest md = MessageDigest.getInstance("MD5"); 
     byte[] publicKey = md.digest(c.getPublicKey().getEncoded()); 

     StringBuffer hexString = new StringBuffer(); 
     for (int i = 0; i < publicKey.length; i++) { 
      String appendString = Integer.toHexString(0xFF & publicKey[i]); 
      if (appendString.length() == 1) 
       hexString.append("0"); 
      hexString.append(appendString); 
     } 

     return hexString.toString(); 
    } 

Это, как я должен быть в состоянии получить отпечаток моего сертификата:

keytool -v -list -keystore filenameandpath 

Моя проблема заключается, что эти два дают разные результаты. Может ли кто-нибудь указать, что я напортачиваю?

ответ

6

Вы вычисления MD5 хэш неправильных данных. Отпечаток сертификата - это хеш (MD5, SHA1, SHA256 и т. Д.) Необработанного сертификата. Т.е., вы должны быть вычисления хэш этих байтов:

byte[] cert = signatures[0].toByteArray(); 

Е.Г., следующий вычисляет SHA1 отпечаток пальца, просто изменить SHA1 для MD5, если вы предпочитаете.

public String computeFingerPrint(final byte[] certRaw) { 

    String strResult = ""; 

    MessageDigest md; 
    try { 
     md = MessageDigest.getInstance("SHA1"); 
     md.update(certRaw); 
     for (byte b : md.digest()) { 
      strAppend = Integer.toString(b & 0xff, 16); 
      if (strAppend.length() == 1) 
       strResult += "0"; 
      strResult += strAppend; 
     } 
     strResult = strResult.toUpperCase(DATA_LOCALE); 
    } 
    catch (NoSuchAlgorithmException ex) { 
     ex.printStackTrace(); 
    } 

    return strResult; 
} 
+0

Да, я проверял неправильные данные! Спасибо за помощь! – Tamas

0

Используйте свой код для сбора отпечатков пальцев на устройстве в режиме «тест» - это означает, что у вас есть временный код, чтобы испускать этот отпечаток в журнал (или в другом месте). Обязательно проверьте это, используя ключ подписи продукта, а не ключ отладки!

Как только вы знаете, с точки зрения устройства, вы можете удалить временный код и в другом месте, где вы можете сравнить с тем, что вы ранее определили как ключ.

Помните, что вы, вероятно, делаете это, чтобы кто-то не модифицировал ваше приложение и не подписал его другим ключом, но у кого есть возможность сделать это, также есть возможность изменить проверку ключа. Это проблема, которая может быть решена с помощью дополнительной обфускации, но вам нужно придумать собственное решение, чтобы минимизировать вероятность того, что злоумышленник знает, что искать.

+0

да, мой Цель состоит в том, чтобы усложнить повторную подписку приложения. Моя проблема в том, что у меня уже есть код для запроса отпечатка пальца приложения, но он отличается от того, что я думаю, что это должно быть. – Tamas

0

Вы можете открыть apk как zip-файл и отфильтровать текст ascii из двоичного содержимого META-INF/CERT.RSA и проверить, есть ли он, который его сшил.


попробовать:

final void initVerify(Certificate certificate) 

от: http://developer.android.com/reference/java/security/Signature.html

+0

ascii текст внутри: "test". Я уверен, что правильно его подписал – Tamas

+0

@Tamas это означает, что он не поет – akuzma

+0

nope, я подписал его с помощью ключа, который я создал для тестирования, поэтому я заполнил название компании и т. Д. С помощью «теста» :), поэтому Я правильно подписывал свое приложение.Таким образом, моя проблема по-прежнему сохраняется, я хочу иметь возможность проверять во время выполнения, с каким сертификатом подписан apk. – Tamas

0

код ниже:

c.getPublicKey().getEncoded() 

это должно быть, как это

c.getEncoded() 

я думаю, что проверка md5 на Keytool это проверить CERTFILE, не ОткрытыйКлюч

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