Android使用NDK进行联网签名认证
16lz
2021-12-04
Android使用NDK进行联网签名认证
#include #include #include #include #include #include #include extern "C"{#define HOST "127.0.0.1"#define PAGE "/loc/keylist.do"#define PORT 80#define USERAGENT "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.114 Safari/537.36"#define ACCEPTLANGUAGE "zh-CN,zh;q=0.8,en;q=0.6,en-US;q=0.4,en-GB;q=0.2"#define ACCEPTENCODING "gzip,deflate,sdch"#define LOG_TAG "HelloJni"#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)char* getServerKey(void);char *jstringTostring(JNIEnv *env, jstring jstr) { char *rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("utf-8"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte *ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) { rtn = (char *) malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env->ReleaseByteArrayElements(barr, ba, 0); return rtn;}char *get_ip(const char *host){ struct hostent *hent; int iplen=15; char *ip=(char *)malloc(iplen+1); memset(ip,0,iplen+1); if((hent=gethostbyname(host))==NULL){ // perror("Can't get ip"); // exit(1); return NULL; } if(inet_ntop(AF_INET,(void *)hent->h_addr_list[0],ip,iplen)==NULL){ LOGI("Can't resolve host!\n"); //exit(1); return NULL; } return ip;}char *build_get_query(const char *host,const char *page){ char *query; const char *getpage=page; const char *tpl="GET %s HTTP/1.1\r\nHost:%s\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\nUser-Agent:%s\r\nAccept-Language:%s\r\n\r\n"; query=(char *)malloc(strlen(host)+strlen(getpage)+strlen(USERAGENT)+strlen(tpl)+strlen(ACCEPTLANGUAGE)-5);//+strlen(ACCEPTENCODING) sprintf(query,tpl,getpage,host,USERAGENT,ACCEPTLANGUAGE);//ACCEPTENCODING return query;}char* getServerKey(void){ const char* strend="\r\n0\r\n"; std::string strcontent; struct sockaddr_in *remote; int sock; int tmpres; char* ip; char* get; const char* host; char buf[BUFSIZ+1]; const char *page; if((sock=socket(AF_INET,SOCK_STREAM,0))<0) { LOGI("socket create failed!"); return NULL; } page=PAGE; host=HOST; ip=get_ip(host); if(ip== NULL){ LOGI("ip is null"); return NULL; } remote=(struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); remote->sin_family=AF_INET; tmpres=inet_pton(AF_INET,ip,(void *)(&(remote->sin_addr.s_addr))); remote->sin_port=htons(PORT); if(connect(sock,(struct sockaddr *)remote,sizeof(struct sockaddr))<0){ LOGI("Could not connect!\n"); // exit(1); return NULL; } get =build_get_query(host,page); int sent=0; while(sent<strlen(get)){ tmpres=send(sock,get+sent,strlen(get)-sent,0); if(tmpres==-1){ LOGI("Can't send query!"); // exit(1); return NULL; } sent+=tmpres; } memset(buf,0,sizeof(buf)); int htmlstart=0; char *htmlcontent; while((tmpres=recv(sock,buf,BUFSIZ,0))>0){ if(htmlstart==0){ htmlcontent=strstr(buf,"\r\n\r\n"); if(htmlcontent!=NULL){ htmlstart=1; htmlcontent+=4; } }else{ htmlcontent=buf; } if(htmlstart){ LOGI("start receive"); strcontent+=std::string(htmlcontent);//这个地方不完善 不完善 不完善 不完善 不完善 没去对CHUNKED编码解析 如果是content length 需要去比对长度 手动断掉TCP连接不然recv会阻塞 ,这个只是个demo不完善 if( strstr(strcontent.c_str(),strend)) { break; } } LOGI("%s",buf); memset(buf,0,tmpres); LOGI("\n\n\ntmpres Value:%d\n",tmpres); } LOGI("receive data over!\n"); if(tmpres<0){ LOGI("Error receiving data!\n"); } free(get); free(remote); free(ip); close(sock); LOGI("content size:%d",strcontent.size()); //int pos=strcontent.find(strend); //if(pos>=0) // strcontent.erase((pos,strlen(strend))); return (char*)strcontent.c_str();}bool CourseKeyIsVail(JNIEnv *env, jobject contextObject, const char *key) { jclass native_class = env->GetObjectClass(contextObject); jmethodID pm_id = env->GetMethodID(native_class, "getPackageManager", "()Landroid/content/pm/PackageManager;"); jobject pm_obj = env->CallObjectMethod(contextObject, pm_id); jclass pm_clazz = env->GetObjectClass(pm_obj); jmethodID package_info_id = env->GetMethodID(pm_clazz, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); jclass native_classs = env->GetObjectClass(contextObject); jmethodID mId = env->GetMethodID(native_classs, "getPackageName", "()Ljava/lang/String;"); jstring pkg_str = static_cast(env->CallObjectMethod(contextObject, mId)); jobject pi_obj = env->CallObjectMethod(pm_obj, package_info_id, pkg_str, 64);// 获得应用包的信息 jclass pi_clazz = env->GetObjectClass(pi_obj);// 获得 PackageInfo 类 jfieldID signatures_fieldId = env->GetFieldID(pi_clazz, "signatures", "[Landroid/content/pm/Signature;");// 获得签名数组属性的 ID jobject signatures_obj = env->GetObjectField(pi_obj, signatures_fieldId); jobjectArray signaturesArray = (jobjectArray) signatures_obj; jsize size = env->GetArrayLength(signaturesArray); jobject signature_obj = env->GetObjectArrayElement(signaturesArray, 0); jclass signature_clazz = env->GetObjectClass(signature_obj); jmethodID string_id = env->GetMethodID(signature_clazz, "toCharsString", "()Ljava/lang/String;"); jstring str = static_cast(env->CallObjectMethod(signature_obj, string_id)); char *c_msg = (char *) env->GetStringUTFChars(str, 0); if(strcmp(c_msg,key)==0) return true; else return false; }}
使用方法
JNIEXPORTjbooleanJava_com_xxx_xxx_xxx_xxx_KeyIsVail(JNIEnv *env, jobject contextObject){ if (CourseKeyIsVail(env,contextObject,getServerKey())) return 1; else return 0;}Java层的代码是 public native boolean KeyIsVail();
更多相关文章
- android获得屏幕高度和宽度
- Android中获得SD卡中的值
- Android(安卓)studio 签名 报错:Could not download groovy-all.j
- 获取Android版本信息和电话信息
- Android中获得SD卡中的值
- Android中获得SD卡中的值
- Android中获得SD卡中的值
- android粗略获得程序运行时间的方法
- Android自动打包、签名、优化、上传ANT脚本