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();

更多相关文章

  1. Glide使用方法汇总
  2. [android]布局(容器)简介和使用方法
  3. 【Android 开发】:Android五种布局的使用方法
  4. android下拉菜单spinner的使用方法
  5. Android HandlerThread使用方法
  6. 【Android 开发】:UI控件之拖动条控件 SeekBar的使用方法

随机推荐

  1. android 源码的一些修改定制方案
  2. 禁止状态栏下拉
  3. Android intent 传递数组对象序列化
  4. Android监听Dialog点击外部区域
  5. ffmpeg compile with neon support for a
  6. android 背光控制 HAL层分析
  7. android sdk不fq更新方案
  8. Android自动判定输入的是电话号码还是网
  9. android实现截屏
  10. android 首页fragment切换