mirror of
https://github.com/wrwrabbit/Partisan-Telegram-Android.git
synced 2026-05-05 23:51:00 +00:00
Update to 5.13.0 (1818)
This commit is contained in:
parent
28eb8dfd0e
commit
f41b228a11
2574 changed files with 1023378 additions and 62330 deletions
|
|
@ -8,22 +8,173 @@
|
|||
|
||||
package org.telegram.ui;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.security.keystore.KeyGenParameterSpec;
|
||||
import android.security.keystore.KeyPermanentlyInvalidatedException;
|
||||
import android.security.keystore.KeyProperties;
|
||||
import android.util.Base64;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.messenger.support.fingerprint.FingerprintManagerCompat;
|
||||
import org.telegram.ui.ActionBar.ActionBar;
|
||||
import org.telegram.ui.ActionBar.BaseFragment;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.EditTextBoldCursor;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.MediaActionDrawable;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.spec.MGF1ParameterSpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.OAEPParameterSpec;
|
||||
import javax.crypto.spec.PSource;
|
||||
|
||||
import androidx.core.os.CancellationSignal;
|
||||
|
||||
@TargetApi(23)
|
||||
public class TestActivity extends BaseFragment {
|
||||
|
||||
int num = 0;
|
||||
int p = 0;
|
||||
private EditTextBoldCursor codeField;
|
||||
|
||||
private KeyStore keyStore;
|
||||
private KeyPairGenerator keyPairGenerator;
|
||||
private String encryptedString;
|
||||
private Cipher cipher;
|
||||
|
||||
private FingerprintHelper fingerprintHelper;
|
||||
|
||||
private static final String KEY_NAME = "wallet_key11";
|
||||
|
||||
@Override
|
||||
public boolean onFragmentCreate() {
|
||||
try {
|
||||
keyStore = KeyStore.getInstance("AndroidKeyStore");
|
||||
keyStore.load(null);
|
||||
keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
|
||||
cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
|
||||
} catch (Exception exception) {
|
||||
FileLog.e(exception);
|
||||
}
|
||||
|
||||
return super.onFragmentCreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFragmentDestroy() {
|
||||
super.onFragmentDestroy();
|
||||
if (encryptedString != null) {
|
||||
SharedPreferences preferences = MessagesController.getMainSettings(UserConfig.selectedAccount);
|
||||
preferences.edit().remove("test_enc").commit();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean createKeyPair() {
|
||||
try {
|
||||
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
|
||||
.setDigests(KeyProperties.DIGEST_SHA1, KeyProperties.DIGEST_SHA256)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
|
||||
.setKeySize(2048);
|
||||
builder.setIsStrongBoxBacked(true);
|
||||
builder.setInvalidatedByBiometricEnrollment(true);
|
||||
builder.setUserAuthenticationRequired(true);
|
||||
|
||||
keyPairGenerator.initialize(builder.build());
|
||||
keyPairGenerator.generateKeyPair();
|
||||
return true;
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isKeyCreated() {
|
||||
try {
|
||||
return keyStore.containsAlias(KEY_NAME) || createKeyPair();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean initCipher(int mode) {
|
||||
try {
|
||||
switch (mode) {
|
||||
case Cipher.ENCRYPT_MODE: {
|
||||
PublicKey key = keyStore.getCertificate(KEY_NAME).getPublicKey();
|
||||
PublicKey unrestricted = KeyFactory.getInstance(key.getAlgorithm()).generatePublic(new X509EncodedKeySpec(key.getEncoded()));
|
||||
OAEPParameterSpec spec = new OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT);
|
||||
cipher.init(mode, unrestricted, spec);
|
||||
break;
|
||||
}
|
||||
case Cipher.DECRYPT_MODE: {
|
||||
PrivateKey key = (PrivateKey) keyStore.getKey(KEY_NAME, null);
|
||||
OAEPParameterSpec spec = new OAEPParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT);
|
||||
cipher.init(mode, key, spec);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (KeyPermanentlyInvalidatedException exception) {
|
||||
deleteInvalidKey();
|
||||
} catch (UnrecoverableKeyException e) {
|
||||
deleteInvalidKey();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void deleteInvalidKey() {
|
||||
try {
|
||||
keyStore.deleteEntry(KEY_NAME);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String encode(String inputString) {
|
||||
try {
|
||||
if (isKeyCreated() && initCipher(Cipher.ENCRYPT_MODE)) {
|
||||
byte[] bytes = cipher.doFinal(inputString.getBytes());
|
||||
return Base64.encodeToString(bytes, Base64.NO_WRAP);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String decode(String encodedString, Cipher cipherDecrypter) {
|
||||
try {
|
||||
byte[] bytes = Base64.decode(encodedString, Base64.NO_WRAP);
|
||||
return new String(cipherDecrypter.doFinal(bytes));
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View createView(Context context) {
|
||||
|
|
@ -41,30 +192,109 @@ public class TestActivity extends BaseFragment {
|
|||
});
|
||||
|
||||
FrameLayout frameLayout = new FrameLayout(context);
|
||||
frameLayout.setBackgroundColor(0xff000000);
|
||||
frameLayout.setBackgroundColor(0xffffffff);
|
||||
fragmentView = frameLayout;
|
||||
|
||||
MediaActionDrawable actionDrawable2 = new MediaActionDrawable();
|
||||
actionDrawable2.setIcon(MediaActionDrawable.ICON_DOWNLOAD, false);
|
||||
codeField = new EditTextBoldCursor(context);
|
||||
codeField.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
|
||||
codeField.setCursorColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
|
||||
codeField.setCursorSize(AndroidUtilities.dp(20));
|
||||
codeField.setCursorWidth(1.5f);
|
||||
codeField.setHintTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteHintText));
|
||||
codeField.setBackgroundDrawable(Theme.createEditTextDrawable(context, false));
|
||||
codeField.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||
codeField.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
|
||||
codeField.setMaxLines(1);
|
||||
codeField.setPadding(0, 0, 0, 0);
|
||||
codeField.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
|
||||
frameLayout.addView(codeField, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36, Gravity.CENTER_HORIZONTAL, 10, 20, 10, 0));
|
||||
|
||||
ImageView imageView = new ImageView(context);
|
||||
imageView.setImageDrawable(actionDrawable2);
|
||||
actionDrawable2.setDelegate(imageView::invalidate);
|
||||
frameLayout.addView(imageView, LayoutHelper.createFrame(48, 48, Gravity.CENTER));
|
||||
frameLayout.setOnClickListener(v -> {
|
||||
int icon = actionDrawable2.getCurrentIcon();
|
||||
boolean animated = true;
|
||||
if (icon == MediaActionDrawable.ICON_DOWNLOAD) {
|
||||
icon = MediaActionDrawable.ICON_CANCEL;
|
||||
} else if (icon == MediaActionDrawable.ICON_CANCEL) {
|
||||
icon = MediaActionDrawable.ICON_PLAY;
|
||||
} else if (icon == MediaActionDrawable.ICON_PLAY) {
|
||||
icon = MediaActionDrawable.ICON_DOWNLOAD;
|
||||
animated = false;
|
||||
Button button = new Button(context);
|
||||
button.setText("encrypt");
|
||||
frameLayout.addView(button, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.CENTER_HORIZONTAL, 10, 80, 10, 0));
|
||||
button.setOnClickListener(v -> {
|
||||
String str = encode(codeField.getText().toString());
|
||||
if (str != null) {
|
||||
SharedPreferences preferences = MessagesController.getMainSettings(UserConfig.selectedAccount);
|
||||
preferences.edit().putString("test_enc", str).commit();
|
||||
Toast.makeText(getParentActivity(), "String encoded", Toast.LENGTH_SHORT).show();
|
||||
finishFragment();
|
||||
}
|
||||
actionDrawable2.setIcon(icon, animated);
|
||||
});
|
||||
|
||||
SharedPreferences preferences = MessagesController.getMainSettings(UserConfig.selectedAccount);
|
||||
encryptedString = preferences.getString("test_enc", null);
|
||||
if (encryptedString != null) {
|
||||
codeField.setText(encryptedString);
|
||||
}
|
||||
|
||||
return fragmentView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (encryptedString != null) {
|
||||
prepareSensor();
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareSensor() {
|
||||
isKeyCreated();
|
||||
initCipher(Cipher.DECRYPT_MODE);
|
||||
FingerprintManagerCompat.CryptoObject cryptoObject = new FingerprintManagerCompat.CryptoObject(cipher);
|
||||
|
||||
if (cryptoObject != null) {
|
||||
Toast.makeText(getParentActivity(), "use fingerprint to login", Toast.LENGTH_LONG).show();
|
||||
fingerprintHelper = new FingerprintHelper(getParentActivity());
|
||||
fingerprintHelper.startAuth(cryptoObject);
|
||||
} else {
|
||||
Toast.makeText(getParentActivity(), "new fingerprint enrolled. enter pin again", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
public class FingerprintHelper extends FingerprintManagerCompat.AuthenticationCallback {
|
||||
|
||||
private Context mContext;
|
||||
private CancellationSignal mCancellationSignal;
|
||||
|
||||
FingerprintHelper(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
void startAuth(FingerprintManagerCompat.CryptoObject cryptoObject) {
|
||||
mCancellationSignal = new CancellationSignal();
|
||||
FingerprintManagerCompat manager = FingerprintManagerCompat.from(mContext);
|
||||
manager.authenticate(cryptoObject, 0, mCancellationSignal, this, null);
|
||||
}
|
||||
|
||||
void cancel() {
|
||||
if (mCancellationSignal != null) {
|
||||
mCancellationSignal.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationError(int errMsgId, CharSequence errString) {
|
||||
Toast.makeText(mContext, errString, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
|
||||
Toast.makeText(mContext, helpString, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
|
||||
Cipher cipher = result.getCryptoObject().getCipher();
|
||||
String decoded = decode(encryptedString, cipher);
|
||||
codeField.setText(decoded);
|
||||
Toast.makeText(mContext, "success", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailed() {
|
||||
Toast.makeText(mContext, "try again", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue