Based on Jcs answer, we use this to find out at runtime which the running package created:
private enum BuildSigner { unknown, Joe, Carl, Linda } private BuildSigner whoBuiltThis() { try { PackageManager packageManager = getPackageManager(); PackageInfo info = packageManager.getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES); Signature[] signs = info.signatures; CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate)cf.generateCertificate( new ByteArrayInputStream(signs[0].toByteArray())); PublicKey key = cert.getPublicKey(); int modulusHash = ((RSAPublicKey)key).getModulus().hashCode(); switch (modulusHash) { case 123456789: return BuildSigner.Joe; case 424242424: return BuildSigner.Carl; case -975318462: return BuildSigner.Linda; } } catch (Exception e) { } return BuildSigner.unknown; }
For any certificate involved, you just need to find the hash once and add it to the list.
The simplest way to โfind the hash onceโ might be to simply add a pop-up toast before the switch statement that displays modulusHash , compile your application, run it, write the hash, delete the toast code and add the hash to the list.
Alternatively, when I did this, I created a small template application with one action and one TextView with the identifier tv in the main layout, putting it in the action:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); int hash = 0; try{ PackageManager packageManager = getPackageManager(); PackageInfo info = packageManager.getPackageInfo( "com.stackexchange.marvin", PackageManager.GET_SIGNATURES); Signature[] signs = info.signatures; CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) cf.generateCertificate( new ByteArrayInputStream(signs[0].toByteArray())); PublicKey key = cert.getPublicKey(); hash = ((RSAPublicKey) key).getModulus().hashCode(); }catch(Exception e){} TextView tv = ((TextView)findViewById(R.id.tv)); tv.setText("The Stack Exchange app signature hash is " + hash + "."); tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24); }
(change com.stackexchange.marvin to your application name), compiled this gadget and sent the APK to all participating developers, asking them to run it on their device and tell me the displayed hash.
balpha Jul 16 '13 at 6:12 2013-07-16 06:12
source share