简体   繁体   English

生成访问服务器资源的令牌

[英]Generate token for access server resources

I am trying to generate token at run time using sign certificate and verify that token on server to access any resources. 我试图在运行时使用签名证书生成令牌,并验证服务器上的令牌以访问任何资源。 I don't want to store token in XML file because it is available after reverse engineering of APK 我不希望将令牌存储在XML文件中,因为在对APK进行反向工程后可以使用令牌

Code for generating token is 生成令牌的代码是

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;
    }
}

Issue is some device return different token even apk is generated from the same certificate, don't know the reason why it is returning different token for some devices. 问题是即使同一证书生成了apk,某些设备也会返回不同的令牌,不知道为什么某些设备会返回不同的令牌。

All i want is generate a token which could be used to access web resources, and i don't want to store token in apk no one can get the token by decompiling apk. 我想要的只是生成一个可用于访问Web资源的令牌,而且我不想将令牌存储在apk中,没有人可以通过反编译apk来获取令牌。

The signing certificate's fingerprint will be unique across all the devices. 签名证书的指纹在所有设备上都是唯一的。 Would you please try this solution to get that fingerprint as String and use it as token. 您能否尝试此解决方案以将指纹作为String并将其用作令牌。

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

you can store token with C or C++ and add signature verification 您可以使用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;
}

@Om Infowave Developers, @Om Infowave开发人员,

I Suggest you to use a Android Keystore System to generate a KeyPair then use KeyPair to encrypt a Token, Store a token in shared preference. 我建议您使用Android Keystore系统生成KeyPair,然后使用KeyPair加密令牌,以共享首选项存储令牌。 whenever you need a token decrypt token using KeyPair. 每当您需要令牌时,都可以使用KeyPair解密令牌。

  1. This way you get unique token every time. 这样,您每次都会获得唯一令牌。
  2. Token is encrypted and secured. 令牌已加密并受到保护。
  3. KeyPair is different for every device hence more secure. 每个设备的KeyPair不同,因此更安全。

Also I just notice that you are returning zero-index based key. 我也注意到您正在返回基于零索引的密钥。 Their might be chances that key you are looking for present in subsequent indices. 他们可能是您正在寻找的关键字出现在后续索引中的机会。 Suggest you to log all key stored in Signature[] sigs ; 建议您记录存储在Signature[] sigs所有密钥;

Hope this help. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM