From 38957d94079b81a6506a3335f343bc5ec788486d Mon Sep 17 00:00:00 2001
From: CounterFire2023 <136581895+CounterFire2023@users.noreply.github.com>
Date: Mon, 21 Aug 2023 10:26:24 +0800
Subject: [PATCH] save temporary
---
app/AndroidManifest.xml | 15 ++-
.../com/cege/games/release/MainActivity.java | 91 +++++++++++--------
.../release/activity/BiometricActivity.java | 44 ++++++---
app/src/com/jc/jcfw/JcSDK.java | 27 +++++-
.../com/jc/jcfw/security/BiometricHelper.java | 19 ++--
.../com/jc/jcfw/security/BiometricResult.java | 61 +++++++++++++
.../security/CryptographyManagerImpl.java | 4 +
app/src/com/jc/jcfw/util/Installation.java | 56 ++++++++++++
res/values/styles.xml | 5 +
9 files changed, 256 insertions(+), 66 deletions(-)
create mode 100644 app/src/com/jc/jcfw/security/BiometricResult.java
create mode 100644 app/src/com/jc/jcfw/util/Installation.java
diff --git a/app/AndroidManifest.xml b/app/AndroidManifest.xml
index b1b25d8..ec4b8b0 100644
--- a/app/AndroidManifest.xml
+++ b/app/AndroidManifest.xml
@@ -5,6 +5,7 @@
+ android:theme="@style/DayNightActivity"
+ android:screenOrientation="sensorLandscape"
+ android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|layoutDirection"
+ />
@@ -203,6 +207,9 @@
+
@@ -222,7 +229,6 @@
android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
tools:ignore="ProtectedPermissions" />
-
+
+
diff --git a/app/src/com/cege/games/release/MainActivity.java b/app/src/com/cege/games/release/MainActivity.java
index b053e65..2f6fa72 100644
--- a/app/src/com/cege/games/release/MainActivity.java
+++ b/app/src/com/cege/games/release/MainActivity.java
@@ -4,6 +4,8 @@ import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRON
import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL;
import android.Manifest;
+import android.accounts.Account;
+import android.accounts.AccountManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -35,7 +37,6 @@ import com.bytedance.sdk.open.tiktok.base.VideoObject;
import com.bytedance.sdk.open.tiktok.share.Share;
import com.cege.games.release.activity.BiometricActivity;
import com.cege.games.release.activity.CustomCaptureActivity;
-import com.cege.games.release.activity.UnityPlayerActivity;
import com.cege.games.release.activity.WebPageActivity;
import com.cege.games.release.apple.AppleLoginActivity;
import com.cege.games.release.dialog.QRCodeActivity;
@@ -67,10 +68,12 @@ import com.jc.jcfw.security.BiometricHelper;
import com.jc.jcfw.security.CryptographyManager;
import com.jc.jcfw.security.CryptographyManagerImpl;
import com.jc.jcfw.security.EncryptedData;
+import com.jc.jcfw.util.Installation;
import com.jc.jcfw.util.JsonUtils;
import com.king.zxing.CameraScan;
import com.king.zxing.util.CodeUtils;
import com.king.zxing.util.LogUtils;
+import com.unity3d.player.UnityPlayerActivity;
import net.openid.appauth.AppAuthConfiguration;
import net.openid.appauth.AuthState;
@@ -147,6 +150,7 @@ public class MainActivity extends UnityPlayerActivity
private CountDownLatch mAuthIntentLatch = new CountDownLatch(1);
private TikTokOpenApi tiktokOpenApi;
+
public String getFunId() {
return funId;
}
@@ -160,8 +164,8 @@ public class MainActivity extends UnityPlayerActivity
private FirebaseAnalytics mFirebaseAnalytics;
private AppEventsLogger fbLogger;
- private BiometricPrompt.PromptInfo promptInfo;
- private CryptographyManager cryptographyManager;
+
+ private AccountManager accountManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -204,8 +208,10 @@ public class MainActivity extends UnityPlayerActivity
PayClient payClient = PayClient.getInstance();
payClient.init(this);
- promptInfo = BiometricHelper.createPromptInfo(this);
- cryptographyManager = new CryptographyManagerImpl();
+ accountManager = AccountManager.get(this);
+ String id = Installation.id(this);
+ Log.i(TAG, "custom id:: " + id);
+ Log.i(TAG, "build info::" + Installation.getBuildInfo());
}
@Override
@@ -285,7 +291,6 @@ public class MainActivity extends UnityPlayerActivity
// begin for unity
-
protected void onLoadNativeLibraries() {
try {
ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
@@ -855,15 +860,12 @@ public class MainActivity extends UnityPlayerActivity
public void showPage(String fid, final String url) {
runOnUiThread(() -> {
Log.i(TAG, "show page: " + url);
-// Intent intent = new Intent(this, WebPageActivity.class);
-// intent.putExtra("url", url);
-// Intent intent = new Intent(this, BiometricActivity.class);
-// intent.putExtra("action", "encrypt");
-// intent.putExtra("key", "1111");
-// startActivity(intent);
+ Intent intent = new Intent(this, WebPageActivity.class);
+ intent.putExtra("url", url);
+ startActivity(intent);
// picker video file and share to tiktok
// openFileSelector();
- authenticateToEncrypt("1111");
+ // authenticateToEncrypt("1111");
});
}
@@ -910,32 +912,43 @@ public class MainActivity extends UnityPlayerActivity
startActivityForResult(intent, FILE_SELECTOR_CODE);
}
- public void authenticateToEncrypt(String text) {
- if (BiometricManager.from(this).canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) == BiometricManager
- .BIOMETRIC_SUCCESS) {
- Cipher cipher = cryptographyManager.getInitializedCipherForEncryption("cebg_wallet_key");
- BiometricPrompt biometricPrompt = BiometricHelper.createBiometricPrompt(MainActivity.this, _cipher -> {
- EncryptedData encryptedData = cryptographyManager.encryptData(text, _cipher);
- String encryptedString = Base64.encodeToString(encryptedData.getCiphertext(), Base64.DEFAULT);
- String ivString = Base64.encodeToString(encryptedData.getInitializationVector(), Base64.DEFAULT);
- Log.i(TAG, "encrypted msg: " + encryptedString);
- Log.i(TAG, "encrypted iv: " + ivString);
- });
- biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher));
- }
- }
- public void authenticateToDecrypt(String text, String iv) {
- if (BiometricManager.from(this).canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) == BiometricManager
- .BIOMETRIC_SUCCESS) {
- byte[] ivData = Base64.decode(iv, Base64.DEFAULT);
- byte[] textData = Base64.decode(text, Base64.DEFAULT);
- Cipher cipher = cryptographyManager.getInitializedCipherForDecryption("cebg_wallet_key", ivData);
- BiometricPrompt biometricPrompt = BiometricHelper.createBiometricPrompt(MainActivity.this, _cipher -> {
- String decryptedMsg = cryptographyManager.decryptData(textData, _cipher);
- Log.i(TAG, "decrypted msg: " + decryptedMsg);
- });
- biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher));
- }
+ public void passStorageState(String funid, String account) {
+ Log.i(TAG, "passStorageState with: " + account);
}
+ public void storagePass(String funid, String account, String password) {
+ Log.i(TAG, "storagePass with: " + account + " | " + password);
+
+ // save to account manage
+ final Account act = new Account(account, "main");
+ accountManager.addAccountExplicitly(act, password, null);
+ // runOnUiThread(() -> {
+ // Intent intent = new Intent(this, BiometricActivity.class);
+ // intent.putExtra("action", "encrypt");
+ // intent.putExtra("funid", funId);
+ // intent.putExtra("account", account);
+ // intent.putExtra("password", password);
+ // startActivity(intent);
+ // });
+ }
+
+ public void authGetStoragePass(String funid, String account) {
+ Log.i(TAG, "authGetStoragePass with: " + account);
+ Account[] accounts = accountManager.getAccounts();
+ for (Account act : accounts) {
+ Log.i(TAG, "authGetStoragePass account: " + act.name + " | " + act.type + " | " + accountManager.getPassword(act));
+ }
+ // runOnUiThread(() -> {
+ // Intent intent = new Intent(this, BiometricActivity.class);
+ // intent.putExtra("action", "decrypt");
+ // intent.putExtra("funid", funId);
+ // intent.putExtra("account", account);
+ // startActivity(intent);
+ // });
+ }
+
+ public void getClientId(String funid) {
+ Log.i(TAG, "getClientId ");
+
+ }
}
\ No newline at end of file
diff --git a/app/src/com/cege/games/release/activity/BiometricActivity.java b/app/src/com/cege/games/release/activity/BiometricActivity.java
index 73d5f27..68b633f 100644
--- a/app/src/com/cege/games/release/activity/BiometricActivity.java
+++ b/app/src/com/cege/games/release/activity/BiometricActivity.java
@@ -2,9 +2,11 @@ package com.cege.games.release.activity;
import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG;
import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL;
+import static androidx.biometric.BiometricPrompt.ERROR_USER_CANCELED;
import android.content.Intent;
import android.os.Bundle;
+import android.security.keystore.KeyInfo;
import android.util.Base64;
import android.util.Log;
@@ -34,26 +36,36 @@ public class BiometricActivity extends AppCompatActivity {
cryptographyManager = new CryptographyManagerImpl();
Intent intent = getIntent();
String action = intent.getStringExtra("action");
- String key = intent.getStringExtra("key");
+ String funId = intent.getStringExtra("funid");
+ String account = intent.getStringExtra("account");
// check if action is exists
-// if ("encrypt".equals(action)) {
-// authenticateToEncrypt(key);
-// } else if ("decrypt".equals(action)) {
-// String iv = intent.getStringExtra("iv");
-// authenticateToDecrypt(key, iv);
-// }
+ if ("encrypt".equals(action)) {
+ String password = intent.getStringExtra("password");
+ authenticateToEncrypt(funId, password);
+ } else if ("decrypt".equals(action)) {
+ String iv = intent.getStringExtra("iv");
+ authenticateToDecrypt(account, iv);
+ }
}
- public void authenticateToEncrypt(String text) {
+ public void authenticateToEncrypt(String funId, String text) {
if (BiometricManager.from(this)
.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS) {
Cipher cipher = cryptographyManager.getInitializedCipherForEncryption("cebg_wallet_key");
- BiometricPrompt biometricPrompt = BiometricHelper.createBiometricPrompt(this, _cipher -> {
- EncryptedData encryptedData = cryptographyManager.encryptData(text, _cipher);
+ BiometricPrompt biometricPrompt = BiometricHelper.createBiometricPrompt(this, _result -> {
+ if (_result.isError()) {
+ if (_result.getErrcode() == ERROR_USER_CANCELED) {
+ // close current activity
+ finish();
+ }
+ return;
+ }
+ EncryptedData encryptedData = cryptographyManager.encryptData(text, _result.getCipher());
String encryptedString = Base64.encodeToString(encryptedData.getCiphertext(), Base64.DEFAULT);
String ivString = Base64.encodeToString(encryptedData.getInitializationVector(), Base64.DEFAULT);
Log.i(TAG, "encrypted msg: " + encryptedString);
Log.i(TAG, "encrypted iv: " + ivString);
+ finish();
});
biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher));
}
@@ -65,9 +77,17 @@ public class BiometricActivity extends AppCompatActivity {
byte[] ivData = Base64.decode(iv, Base64.DEFAULT);
byte[] textData = Base64.decode(text, Base64.DEFAULT);
Cipher cipher = cryptographyManager.getInitializedCipherForDecryption("cebg_wallet_key", ivData);
- BiometricPrompt biometricPrompt = BiometricHelper.createBiometricPrompt(this, _cipher -> {
- String decryptedMsg = cryptographyManager.decryptData(textData, _cipher);
+ BiometricPrompt biometricPrompt = BiometricHelper.createBiometricPrompt(this, _result -> {
+ if (_result.isError()) {
+ if (_result.getErrcode() == ERROR_USER_CANCELED) {
+ // close current activity
+ finish();
+ }
+ return;
+ }
+ String decryptedMsg = cryptographyManager.decryptData(textData, _result.getCipher());
Log.i(TAG, "decrypted msg: " + decryptedMsg);
+ finish();
});
biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher));
}
diff --git a/app/src/com/jc/jcfw/JcSDK.java b/app/src/com/jc/jcfw/JcSDK.java
index 9724ab3..2b8e9bb 100644
--- a/app/src/com/jc/jcfw/JcSDK.java
+++ b/app/src/com/jc/jcfw/JcSDK.java
@@ -34,7 +34,7 @@ public class JcSDK {
/**
* @Deprecated
- * 不使用该方法, 直接由unity调用cpp方法
+ * 不使用该方法, 直接由unity调用cpp方法
* @param password
*/
public static void initWallet(String password) {
@@ -58,8 +58,8 @@ public class JcSDK {
* check if metamask installed and jump to metamask
*
* @param url
- * sample:
- * "https://metamask.app.link/wc?uri="+ExampleApplication.config.toWCUri();
+ * sample:
+ * "https://metamask.app.link/wc?uri="+ExampleApplication.config.toWCUri();
*/
public static void toWallet(String url) {
@@ -137,6 +137,7 @@ public class JcSDK {
}
payClient.queryProductList(funid, skuList);
}
+
public static void buyProduct(String funid, String productId, String orderId) {
Log.i(TAG, "buyProduct with: " + productId);
if (payClient == null) {
@@ -153,6 +154,26 @@ public class JcSDK {
payClient.queryPurchase(funid);
}
+ public static void passStorageState(String funid, String account) {
+ Log.i(TAG, "passStorageState with: " + account);
+ MainActivity.app.passStorageState(funid, account);
+ }
+
+ public static void storagePass(String funid, String account, String password) {
+ Log.i(TAG, "storagePass with: " + account);
+ MainActivity.app.storagePass(funid, account, password);
+ }
+
+ public static void authGetStoragePass(String funid, String account) {
+ Log.i(TAG, "authGetStoragePass with: " + account);
+ MainActivity.app.authGetStoragePass(funid, account);
+ }
+
+ public static void getClientId(String funid) {
+ Log.i(TAG, "getClientId ");
+ MainActivity.app.getClientId(funid);
+ }
+
/**
* 回调至js
*/
diff --git a/app/src/com/jc/jcfw/security/BiometricHelper.java b/app/src/com/jc/jcfw/security/BiometricHelper.java
index d7c41e6..3a40475 100644
--- a/app/src/com/jc/jcfw/security/BiometricHelper.java
+++ b/app/src/com/jc/jcfw/security/BiometricHelper.java
@@ -19,6 +19,9 @@ import java.util.function.Consumer;
import javax.crypto.Cipher;
public class BiometricHelper {
+
+ public static final int ERROR_BIOMETRIC_FAIL = 100;
+ public static final int ERROR_BIOMETRIC_NO_CIPHER = 101;
private static final String TAG = BiometricHelper.class.getSimpleName();
public static BiometricPrompt.PromptInfo createPromptInfo(Context context) {
BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()
@@ -34,28 +37,26 @@ public class BiometricHelper {
return promptInfo;
}
- public static BiometricPrompt createBiometricPrompt(FragmentActivity activity, Consumer func) {
+ public static BiometricPrompt createBiometricPrompt(FragmentActivity activity, Consumer func) {
Executor executor = ContextCompat.getMainExecutor(activity.getApplicationContext());
return new BiometricPrompt(activity, executor, new BiometricPrompt.AuthenticationCallback() {
@Override
- public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
- super.onAuthenticationError(errorCode, errString);
- Log.i(TAG, "Authentication error: " + errString);
+ public void onAuthenticationError(int errcode, @NonNull CharSequence errString) {
+ super.onAuthenticationError(errcode, errString);
+ Log.i(TAG, "Authentication error: " + errcode +" | "+ errString);
+ func.accept(new BiometricResult(errcode, (String) errString));
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
Log.i(TAG, "Authentication failed!");
+ func.accept(new BiometricResult(ERROR_BIOMETRIC_FAIL, "Authentication failed"));
}
@Override
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
Log.i(TAG, "Authentication succeeded!");
- try {
- func.accept(result.getCryptoObject().getCipher());
- } catch (Exception e) {
- Log.e("BiometricHelper", e.getMessage());
- }
+ func.accept(new BiometricResult(result.getCryptoObject().getCipher()));
}
});
}
diff --git a/app/src/com/jc/jcfw/security/BiometricResult.java b/app/src/com/jc/jcfw/security/BiometricResult.java
new file mode 100644
index 0000000..45b31a8
--- /dev/null
+++ b/app/src/com/jc/jcfw/security/BiometricResult.java
@@ -0,0 +1,61 @@
+package com.jc.jcfw.security;
+
+import androidx.annotation.Nullable;
+
+import javax.crypto.Cipher;
+
+public class BiometricResult {
+ private Cipher cipher;
+ private boolean error;
+ private int errcode;
+ private String errmsg;
+
+ public BiometricResult(Cipher cipher) {
+ if (null != cipher) {
+ this.cipher = cipher;
+ this.error = false;
+ } else {
+ this.error = true;
+ this.errcode = 101;
+ this.errmsg = "cipher is null";
+ }
+ }
+
+ public BiometricResult(int errcode, String errmsg) {
+ this.error = true;
+ this.errcode = errcode;
+ this.errmsg = errmsg;
+ }
+ @Nullable
+ public Cipher getCipher() {
+ return cipher;
+ }
+
+ public void setCipher(Cipher cipher) {
+ this.cipher = cipher;
+ }
+
+ public boolean isError() {
+ return error;
+ }
+
+ public void setError(boolean error) {
+ this.error = error;
+ }
+
+ public int getErrcode() {
+ return errcode;
+ }
+
+ public void setErrcode(int errcode) {
+ this.errcode = errcode;
+ }
+
+ public String getErrmsg() {
+ return errmsg;
+ }
+
+ public void setErrmsg(String errmsg) {
+ this.errmsg = errmsg;
+ }
+}
diff --git a/app/src/com/jc/jcfw/security/CryptographyManagerImpl.java b/app/src/com/jc/jcfw/security/CryptographyManagerImpl.java
index f23443b..856aa7f 100644
--- a/app/src/com/jc/jcfw/security/CryptographyManagerImpl.java
+++ b/app/src/com/jc/jcfw/security/CryptographyManagerImpl.java
@@ -5,15 +5,19 @@ import static android.security.keystore.KeyProperties.ENCRYPTION_PADDING_PKCS7;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
+import android.util.Log;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
import java.security.KeyStore;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
public class CryptographyManagerImpl implements CryptographyManager {
diff --git a/app/src/com/jc/jcfw/util/Installation.java b/app/src/com/jc/jcfw/util/Installation.java
new file mode 100644
index 0000000..4e65f02
--- /dev/null
+++ b/app/src/com/jc/jcfw/util/Installation.java
@@ -0,0 +1,56 @@
+package com.jc.jcfw.util;
+
+import android.content.Context;
+import android.os.Build;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.UUID;
+
+public class Installation {
+ private static String sID = null;
+ private static final String INSTALLATION = "INSTALLATION";
+
+ public synchronized static String id(Context context) {
+ if (sID == null) {
+ File installation = new File(context.getFilesDir(), INSTALLATION);
+ try {
+ if (!installation.exists())
+ writeInstallationFile(installation);
+ sID = readInstallationFile(installation);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return sID;
+ }
+
+ private static String readInstallationFile(File installation) throws IOException {
+ RandomAccessFile f = new RandomAccessFile(installation, "r");
+ byte[] bytes = new byte[(int) f.length()];
+ f.readFully(bytes);
+ f.close();
+ return new String(bytes);
+ }
+
+ private static void writeInstallationFile(File installation) throws IOException {
+ FileOutputStream out = new FileOutputStream(installation);
+ String id = UUID.randomUUID().toString();
+ out.write(id.getBytes());
+ out.close();
+ }
+
+ public static String getBuildInfo() {
+//这里选用了几个不会随系统更新而改变的值
+ StringBuffer buildSB = new StringBuffer();
+ buildSB.append(Build.BRAND).append("/");
+ buildSB.append(Build.PRODUCT).append("/");
+ buildSB.append(Build.DEVICE).append("/");
+ buildSB.append(Build.ID).append("/");
+ buildSB.append(Build.VERSION.INCREMENTAL);
+ return buildSB.toString();
+// return Build.FINGERPRINT;
+ }
+}
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a255e0d..e867333 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -14,6 +14,11 @@
- true
- @android:style/Animation.Translucent
+