Pro Android 5

Dave MacLean, Satya Komatineni, Grant Allen

Mentioned 1

Pro Android 5 shows you how to build real-world and fun mobile apps using the Android 5 SDK. This book updates the best-selling Pro Android and covers everything from the fundamentals of building apps for smartphones, tablets, and embedded devices to advanced concepts such as custom components, multi-tasking, sensors/augmented reality, better accessories support and much more. Using the tutorials and expert advice, you'll quickly be able to build cool mobile apps and run them on dozens of Android-based smartphones. You'll explore and use the Android APIs, including those for media and sensors. And you'll check out what's new in Android, including the improved user interface across all Android platforms, integration with services, and more. By reading this definitive tutorial and reference, you'll gain the knowledge and experience to create stunning, cutting-edge Android apps that can make you money, while keeping you agile enough to respond to changes in the future.

More on Amazon.com

Mentioned in questions and answers.

I want to check if installed android application has self signed or trusted certificate. The problem is that my code listed below raises CertificateException for all installed (including Google made) apps. Could you help me to find a problem why it doesn't work correctly?

    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    List<ResolveInfo> runningServices = getPackageManager().queryIntentActivities(intent, 0);
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    KeyStore ks = KeyStore.getInstance("AndroidCaStore");
    ks.load(null, null);
    tmf.init(ks);
    X509TrustManager trustManager = (X509TrustManager)tmf.getTrustManagers()[0];
    PackageManager manager = getPackageManager();
    try {
        for (ResolveInfo runningService : runningServices) {
            PackageInfo info = manager.getPackageInfo(runningService.activityInfo.packageName,
                    PackageManager.GET_SIGNATURES);

            Signature signature = info.signatures[0];
            Signature[] arrSignatures = info.signatures;
            for (Signature sig : arrSignatures) {
                byte[] rawCert = sig.toByteArray();
                InputStream certStream = new ByteArrayInputStream(rawCert);

                CertificateFactory certFactory;
                X509Certificate x509Cert;
                try {
                    certFactory = CertificateFactory.getInstance("X509");
                    x509Cert = (X509Certificate) certFactory.generateCertificate(certStream);
                    trustManager.checkServerTrusted(new X509Certificate[] { x509Cert }, "RSA");
                }
                catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (KeyStoreException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (CertificateException e) {
                    e.printStackTrace();
                }
            }
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }

The answer is pretty obvious: we can't validate android app certificate using trusted certificates chain (what normally do ssl guts to check web resource certificate), because they are self-signed. That is why checkServerTrusted function raises CertificateException during such check. This book gives following information:

Because a process is tied to a package name, and a package name is tied to its signature, signatures play a role in securing the data belonging to a package. A package is typically signed with a self-signed PKI (Public Key Infrastructure) certificate. A certificate identifies who the author of the package is. These certificates need not be issued by a certificate authority. This means the information in the certificate is not approved or validated by any authority. This means one can create a certificate that says that their name is Google. The only assurance is that this package name is reserved to that user if no one had claimed it in the marketplace before, and any subsequent updates to that package are given only to that user (identified by that certificate).