Merge pull request #34 from xianglin1998/master

Removed module "Crapto1" to maven(gitpack.io)
This commit is contained in:
DXL
2020-04-06 17:29:08 +08:00
committed by GitHub
14 changed files with 2 additions and 815 deletions
+1 -1
View File
@@ -54,11 +54,11 @@ dependencies {
// This my project maven from github release!
implementation 'com.github.xianglin1998:IORedirector:1.0'
implementation 'com.github.xianglin1998:Crapto1:1.2'
implementation project(':utils')
implementation project(':mfkey_32_64')
implementation project(':libnfc_pn53x')
implementation project(':crapto1')
implementation project(':console')
implementation project(':chameleon')
implementation project(':communication')
-62
View File
@@ -1,62 +0,0 @@
# Built application files
*.apk
*.ap_
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Cmake gen
.cxx/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# IntelliJ
*.iml
.idea/
# Keystore files
# Uncomment the following line if you do not want to check your keystore files in.
#*.jks
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
# Google Services (e.g. APIs or Firebase)
google-services.json
# Freeline
freeline.py
freeline/
freeline_project_description.json
# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md
-43
View File
@@ -1,43 +0,0 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
minSdkVersion 19
targetSdkVersion 29
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_static'
abiFilters "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
}
//abiFilters "armeabi"
/*abiFilters "arm64-v8a"*/
/*abiFilters "x86_64"*/
/*abiFilters "arm64-v8a"
abiFilters "mips"
abiFilters "mips64"
abiFilters "x86"
abiFilters "x86_64"*/
}
}
externalNativeBuild {
cmake {
version '3.10.2'
path 'src/main/cpp/CMakeLists.txt'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
}
-21
View File
@@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-2
View File
@@ -1,2 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.rrg.crapto1" />
-20
View File
@@ -1,20 +0,0 @@
#需要的最cmake版本
cmake_minimum_required(VERSION 3.4.1)
#进行库(动态)的添加,在之后的参数中引入cpp/c文件
add_library(
crapto1 SHARED
crapto1.c
crypto1.c
main.c)
#进行头文件的添加!
target_include_directories(crapto1 PRIVATE
../libnfc/include/
${CMAKE_CURRENT_SOURCE_DIR}/include)
#进行最终动态库的链接!
target_link_libraries(
crapto1
android
log)
-251
View File
@@ -1,251 +0,0 @@
#include <stdlib.h>
#include "crapto1.h"
#include "crypto1.h"
#pragma package(smart_init)
#if !defined LOWMEM && defined __GNUC__
static uint8_t filterlut[1 << 20];
static void __attribute__((constructor)) fill_lut() {
uint32_t i;
for (i = 0; i < 1 << 20; ++i)
filterlut[i] = filter(i);
}
#define filter(x) (filterlut[(x) & 0xfffff])
#endif
/* quicksort
* in place quicksort of table
*/
static void
quicksort(uint32_t *const start, uint32_t *const stop) {
uint32_t *it = start + 1, *rit = stop;
if (it > rit)
return;
while (it < rit)
if (*it < *start)
++it;
else if (*rit >= *start)
--rit;
else
*it ^= (*it ^= *rit, *rit ^= *it);
if (*rit >= *start)
--rit;
if (rit != start)
*rit ^= (*rit ^= *start, *start ^= *rit);
quicksort(start, rit - 1);
quicksort(rit + 1, stop);
}
/* binsearch
* Binary search for the first occurence of *stop's MSB in sorted [start,stop]
*/
static inline uint32_t *
binsearch(uint32_t *start, uint32_t *stop) {
uint32_t mid, val = *stop & 0xff000000;
while (start != stop)
if (start[mid = (stop - start) >> 1] > val)
stop = &start[mid];
else
start += mid + 1;
return start;
}
/* update_contribution
* helper, calculates the partial linear feedback contributions and puts in MSB
*/
static inline void
update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2) {
uint32_t p = *item >> 25;
p = p << 1 | parity(*item & mask1);
p = p << 1 | parity(*item & mask2);
*item = p << 24 | (*item & 0xffffff);
}
/* extend_table
* using a bit of the keystream extend the table of possible lfsr states
*/
static inline void
extend_table(uint32_t *tbl, uint32_t **end, int bit, uint32_t m1, uint32_t m2) {
for (; tbl <= *end; tbl++)
if (filter(*tbl <<= 1) == bit) {
if (filter(*tbl | 1) == bit) {
*++*end = tbl[1];
tbl[1] = tbl[0] | 1;
update_contribution(tbl++, m1, m2);
}
update_contribution(tbl, m1, m2);
} else if (filter(*tbl |= 1) == bit)
update_contribution(tbl, m1, m2);
else
*tbl-- = *(*end)--;
}
/* recover
* recursively narrow down the search space, 4 bits of keystream at a time
*/
static uint32_t *
recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem) {
uint32_t *o, *e, i;
if (rem == -1) {
o_head[1] = *e_head << 1;
*e_head &= LF_POLY_EVEN;
o_head[1] |= parity(*e_head ^ *o_head & LF_POLY_ODD);
return o_head;
}
for (i = 0; i < 4 && rem--; i++) {
extend_table(o_head, &o_tail, (oks >>= 1) & 1, LF_POLY_ODD * 2, LF_POLY_EVEN * 2 + 1);
extend_table(e_head, &e_tail, (eks >>= 1) & 1, LF_POLY_EVEN * 2 + 1, LF_POLY_ODD);
}
quicksort(o_head, o_tail);
quicksort(e_head, e_tail);
while (o_tail >= o_head && e_tail >= e_head)
if ((*o_tail ^ *e_tail) >> 24 == 0) {
o_tail = binsearch(o_head, o = o_tail);
e_tail = binsearch(e_head, e = e_tail);
if (e = recover(o_tail--, o, oks, e_tail--, e, eks, rem))
return e;
} else if (*o_tail > *e_tail)
--o_tail;
else
--e_tail;
return 0;
}
/* lfsr_recovery
* recover the state of the lfsr given a part of the keystream
*/
struct Crypto1State *lfsr_recovery(uint32_t ks2, uint32_t ks3) {
uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
uint32_t *even_head = 0, *even_tail = 0, eks = 0, *res;
struct Crypto1State *state = crypto1_create(-1);
int i;
for (i = 31; i >= 0; i -= 2)
oks = oks << 1 | BEBIT(ks2, i) | BEBIT(ks3, i) << 16;
for (i = 30; i >= 0; i -= 2)
eks = eks << 1 | BEBIT(ks2, i) | BEBIT(ks3, i) << 16;
odd_head = odd_tail = (uint32_t *) malloc(sizeof(uint32_t) << 21);
even_head = even_tail = (uint32_t *) malloc(sizeof(uint32_t) << 21);
if (!odd_tail-- || !even_tail--)
goto out;
for (i = 1 << 20; i >= 0; --i) {
if (filter(i) == (oks & 1))
*++odd_tail = i;
if (filter(i) == (eks & 1))
*++even_tail = i;
}
for (i = 0; i < 4; i++) {
extend_table(odd_head, &odd_tail, (oks >>= 1) & 1, 0, 0);
extend_table(even_head, &even_tail, (eks >>= 1) & 1, 0, 0);
}
res = recover(odd_head, odd_tail, oks, even_head, even_tail, eks, 27);
if (res) {
state->odd = res[1];
state->even = res[0];
}
out:
free(odd_head);
free(even_head);
return state;
}
/* Variation mentioned in the paper. Borked due to omitted constants.
* comform the above version given 64 bits of keystream, it returns a possible
* cipher state if any.
* It can be optimized dramatically but since it was borked a somewhat readable
* and above all short version is included.
*/
#define MAGIX1 (0)
#define MAGIX2 (0) /* Well this number isn't that magical ... */
struct Crypto1State *lfsr_recovery_borked(uint32_t ks2, uint32_t ks3) {
struct Crypto1State *state = crypto1_create(-1);
uint32_t win = 0, oks = 0, eks = 0, tes, tos;
uint64_t cmb, *table = (uint64_t *) malloc(1 << 25), *tail = table - 1, *tbl;
int i;
for (i = 0; i < 32; i += 2)
oks = oks << 1 | BEBIT(ks3, i) | BEBIT(ks2, i) << 16;
for (i = 1; i < 32; i += 2)
eks = eks << 1 | BEBIT(ks3, i) | BEBIT(ks2, i) << 16;
for (i = 0; i < 1 << 20; ++i)
if (filter(i) == BIT(oks, 31))
*++tail = i;
for (i = 30; i > 2; --i)
for (*(tbl = table) <<= 1; tbl <= tail; *++tbl <<= 1)
if (filter(*tbl) ^ filter(*tbl | 1))
*tbl |= (filter(*tbl) != BIT(oks, i));
else if (filter(*tbl) == BIT(oks, i)) {
*++tail = *++tbl;
*tbl = tbl[-1] | 1;
} else
*tbl-- = *tail--;
for (; tail >= table; --tail) {
cmb = MAGIX1;
for (i = 0; i < 51; ++i) {
win = win << 1 ^ par64(*tail & cmb);
tes = tes << 1 ^ filter(win);
cmb = cmb >> 1 ^ -(cmb & 1) & MAGIX2;
}
for (i = 2; i >= 0; --i) {
*tail = *tail << 1 | par64(*tail & MAGIX2);
tos = tos << 1 | filter(*tail);
}
if (tes == eks && (tos & 7) == (oks & 7)) {
state->odd = *tail << 1 | par64(*tail & MAGIX2);
state->even = win;
}
}
free(table);
return state;
}
/* lfsr_rollback
* Rollback the shift register in order to get previous states
*/
void lfsr_rollback(struct Crypto1State *s, uint32_t in, int fb) {
int i, out;
s->odd &= 0xffffff;
s->even &= 0xffffff;
for (i = 31; i >= 0; --i) {
s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
out = s->even & 1;
out ^= LF_POLY_EVEN & (s->even >>= 1);
out ^= LF_POLY_ODD & s->odd;
out ^= BEBIT(in, i);
out ^= filter(s->odd) & !!fb;
s->even |= parity(out) << 23;
}
}
-90
View File
@@ -1,90 +0,0 @@
/* crypto1.c
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, US
Copyright (C) 2008-2008 bla <blapost@gmail.com>
*/
#include "crapto1.h"
#include <stdlib.h>
#define SWAPENDIAN(x)\
(x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
struct Crypto1State *crypto1_create(uint64_t key) {
struct Crypto1State *s = malloc(sizeof(*s));
int i;
for (i = 47; s && i > 0; i -= 2) {
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
s->even = s->even << 1 | BIT(key, i ^ 7);
}
return s;
}
void crypto1_destroy(struct Crypto1State *state) {
free(state);
}
void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr) {
int i;
for (*lfsr = 0, i = 23; i >= 0; --i) {
*lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
*lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
}
}
uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted) {
uint32_t feedin;
uint8_t ret = filter(s->odd);
feedin = ret & !!is_encrypted;
feedin ^= !!in;
feedin ^= LF_POLY_ODD & s->odd;
feedin ^= LF_POLY_EVEN & s->even;
s->even = s->even << 1 | parity(feedin);
s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
return ret;
}
uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted) {
uint8_t i, ret = 0;
for (i = 0; i < 8; ++i)
ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i;
return ret;
}
uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted) {
uint32_t i, ret = 0;
for (i = 0; i < 32; ++i)
ret |= crypto1_bit(s, BEBIT(in, i), is_encrypted) << (i ^ 24);
return ret;
}
/* prng_successor
* helper used to obscure the keystream during authentication
*/
uint32_t prng_successor(uint32_t x, uint32_t n) {
SWAPENDIAN(x);
while (n--)
x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
return SWAPENDIAN(x);
}
-57
View File
@@ -1,57 +0,0 @@
//---------------------------------------------------------------------------
#ifndef crapto1H
#define crapto1H
//---------------------------------------------------------------------------
#include "crypto1.h"
#include <stdint.h>
struct Crypto1State {
unsigned int odd, even;
};
struct Crypto1State *crypto1_create(uint64_t key);
void crypto1_destroy(struct Crypto1State *state);
void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr);
unsigned int crypto1_word(struct Crypto1State *state, unsigned int in_word, int fb);
unsigned int prng_successor(unsigned int x, unsigned int n);
struct Crypto1State *lfsr_recovery(unsigned int ks2, unsigned int ks3);
struct Crypto1State *lfsr_recovery_borked(unsigned int ks2, unsigned int ks3);
void lfsr_rollback(struct Crypto1State *s, unsigned int in, int fb);
#define LF_POLY_ODD (0x29CE5C)
#define LF_POLY_EVEN (0x870804)
#define BIT(x, n) ((x) >> (n) & 1)
#define BEBIT(x, n) ((x) >> ((n) ^ 24) & 1)
static inline int parity(unsigned int x) {
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
return BIT(0x6996, x & 0xf);
}
static inline int par64(uint64_t x) {
return parity(x ^ x >> 32);
}
static inline int filter(unsigned int const x) {
unsigned int f;
f = 0xf22c0 >> (x & 0xf) & 16;
f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8;
f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4;
f |= 0x1e458 >> (x >> 12 & 0xf) & 2;
f |= 0x0d938 >> (x >> 16 & 0xf) & 1;
return BIT(0xEC57E80A, f);
}
#endif
-19
View File
@@ -1,19 +0,0 @@
//---------------------------------------------------------------------------
#ifndef crypto1H
#define crypto1H
//---------------------------------------------------------------------------
#include "crapto1.h"
#include <stdlib.h>
struct Crypto1State *crypto1_create(uint64_t key);
void crypto1_destroy(struct Crypto1State *state);
void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr);
unsigned int crypto1_word(struct Crypto1State *s, unsigned int in_word, int fb);
unsigned int prng_successor(unsigned int x, unsigned int n);
#endif
-183
View File
@@ -1,183 +0,0 @@
#include <stdbool.h>
#include <ctype.h>
#include <inttypes.h>
#include <crapto1.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <jni.h>
//转为小写字符串!
char *strupr(char *str) {
char *ret = str;
char *tmp = ret;
//测试长度!
size_t len = strlen(tmp);
while (len != 0 && tmp != NULL) {
*str = (char) toupper(*tmp);
--len;
++tmp;
++str;
}
return ret;
}
struct CHexMap {
char chr;
int value;
};
const int HexMapL = 16;
struct CHexMap HexMap[HexMapL] = {
{'0', 0},
{'1', 1},
{'2', 2},
{'3', 3},
{'4', 4},
{'5', 5},
{'6', 6},
{'7', 7},
{'8', 8},
{'9', 9},
{'A', 10},
{'B', 11},
{'C', 12},
{'D', 13},
{'E', 14},
{'F', 15}
};
//16进制字符串转整形!
uint32_t httoi(const char *value) {
//拷贝一份新的!
char *newCs = strdup(value);
char *s = strupr(newCs);;
uint32_t result = 0;
if (*s == '0' && *(s + 1) == 'X') s += 2;
bool firsttime = true;
while (*s != '\0') {
bool found = false;
for (int i = 0; i < HexMapL; i++) {
if (*s == HexMap[i].chr) {
if (!firsttime) result <<= 4;
result |= HexMap[i].value;
found = true;
break;
}
}
if (!found) break;
s++;
firsttime = false;
}
//LOGD("尝试输出字符值: %s", mstr);
free(newCs);
return result;
}
//主函数,进行最终的线性反馈寄存器算法回滚!
uint64_t finalKey(const char *id, const char *tc, const char *rc, const char *rr, const char *tr) {
struct Crypto1State *revstate;
uint64_t lfsr;
//获得输入框得UID
uint32_t uid = httoi(id);
//LOGD("测试输出ID %u", uid);
//获得TAG得收集信息!
uint32_t tag_challenge = httoi(tc);
//LOGD("测试输出TC %u", tag_challenge);
//获得ENC
uint32_t nr_enc = httoi(rc);
//LOGD("测试输出RC %u", nr_enc);
//获得来自于读卡器得应答
uint32_t reader_response = httoi(rr);
//LOGD("测试输出RR %u", reader_response);
//获得来自于标签得应答
uint32_t tag_response = httoi(tr);
//LOGD("测试输出TR %u", tag_response);
//进行ks计算
uint32_t ks2 = reader_response ^prng_successor(tag_challenge, 64);
uint32_t ks3 = tag_response ^prng_successor(tag_challenge, 96);
//调用线性反馈寄存器关键函数进行计算
revstate = lfsr_recovery(ks2, ks3);
//尝试回滚
lfsr_rollback(revstate, 0, 0);
//第二次尝试回滚
lfsr_rollback(revstate, 0, 0);
//通过nr尝试回滚
lfsr_rollback(revstate, nr_enc, 1);
//通过uid与关键信息进行回滚
lfsr_rollback(revstate, uid ^ tag_challenge, 0);
//得到关键密钥
crypto1_get_lfsr(revstate, &lfsr);
//回收内存!
crypto1_destroy(revstate);
//返回最终结果
return lfsr;
}
//映射函数,两端映射,类型转换!
jstring
final(JNIEnv *env, jobject instance, jstring hexID, jstring hexTC, jstring hexRC, jstring hexRR,
jstring hexTR) {
if (hexID == NULL || hexTC == NULL || hexRC == NULL || hexRR == NULL || hexTR == NULL) {
return NULL;
}
jboolean isCopy = false;
//获得字符数组!
const char *id = (*env)->GetStringUTFChars(env, hexID, &isCopy);
//const jint idLen = (*env)->GetStringUTFLength(env, hexID);
// LOGD("final ID: %s", id);
const char *tc = (*env)->GetStringUTFChars(env, hexTC, &isCopy);
//const jint tcLen = (*env)->GetStringUTFLength(env, hexTC);
//LOGD("final TC: %s", tc);
const char *rc = (*env)->GetStringUTFChars(env, hexRC, &isCopy);
//const jint rcLen = (*env)->GetStringUTFLength(env, hexRC);
//LOGD("final RC: %s", rc);
const char *rr = (*env)->GetStringUTFChars(env, hexRR, &isCopy);
//const jint rrLen = (*env)->GetStringUTFLength(env, hexRR);
//LOGD("final RR: %s", rr);
const char *tr = (*env)->GetStringUTFChars(env, hexTR, &isCopy);
//const jint trLen = (*env)->GetStringUTFLength(env, hexTR);
//LOGD("final TR: %s", tr);
//调用主要的逻辑函数,进行计算!
uint64_t key = finalKey(id, tc, rc, rr, tr);
//谨记释放!
(*env)->ReleaseStringUTFChars(env, hexID, id);
(*env)->ReleaseStringUTFChars(env, hexTC, tc);
(*env)->ReleaseStringUTFChars(env, hexRC, rc);
(*env)->ReleaseStringUTFChars(env, hexRR, rr);
(*env)->ReleaseStringUTFChars(env, hexTR, tr);
//进行格式化转换!
char keyChars[13] = {0};
memset(keyChars, 0, sizeof(keyChars));
sprintf(keyChars, "%012"PRIX64, key);
//LOGD("输出测试的64位值: %lu", key);
//LOGD("输出测试的密钥: %s", keyChars);
return (*env)->NewStringUTF(env, keyChars);
}
/*
* jvm加载so时的映射回调
* */
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *jniEnv = NULL;
//得到当前的jvm环境指针
if ((*vm)->GetEnv(vm, (void **) &jniEnv, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
//得到native函数的定义类
jclass clazz = (*jniEnv)->FindClass(jniEnv, "cn/rrg/maps/Crapto1Tools");
if (clazz == NULL) {
return -1;
}
//构建和初始化函数结构体,分别是java层的函数名称,签名,对应的函数指针
JNINativeMethod methods[] = {
{"finalKeyNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void *) final},
};
//注册函数
if ((*jniEnv)->RegisterNatives(jniEnv, clazz, methods,
sizeof(methods) / sizeof(methods[0])) !=
JNI_OK) {
return -1;
}
//最后一定要返回jni的版本。
return JNI_VERSION_1_4;
}
@@ -1,62 +0,0 @@
package cn.rrg.crapto1;
/*
* 此class用于crapto1算法的回滚计算!
* */
public class Crapto1Tools {
static {
//加载动态库!
System.loadLibrary("crapto1");
}
private String mHexId = null;
private String mHexTC = null;
private String mHexRC = null;
private String mHexRR = null;
private String mHexTR = null;
public Crapto1Tools setUid(String hexID) {
mHexId = hexID;
return this;
}
public Crapto1Tools setTagChallenge(String hexTC) {
mHexTC = hexTC;
return this;
}
public Crapto1Tools setReaderChallenge(String hexRC) {
mHexRC = hexRC;
return this;
}
public Crapto1Tools setReaderResponse(String hexRR) {
mHexRR = hexRR;
return this;
}
public Crapto1Tools setTagResponse(String hexTR) {
mHexTR = hexTR;
return this;
}
public String finalKey() {
//非空判定!
if (mHexId == null || mHexTC == null ||
mHexRC == null || mHexRR == null || mHexTR == null)
return null;
//格式判定!
if (invailV(mHexId) || invailV(mHexTC)
|| invailV(mHexRC) || invailV(mHexRR) || invailV(mHexTR)) {
return null;
}
return finalKeyNative(mHexId, mHexTC, mHexRC, mHexRR, mHexTR);
}
private boolean invailV(String v) {
return v.length() != 8 || !v.matches("[A-Za-z0-9]+");
}
private native String finalKeyNative(String id, String tc, String rc, String rr, String tr);
}
-3
View File
@@ -1,3 +0,0 @@
<resources>
<string name="app_name">Crapto1</string>
</resources>
+1 -1
View File
@@ -1,2 +1,2 @@
include ':app_main', ':utils', ':crapto1', ':mfkey_32_64', ':console', ':chameleon', ':communication', ':libnfc_pn53x', ':pm3official', ':pm3iceman', ':pm3rdv4rrg', ':mifaretag'
include ':app_main', ':utils', ':mfkey_32_64', ':console', ':chameleon', ':communication', ':libnfc_pn53x', ':pm3official', ':pm3iceman', ':pm3rdv4rrg', ':mifaretag'
include ':pm3flasher'