给APP增加RSA签名

来源:互联网 发布:爱马仕雪白龙胆知乎 编辑:程序博客网 时间:2024/06/06 12:43
     RSA签名,Google主要用于APP的来源控制与结算。所谓的结算,也是就是控制了APP只有使用现在机子上登录的Google账户从Google市场曾经下载过该APP的才能够使用,这样也就达到了app销售的目的。
   

增加RSA签名主要分为以下几步骤
   1).添加License Verification Library(LVL)库
   2).发布一个测试版(BETA 版)到Google Play市场。
   3).代码中实现签名的认证功能并进行APP的权限控制。

以下所有操作都是在Android Studio里面完成。Eclipse可以进行对应参考。

一。添加第三方库License Verification Library(LVL)步骤
1,下载LVL库
      打开Android SDK Manager。在库列表Extras下面找到Google Play LIcensing Library。下载之。现在完成该Lib会存放在android-sdk-windows\extras\google\play_licensing\library。
2,添加LVL库到工程中
File---New---Import Module。选择SDK中LVL库。也就是android-sdk-windows\extras\google\play_licensing\library。选择正确,则会出现Module Name。可以自定义这个Lib名字。这里定义为lvl。


3,打开App的Grade file。注意:是App目录下的Grade File。一般命名为build.grade。对应位置(dependencies)添加
compile project(':lvl')


 4,点击Tools----Android-----Sync Project with Grade Files。完成了第三方库的添加。

添加第三方库方法参考:http://www.truiton.com/2015/02/android-studio-add-library-project/


二。发布一个测试版到Google 市场
     该步骤和正常发布一个App是一样的。只不过APK上传的时候,选择的是Beta版,非正式版。注意:点击右上角的发布之后才是完成,非上传完APK就算完成了。测试的APP需要添加测试账户到封闭的测试列表里面,也就是手机现已登录的Google账户需要添加到里面,不然无法进行测试。

三,实现与签名服务器的交互达到实现控制应用程序的权限的控制
    官方操作方法参考:http://developer.android.com/google/play/licensing/adding-licensing.html#impl-Obfuscator
    与签名服务器交互主要通过LicenseChecker这个类。通过LicenseChecker注册一个LicenseCheckerCallback的回调来达到控制APP的目的,一般都是在MainActivity进行与签名服务器的交互工作,在mLicenseCheckerCallback中,如果成功认证APP则继续往下走,否则可以提示退出。
    操作方法如下:
1,添加App的权限
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />

2,在MainActivity定义一个20个随机字节的数组(供AESObfuscator使用),和一些变量。
    private static final String BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjynFykMkHwAuVkL22mUo3Z2HkTXbtXzjAktR1xrIAudSnWCYWKoAeWsSGccS+KOinEyTK1/aMPbWFhjqUl08AtMAygaukoFD3OltfKan4At99AJH9BxKNWZCLAAilt7jW1+8PoiaintlLHZpyG2c6VqSET2VRyGCFCXzKq9BnnhJqkGxJagSRf43WhFXHl1nueDDDm4DdmGjAegY2loglRbYq9cuqxSGn8T1c/ebYE2IZn+OjtG0/9+ce6WwGabeTyQi3HVcvwerTVYwT8PAzujcX6epvhtL3Jfvp73QEWojR381e8Fpsw+Qvd+2rnSZNphbSY56f/4wg4OhPGG6twIDAQAB";     private static final byte[] SALT = new byte[] { 13, 32, 81, 65, 53, 82, 18, 100, -69, -17, 51, 81, -13, 86, -10, -40, 19, 45, 63, -7 };    private LicenseChecker mChecker;     private LicenseCheckerCallback mLicenseCheckerCallback;

3.定义一个内部LicenseCheckerCallback类
private class MyLicenseCheckerCallback implements LicenseCheckerCallback {        @Override        public void allow(int reason) {//            Log.i("RSA", "success Code: " + reason);            delayedHide(HIDE_DELAY_MILLIS);        }         @Override        public void applicationError(int errorCode) {//            Log.i("RSA", "Error Code: " + errorCode);            haveNoLicence();        }                 @Override        public void dontAllow(int reason) {            Log.i("RSA", "dontAllow Code: " + reason);            if (reason !=Policy.LICENSED){  //not success                haveNoLicence();            }                      }    }

 
   在这个Callback类里面,访问返回方法是dontAllow。在成功的情况下才会调用allow。报错的情况下才会调用applicationError,报错不包括没有license,网络错误等。所以我这里直接是没有认证成功就执行没有权限的方法。

4,初始化LicenseChecker和LicenseCheckerCallback
        String deviceId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);        // Library calls this when it's done.        mLicenseCheckerCallback = new MyLicenseCheckerCallback();        // Construct the LicenseChecker with a policy.        mChecker = new LicenseChecker(this, new ServerManagedPolicy(this, new AESObfuscator(SALT, getPackageName(), deviceId)), Constants.RSA_KEY);


5,访问签名服务器进行校验。
mChecker.checkAccess(mLicenseCheckerCallback);


到这里,就完成了RSA的认证了。

可能会遇到的问题
1,报错,Error code 3。是由于Google市场没有上传APK。或者还没有发布完成。如果已经完成发布,请等待审核通过。估计24小时内可以通过审核。
2,切换Google账户或者更换应用中的RSA KEY。如果校验结果与想象的结果不相同,则需删除应用并且重启手机再进行测试。
3,其他错误代码列表如下:
LICENSED = Hex: 0x0100, Decimal: 256NOT_LICENSED = Hex: 0x0231, Decimal: 561RETRY = Hex: 0x0123, Decimal: 291LICENSED_OLD_KEY = Hex: 0x2, Decimal: 2ERROR_NOT_MARKET_MANAGED = Hex: 0x3, Decimal: 3ERROR_SERVER_FAILURE = Hex: 0x4, Decimal: 4ERROR_OVER_QUOTA = Hex: 0x5, Decimal: 5ERROR_CONTACTING_SERVER = Hex: 0x101, Decimal: 257ERROR_INVALID_PACKAGE_NAME = Hex: 0x102, Decimal: 258 ERROR_NON_MATCHING_UID = Hex: 0x103, Decimal: 259

来源: <http://stackoverflow.com/questions/18324963/how-can-i-implement-a-licensing-strategy-for-android/18325731#18325731>
 

安卓5.0系统不允许隐式调用服务,导致LVL包绑定服务报错。报“Service Intent must be explicit Intent”错误,需修改代码如下:
com.google.android.vending.licensing中的LicenseChecker类中方法checkAccess中的代码:

                     boolean bindResult =mContext                            .bindService(                                    new Intent(                                            new String(                            Base64.decode("Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U=")),                                    this, // ServiceConnection.                                   Context.BIND_AUTO_CREATE);


修改为显式调用:

                   String name = new String(                           Base64.decode("Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U="));                   Intent serviceIntent = new Intent(name);                   serviceIntent.setPackage("com.android.vending");                   boolean bindResult =mContext.getApplicationContext().bindService(serviceIntent, this, Context.BIND_AUTO_CREATE);




0 0