Skip to content

Most visited

Recently visited

navigation

Memperbarui Penyedia Keamanan Agar Terlindung Dari Eksploitasi SSL

Android bergantung pada Provider keamanan untuk menyediakan komunikasi jaringan yang aman. Akan tetapi, dari waktu ke waktu, celah keamanan ditemukan di penyedia keamanan default. Untuk melindungi dari celah keamanan ini, Google Play Services menyediakan cara untuk secara otomatis memperbarui penyedia keamanan perangkat agar terlindung dari eksploitasi yang dikenal. Dengan memanggil metode Google Play Services, aplikasi Anda bisa memastikan bahwa itu berjalan pada perangkat yang memiliki pembaruan terbaru untuk melindungi dari eksploitasi yang dikenal.

Misalnya, celah keamanan ditemukan di OpenSSL (CVE-2014-0224) yang membuat aplikasi rentan terhadap serangan "man-in-the-middle" yang memecahkan kode lalu lintas aman tanpa diketahui kedua pihak. Dengan Google Play Services versi 5.0, tersedia perbaikan, namun aplikasi harus memastikan bahwa perbaikan ini dipasang. Dengan menggunakan metode Google Play Services, aplikasi Anda bisa memastikan bahwa itu berjalan pada perangkat yang aman dari serangan.

Perhatian: Memperbarui keamanan perangkat Provider tidak memperbarui android.net.SSLCertificateSocketFactory. Daripada menggunakan kelas ini, kami menyarankan developer aplikasi untuk menggunakan metode tingkat tinggi untuk berinteraksi dengan kriptografi. Sebagian besar aplikasi bisa menggunakan API seperti HttpsURLConnection tanpa perlu menetapkan TrustManager khusus atau membuat SSLCertificateSocketFactory.

Melakukan Patch Penyedia Keamanan dengan ProviderInstaller

Untuk memperbarui penyedia keamanan perangkat, gunakan kelas ProviderInstaller. Anda bisa memverifikasi bahwa penyedia keamanan adalah versi terbaru (dan memperbaruinya, jika perlu) dengan memanggil metode installIfNeeded() (atau installIfNeededAsync()) kelas tersebut.

Bila Anda memanggil installIfNeeded(), ProviderInstaller akan melakukan hal berikut:

Metode installIfNeededAsync() berperilaku sama, selain sebagai ganti mengeluarkan pengecualian, itu memanggil metode callback yang tepat untuk menunjukkan keberhasilan atau kegagalan.

Jika installIfNeeded() perlu memasang Provider baru, bisa membutuhkan waktu dari 30-50 milidetik (pada perangkat yang lebih baru) hingga 350 milidetik (pada perangkat yang lebih tua). Jika penyedia keamanan sudah versi terbaru, metode ini akan membutuhkan waktu yang sangat singkat. Agar tidak memengaruhi pengalaman pengguna:

Peringatan: Jika ProviderInstaller tidak mampu memasang Provider yang diperbarui, penyedia keamanan perangkat mungkin rentan terhadap eksploitasi. Aplikasi Anda harus bersikap seolah-olah semua komunikasi HTTP tidak terenkripsi.

Setelah Provider diperbarui, semua panggilan ke API keamanan (termasuk API SSL) akan disalurkan melalui itu. (Akan tetapi, ini tidak berlaku untuk android.net.SSLCertificateSocketFactory, yang masih rentan terhadap eksploitasi seperti CVE-2014-0224.)

Melakukan Patch Secara Sinkron

Cara paling mudah untuk melakukan patch penyedia keamanan adalah dengan memanggil metode sinkron installIfNeeded(). Ini cocok jika pengalaman pengguna tidak terpengaruh oleh pemblokiran-thread sambil menunggu operasi diselesaikan.

Misalnya, berikut adalah implementasi dari sync adapter yang melakukan pembaruan penyedia keamanan. Karena sync adapter berjalan di latar belakang, tidak apa-apa jika thread memblokir ketika menunggu penyedia keamanan diperbarui. Sync adapter memanggil installIfNeeded() untuk memperbarui penyedia keamanan. Jika metode kembali secara normal, sync adapter akan mengetahui bahwa penyedia keamanan up-to-date. Jika metode melontarkan pengecualian, sync adapter bisa melakukan tindakan yang tepat (seperti memperingatkan pengguna untuk memperbarui Google Play Services).

/**
 * Sample sync adapter using {@link ProviderInstaller}.
 */
public class SyncAdapter extends AbstractThreadedSyncAdapter {

  ...

