2017-07-28 64 views
1

我试图在运行时使用签名证书生成令牌,并在服务器上验证该令牌以访问任何资源。我不想令牌存储在XML文件,因为它是生成令牌APK为访问服务器资源生成令牌

代码的逆向工程后可为

public String getToken() { 
    Signature[] sigs; 
    try { 
     sigs = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures; 

     String token = sigs[0].toCharsString(); 
     return token; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

的问题是,即使APK是来自同一所产生的一些装置回不同的令牌证书,不知道它为什么为某些设备返回不同令牌的原因。

我想要的是生成一个令牌,可以用来访问网络资源,我不想在apk中存储令牌没有人可以通过反编译apk获得令牌。

+0

_some设备返回不同的令牌_所以你说有一些设备给你相同的令牌? – SripadRaj

+0

我们在服务器上添加了日志文件,主要设备返回相同的令牌,但其中一些返回不同的令牌(1%的用户返回不同的令牌)。 –

+0

regid = FirebaseInstanceId.getInstance()。getToken();像这样得到 –

回答

1

可以存储与C或C++ 令牌,并添加签名验证

public static String getSignature(Context context) { 
try { 
    PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES); 
    Signature[] signatures = packageInfo.signatures; 
    return signatures[0].toCharsString(); 
} catch(PackageManager.NameNotFoundException e) { 
    e.printStackTrace(); 
} 
return null; 

}

const char * app_signature = "singsing"; 
static int is_valid = 0; 
void 
Java_com_xxx_xxx_nativeInit(JNIEnv *env, jobject thiz, jobject context_object){ 
    jclass context_class = (*env)->GetObjectClass(env, context_object); 

    //context.getPackageManager() 
    jmethodID methodId = (*env)->GetMethodID(env, context_class, "getPackageManager", "()Landroid/content/pm/PackageManager;"); 
    jobject package_manager_object = (*env)->CallObjectMethod(env, context_object, methodId); 
    if (package_manager_object == NULL) { 
     return; 
    } 

    //context.getPackageName() 
    methodId = (*env)->GetMethodID(env, context_class, "getPackageName", "()Ljava/lang/String;"); 
    jstring package_name_string = (jstring)(*env)->CallObjectMethod(env, context_object, methodId); 
    if (package_name_string == NULL) { 
     return ; 
    } 
    (*env)->DeleteLocalRef(env,context_class); 

    //PackageManager.getPackageInfo(Sting, int) 
    //public static final int GET_SIGNATURES= 0x00000040; 
    jclass pack_manager_class = (*env)->GetObjectClass(env, package_manager_object); 
    methodId = (*env)->GetMethodID(env, pack_manager_class, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); 
    (*env)->DeleteLocalRef(env,pack_manager_class); 
    jobject package_info_object = (*env)->CallObjectMethod(env, package_manager_object, methodId, package_name_string, 0x40); 
    if (package_info_object == NULL) { 
     return ; 
    } 
    (*env)->DeleteLocalRef(env,package_manager_object); 

    //PackageInfo.signatures[0] 
    jclass package_info_class = (*env)->GetObjectClass(env, package_info_object); 
    jfieldID fieldId = (*env)->GetFieldID(env, package_info_class, "signatures", "[Landroid/content/pm/Signature;"); 
    (*env)->DeleteLocalRef(env,package_info_class); 
    jobjectArray signature_object_array = (jobjectArray)(*env)->GetObjectField(env,package_info_object, fieldId); 
    if (signature_object_array == NULL) { 
     return ; 
    } 
    jobject signature_object = (*env)->GetObjectArrayElement(env,signature_object_array, 0); 
    (*env)->DeleteLocalRef(env,package_info_object); 
    jclass signature_class = (*env)->GetObjectClass(env, signature_object); 
    methodId = (*env)->GetMethodID(env, signature_class, "toCharsString", "()Ljava/lang/String;"); 
    (*env)->DeleteLocalRef(env,signature_class); 
    jstring signature_jstirng = (jstring) (*env)->CallObjectMethod(env, signature_object, methodId); 
    const char *sign=(*env)->GetStringUTFChars(env, signature_jstirng,NULL); 
    if (strcmp(sign,app_signature)==0 || strcmp(sign,app_j_s)==0) { 
     is_valid= 1; 
    } 
    return; 
} 
+0

有错误无法解析'GetObjectClass(contextObject)',请问您可以提供**。c **文件 –

+0

是他们用同样的函数加密'c_msg'的方法吗? –

+0

@OmInfowaveDevelopers我用c更新了。 – sanemars

1

签名证书的指纹在所有设备中都是唯一的。您是否可以尝试使用此解决方案将该指纹作为字符串获取并将其用作标记。

https://stackoverflow.com/a/22506133/4586742

+0

我的代码有什么问题?我已经添加了一些设备调用Web服务的日志文件不同的令牌。 –

+0

所以它是可以破解的,任何人都可以使用上述逻辑生成**指纹**,并使用该密钥访问resources.is他们的任何解决方案。 –

+0

t也可以使用某种技术生成指纹'列表 apps = context.getPackageManager()。getInstalledPackages(PackageMana ger.GET_SIGNATURES);'给出(Signature s:pi.signatures){Log.d(“PackageTrackerfix”,“old:”+ s.toCharsString()+“”+ s)的已安装软件包的所有列表。的hashCode()); }'它返回'generateCertificate()'中使用的所有证书详细信息' –

0

@Om Infowave开发商,

我建议你使用Android Keystore System 生成KeyPair然后使用KeyPair加密令牌,将令牌存储在共享首选项中。无论何时需要使用KeyPair的令牌解密令牌。

  1. 这样你每次都得到唯一的令牌。
  2. 令牌被加密和保护。
  3. KeyPair因每个设备而异,因此更安全。

另外我只注意到你正在返回基于零索引的密钥。他们可能是你在随后的指数中寻找关键的机会。建议您记录存储在Signature[] sigs中的所有密钥;

希望得到这个帮助。

+0

@桑代如何验证服务器上的这个令牌? –

+0

您目前如何验证服务器上的令牌?使用目前在服务器上验证令牌的相同方式。唯一的区别是您在第一次生成后以加密格式在Android设备上以共享首选项的形式存储了令牌。之后从共享首选项解密令牌中提取令牌并将其发送到服务器。如果你有任何其他帮助,请告诉我。非常乐意帮助。 – Sandy

+0

另一种方法是将设备ID和令牌发送到服务器,将设备ID和令牌存储在服务器上。 – Sandy

相关问题