首页

关于android开发中如何正确使用partner activity安全用法及代码示例

标签:android,partner activity,安全     发布时间:2017-10-29   

一、前言

partner activity是指定可信应用程序可使用的Activity。通常用于合作伙伴业务之间共享数据和功能。其风险是:第三方应用可以读取信息,应确保没有第三方恶意程序读取,注意事项如下:

1、不指定taskAffinity.@b@2、不指定launchMode@b@3、不定义intent过滤器,导出属性显式设置为true@b@4、通过白名单预设请求应用的证书。@b@5、确认接收的intent来自合作方的应用。@b@6、只返回合作方授权披露的信息。

二、原示例代码

1.AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>@b@<manifest xmlns:android="http://schemas.android.com/apk/res/android"@b@    package="org.jssec.android.activity.partneractivity" >@b@ @b@    <application@b@        android:allowBackup="false"@b@        android:icon="@drawable/ic_launcher"@b@        android:label="@string/app_name" >@b@       @b@        <!-- Partner activity -->@b@ @b@        <activity@b@            android:name=".PartnerActivity"@b@            android:exported="true" />@b@       @b@    </application>@b@</manifest>

2.PkgCert.java

package org.jssec.android.shared;@b@ @b@import java.security.MessageDigest; @b@import java.security.NoSuchAlgorithmException;@b@ @b@import android.content.Context; @b@import android.content.pm.PackageInfo; @b@import android.content.pm.PackageManager; @b@import android.content.pm.PackageManager.NameNotFoundException;@b@import android.content.pm.Signature;@b@ @b@public class PkgCert {@b@ @b@       public static boolean test(Context ctx, String pkgname, String correctHash) {@b@              if (correctHash == null) return false; @b@              correctHash = correctHash.replaceAll(" ", ""); @b@              return correctHash.equals(hash(ctx, pkgname));@b@       }@b@ @b@       public static String hash(Context ctx, String pkgname) {@b@              if (pkgname == null) return null;@b@              try { @b@                     PackageManager pm = ctx.getPackageManager(); @b@                     PackageInfo pkginfo = pm.getPackageInfo(pkgname, PackageManager.GET_SIGNATURES);@b@                     if (pkginfo.signatures.length != 1) return null; // Will not handle multiple signatures.@b@                     Signature sig = pkginfo.signatures[0]; @b@                     byte[] cert = sig.toByteArray(); @b@                     byte[] sha256 = computeSha256(cert);@b@                     return byte2hex(sha256); @b@              } catch (NameNotFoundException e) {@b@                     return null;@b@              }@b@       }@b@ @b@       private static byte[] computeSha256(byte[] data) {@b@              try {@b@                     return MessageDigest.getInstance("SHA-256").digest(data);@b@              } catch (NoSuchAlgorithmException e) {@b@                     return null;@b@              }@b@       }@b@       private static String byte2hex(byte[] data) { @b@              if (data == null) return null; @b@              final StringBuilder hexadecimal = new StringBuilder();@b@              for (final byte b : data) {@b@                     hexadecimal.append(String.format("%02X", b));@b@              }@b@              return hexadecimal.toString();@b@       }@b@}

三、安全代码示例

注意事项如下所示

1、验证目标应用程序的证书已经被登记在白名单中@b@2、不将FLAG_ACTIVITY_NEW_TASK标志用于启动一项活动的intent。@b@3、仅使用putExtra()发送合作方授权的信息。@b@4、显式调用partner activity。@b@5、使用startActivityForResult() 去调用Partner Activity.@b@6、验证收到的数据。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> @b@ @b@<manifest xmlns:android="http://schemas.android.com/apk/res/android" @b@	_package="org.jssec.android.activity.partneruser" >@b@ @b@       <application@b@              android:allowBackup="false"@b@              android:icon="@drawable/ic_launcher"@b@              android:label="@string/app_name" >@b@              <activity@b@                     android:name="org.jssec.android.activity.partneruser.PartnerUserActivity"        @b@                     android:label="@string/app_name" @b@                     android:exported="true" > @b@                     <intent-filter>@b@                            <action android:name="android.intent.action.MAIN" />@b@                            <category android:name="android.intent.category.LAUNCHER" />@b@                     </intent-filter>@b@              </activity>@b@       </application>@b@</manifest>
package org.jssec.android.activity.partneruser;@b@ @b@import org.jssec.android.shared.PkgCertWhitelists;@b@import org.jssec.android.shared.Utils;@b@import android.app.Activity; @b@import android.content.ActivityNotFoundException;@b@import android.content.Context; @b@import android.content.Intent; @b@import android.os.Bundle; @b@import android.view.View; @b@import android.widget.Toast;@b@ @b@public class PartnerUserActivity extends Activity {@b@	@b@       private static PkgCertWhitelists sWhitelists = null; @b@       private static void buildWhitelists(Context context) {@b@              boolean isdebug = Utils.isDebuggable(context);@b@              sWhitelists = new PkgCertWhitelists();@b@ @b@              // Register the certificate hash value of partner application org.jssec.android.activity.partneractivity.            @b@              sWhitelists.add("org.jssec.android.activity.partneractivity", isdebug ? "0EFB7236 328348A9 89718BAD DF57F544 D5CCB4AE B9DB34BC 1E29DD26 F77C8255" : "D397D343 A5CBC10F 4EDDEB7C A10062DE 5690984F 1FB9E88B D7B3A7C2 42E142CA");@b@ @b@              // Register the other partner applications in the same way.@b@       }@b@       private static boolean checkPartner(Context context, String pkgname) {@b@              if (sWhitelists == null) buildWhitelists(context); @b@              return sWhitelists.test(context, pkgname);@b@       } @b@      @b@       private static final int REQUEST_CODE = 1;@b@ @b@       // Information related the target partner activity @b@       private static final String TARGET_PACKAGE = "org.jssec.android.activity.partneractivity"; @b@       private static final String TARGET_ACTIVITY = "org.jssec.android.activity.partneractivity.PartnerActivity";@b@ @b@       @Override @b@       public void onCreate(Bundle savedInstanceState) {@b@              super.onCreate(savedInstanceState);@b@              setContentView(R.layout.main);@b@       }@b@       public void onUseActivityClick(View view) {@b@ @b@              if (!checkPartner(this, TARGET_PACKAGE)) { @b@                     Toast.makeText(this, "Target application is not a partner application.",Toast.LENGTH_LONG).show();@b@                     return;@b@              }@b@ @b@              try { @b@                     Intent intent = new Intent();@b@                     intent.putExtra("PARAM", "Info for Partner Apps");@b@                     intent.setClassName(TARGET_PACKAGE, TARGET_ACTIVITY);@b@                     startActivityForResult(intent, REQUEST_CODE);@b@              }@b@              catch (ActivityNotFoundException e) { @b@                     Toast.makeText(this, "Target activity not found.", Toast.LENGTH_LONG).show();@b@              }@b@       }@b@ @b@       @Override @b@       public void onActivityResult(int requestCode, int resultCode, Intent data) {@b@              super.onActivityResult(requestCode, resultCode, data);@b@              if (resultCode != RESULT_OK) return;@b@             @b@              switch (requestCode) {@b@              case REQUEST_CODE:@b@                     String result = data.getStringExtra("RESULT");@b@ @b@                     // even though the data comes from a partner application. @b@                     // Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."@b@                     Toast.makeText(this, String.format("Received result:   2 Handling Input Data Carefully and Secure ")); @b@		            break;@b@              }@b@       }@b@}
package org.jssec.android.shared;@b@ @b@import java.util.HashMap;@b@import java.util.Map;@b@import android.content.Context;@b@ @b@public class PkgCertWhitelists { @b@       private Map<String, String> mWhitelists = new HashMap<String, String>();@b@        @b@       public boolean add(String pkgname, String sha256) {@b@              if (pkgname == null) return false; @b@              if (sha256 == null) return false;@b@ @b@              sha256 = sha256.replaceAll(" ", ""); @b@              if (sha256.length() != 64) return false; // SHA-256 -> 32 bytes -> 64 chars @b@              sha256 = sha256.toUpperCase(); @b@              if (sha256.replaceAll("[0-9A-F]+", "").length() != 0) return false; // found non hex char@b@ @b@              mWhitelists.put(pkgname, sha256);@b@              return true;@b@       }@b@       public boolean test(Context ctx, String pkgname) { @b@              // Get the correct hash value which corresponds to pkgname.@b@              String correctHash = mWhitelists.get(pkgname);@b@              // Compare the actual hash value of pkgname with the correct hash value.@b@              return PkgCert.test(ctx, pkgname, correctHash);@b@       }@b@}
package org.jssec.android.shared;@b@ @b@import java.security.MessageDigest;@b@import java.security.NoSuchAlgorithmException;@b@ @b@import android.content.Context; @b@import android.content.pm.PackageInfo; @b@import android.content.pm.PackageManager; @b@import android.content.pm.PackageManager.NameNotFoundException;@b@import android.content.pm.Signature;@b@ @b@public class PkgCert {@b@ @b@       public static boolean test(Context ctx, String pkgname, String correctHash) {@b@              if (correctHash == null) return false; @b@              correctHash = correctHash.replaceAll(" ", ""); @b@              return correctHash.equals(hash(ctx, pkgname));@b@       }@b@ @b@       public static String hash(Context ctx, String pkgname) {@b@              if (pkgname == null) return null; @b@              try {@b@                     PackageManager pm = ctx.getPackageManager();@b@                     PackageInfo pkginfo = pm.getPackageInfo(pkgname, PackageManager.GET_SIGNATURES);@b@                     if (pkginfo.signatures.length != 1) return null;@b@                     Signature sig = pkginfo.signatures[0];@b@                     byte[] cert = sig.toByteArray();@b@                     byte[] sha256 = computeSha256(cert);@b@                     return byte2hex(sha256);@b@              } catch (NameNotFoundException e) {@b@                     return null;@b@              }@b@       }@b@ @b@       private static byte[] computeSha256(byte[] data) {@b@              try {@b@                     return MessageDigest.getInstance("SHA-256").digest(data);@b@              } catch (NoSuchAlgorithmException e) {@b@                     return null;@b@              }@b@       }@b@      @b@       private static String byte2hex(byte[] data) {@b@              if (data == null) return null;@b@              final StringBuilder hexadecimal = new StringBuilder();@b@              for (final byte b : data) {@b@                     hexadecimal.append(String.format("%02X", b));@b@              }@b@              return hexadecimal.toString();@b@       }@b@}
<<热门下载>>