  // This is called each time a sync is attempted; this is okay, since the
  // overhead is negligible if the security provider is up-to-date.
  @Override
  public void onPerformSync(Account account, Bundle extras, String authority,
      ContentProviderClient provider, SyncResult syncResult) {
    try {
      ProviderInstaller.installIfNeeded(getContext());
    } catch (GooglePlayServicesRepairableException e) {

      // Indicates that Google Play services is out of date, disabled, etc.

      // Prompt the user to install/update/enable Google Play services.
      GooglePlayServicesUtil.showErrorNotification(
          e.getConnectionStatusCode(), getContext());

      // Notify the SyncManager that a soft error occurred.
      syncResult.stats.numIOExceptions++;
      return;

    } catch (GooglePlayServicesNotAvailableException e) {
      // Indicates a non-recoverable error; the ProviderInstaller is not able
      // to install an up-to-date Provider.

      // Notify the SyncManager that a hard error occurred.
      syncResult.stats.numAuthExceptions++;
      return;
    }

    // If this is reached, you know that the provider was already up-to-date,
    // or was successfully updated.
  }
}

Melakukan Patch Secara Asinkron

Memperbarui penyedia keamanan bisa membutuhkan waktu 350 milidetik (pada perangkat yang lebih tua). Jika Anda melakukan pembaruan pada thread yang secara langsung memengaruhi pengalaman pengguna, seperti thread UI, Anda sebaiknya tidak membuat panggilan sinkron untuk memperbarui penyedia, karena bisa mengakibatkan aplikasi atau perangkat berhenti sampai operasi selesai. Sebagai gantinya, Anda harus menggunakan metode asinkron installIfNeededAsync(). Metode tersebut menunjukkan keberhasilan atau kegagalan dengan memanggil callback.

Misalnya, berikut adalah beberapa kode yang memperbarui penyedia keamanan dalam aktivitas di thread UI. Aktivitas memanggil installIfNeededAsync() untuk memperbarui penyedia, dan menunjuk dirinya sebagai listener untuk menerima notifikasi berhasil atau gagal. Jika penyedia keamanan menggunakan versi terbaru atau berhasil diperbarui, metode onProviderInstalled() aktivitas akan dipanggil, dan aktivitas akan mengetahui bahwa komunikasi tersebut aman. Jika operator tidak dapat diperbarui, metode onProviderInstallFailed() aktivitas akan dipanggil, dan aktivitas bisa mengambil tindakan yang tepat (seperti memperingatkan pengguna untuk memperbarui Google Play Services).

/**
 * Sample activity using {@link ProviderInstaller}.
 */
public class MainActivity extends Activity
    implements ProviderInstaller.ProviderInstallListener {

  private static final int ERROR_DIALOG_REQUEST_CODE = 1;

  private boolean mRetryProviderInstall;

  //Update the security provider when the activity is created.
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ProviderInstaller.installIfNeededAsync(this, this);
  }

  /**
   * This method is only called if the provider is successfully updated
   * (or is already up-to-date).
   */
  @Override
  protected void onProviderInstalled() {
    // Provider is up-to-date, app can make secure network calls.
  }

  /**
   * This method is called if updating fails; the error code indicates
   * whether the error is recoverable.
   */
  @Override
  protected void onProviderInstallFailed(int errorCode, Intent recoveryIntent) {
    if (GooglePlayServicesUtil.isUserRecoverableError(errorCode)) {
      // Recoverable error. Show a dialog prompting the user to
      // install/update/enable Google Play services.
      GooglePlayServicesUtil.showErrorDialogFragment(
          errorCode,
          this,
          ERROR_DIALOG_REQUEST_CODE,
          new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
              // The user chose not to take the recovery action
              onProviderInstallerNotAvailable();
            }
          });
    } else {
      // Google Play services is not available.
      onProviderInstallerNotAvailable();
    }
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode,
      Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == ERROR_DIALOG_REQUEST_CODE) {
      // Adding a fragment via GooglePlayServicesUtil.showErrorDialogFragment
      // before the instance state is restored throws an error. So instead,
      // set a flag here, which will cause the fragment to delay until
      // onPostResume.
      mRetryProviderInstall = true;
    }
  }

  /**
   * On resume, check to see if we flagged that we need to reinstall the
   * provider.
   */
  @Override
  protected void onPostResume() {
    super.onPostResult();
    if (mRetryProviderInstall) {
      // We can now safely retry installation.
      ProviderInstall.installIfNeededAsync(this, this);
    }
    mRetryProviderInstall = false;
  }

  private void onProviderInstallerNotAvailable() {
    // This is reached if the provider cannot be updated for some reason.
    // App should consider all HTTP communication to be vulnerable, and take
    // appropriate action.
  }
}
This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Ikuti Google Developers di WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (Dec 2017 Android Platform & Tools Survey)