Hello!
I am not allowed to post under Software forum yet, hence posting this question here. Sorry for that.
We have developed a support of biometric authentication in our mobile app using BiometricPrompt API. We decided to go with CryptoObjects as it allows us to comply with regulations.
After implementation we are facing an issue that on Samsung devices after some device software updates and after almost every Security Patch our Key is getting corrupted/invalidated. This forces us generating a new key pair, leading to a terrible user experience (having to re-enable a feature again and again).
Error log:
Caused by java.security.UnrecoverableKeyException: Failed to obtain information about key
at android.security.keystore.AndroidKeyStoreProvider.getKeyCharacteristics(AndroidKeyStoreProvider.java:238)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(AndroidKeyStoreProvider.java:360)
at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:116)
at java.security.KeyStore.getKey(KeyStore.java:1062)
at com.app_name.mobile.data.crypto.CryptoRepositoryImpl.getSignature(CryptoRepositoryImpl.java:527)
at com.app_name.mobile.business.biometric.authentication.BiometricAuthenticationPromptInteractorImpl$getSignatureForAuthentication$1.subscribe(BiometricAuthenticationPromptInteractorImpl.java:52)
Caused by android.security.KeyStoreException: User authentication required
at android.security.KeyStore.getKeyStoreException(KeyStore.java:1151)
at android.security.keystore.AndroidKeyStoreProvider.getKeyCharacteristics(AndroidKeyStoreProvider.java:240)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(AndroidKeyStoreProvider.java:360)
at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:116)
at java.security.KeyStore.getKey(KeyStore.java:1062)
Click to expand...
Click to collapse
Has anyone experienced similar issues? How to prevent our key getting invalidated/corrupted after Samsung security patches? Is it actually a normal behavior and outcome of Security patches?
We are generating a key pair using following code (fallback is used as we discovered that cheaper Samsung devices not supporting EC, hence we use RSA on such devices) :
Code:
@RequiresApi(Build.VERSION_CODES.M)
override fun createSigningKey(keyBaseName: KeyBaseName, useFallbackAlgorithm: Boolean): Either<Throwable, JavaPublicKey> = try {
deleteKey(keyBaseName)
when {
useFallbackAlgorithm -> KeyPairGenerator
.getInstance(KEY_ALGORITHM_RSA, ANDROID_KEY_STORE_PROVIDER)
.apply {
initialize(KeyGenParameterSpec.Builder(keyBaseName, PURPOSE_SIGN or PURPOSE_VERIFY)
.setAlgorithmParameterSpec(RSAKeyGenParameterSpec(KEY_SIZE, RSAKeyGenParameterSpec.F4))
.setDigests(DIGEST_SHA256, DIGEST_SHA512)
.setSignaturePaddings(SIGNATURE_PADDING_RSA_PKCS1)
.setUserAuthenticationRequired(true)
.build())
}
else -> KeyPairGenerator
.getInstance(KEY_ALGORITHM_EC, ANDROID_KEY_STORE_PROVIDER)
.apply {
initialize(KeyGenParameterSpec.Builder(keyBaseName, PURPOSE_SIGN or PURPOSE_VERIFY)
.setDigests(DIGEST_SHA256, DIGEST_SHA512)
.setUserAuthenticationRequired(true)
.build())
}
}.generateKeyPair()
.public
.right()
} catch (e: Exception) {
firebaseRepository.logException(RuntimeException(“createSigningKey”, e))
e.left()
}
Thank you!
Related
[Apologies for posting here - I'm a new user so can't yet post on the developers forum]
I'm trying to develop a noise alerting system using Android/Java and the LG P500 phone. I'm using the following code to set up a mediarecorder:
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
mRecorder.start();
} catch (IOException e) {
Log.e("record", "prepare() failed");
}
However, when I call getMaxAmplitude() repeatedly after this setup (every second) the result is always 0.0. Sound recording does actually take place. The Android OS Version is 2.2.2. This same code works correctly both in the emulator and on an HTC Desire HD phone with Android 2.3.3.
Does anyone know of a problem with this version of Android and/or the LG P500?
Many thanks
AndroNoise
Hi,
I managed to do it in SGS2 but with my tab 10.1 it didn't work ..
I edited the file sec_power_key.kl and removed the WAKE command from POWER.
the reason I want this is for security because I don't want any one to turn off the device if my tab is locked.
Thanks.
logic5 said:
Hi,
I managed to do it in SGS2 but with my tab 10.1 it didn't work ..
I edited the file sec_power_key.kl and removed the WAKE command from POWER.
the reason I want this is for security because I don't want any one to turn off the device if my tab is locked.
Thanks.
Click to expand...
Click to collapse
Without that key edit I am not sure. In source it could be done by doing something like:
Line 317:
https://github.com/CyanogenMod/andr...droid/internal/policy/impl/GlobalActions.java
That creates the list you see when its called. You could create an intent to override those default settings.
Code:
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
//screen locked
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
//screen unlocked
}
}
Then you update the code in 317 to check the variable assigned at that public void. If true it wouldn't display that list, meaning phone locked. If false it would show that list meaning phone awake.
Other then that. I am not sure. I will let you know if I come up with anything else though.
Hello all,
Frankly I am not sure that this even belongs here but I think its the closest fit to the forum that I am seeking. If there is a community better suited to answer this please direct me there I have a question about the findall function in webviews. I know that it is deprecated, in eclipse this comes up "The method findAll(String) from the type WebView is deprecated". This is the code I have:
Code:
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN)
&& ((keyCode == KeyEvent.KEYCODE_ENTER))) {
wv.findAll(findBox.getText().toString());
try {
Method m = WebView.class.getMethod("setFindIsUp",
Boolean.TYPE);
m.invoke(wv, true);
} catch (Exception ignored) {
}
}
return false;
}
I just want to have a functioning find/search in a webview. So far this functions great for only some versions of android, versions such as 4.0, 4.0.3, and I believe 3.0 do not function correctly.
Older versions of android such as the 2.x series and my nexus s on 4.1 work great.
Anyone know of a workaround for a webview function to work on all android versions? If there is something completely different form this I am willing to listen, at this point I only am looking for a functioning search on all versions.
Thanks everybody!
Introduction
In this article, we will learn how to implement Huawei Safety detect kit in to mobile applications. Mobile devices have become more popular than laptops. Now a days users engage in nearly all activities on mobile devices, right from watching the news, checking emails, online shopping, doing bank transactions. Through these apps, business can gather usable information, which can help business to take precise decisions for better services.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
What is Huawei Safety Detect Service?
Safety Detect builds robust security capabilities, including system integrity check (SysIntegrity), app security check (AppsCheck), malicious URL check (URLCheck), fake user detection (UserDetect), and malicious Wi-Fi detection (WifiDetect), into your app, effectively protecting it against security threats.
1. SysIntegrity API: Checks whether the device running your app is secure, for example, whether it is rooted.
2. AppsCheck API: Checks for malicious apps and provides you with a list of malicious apps.
3. URLCheck API: Determines the threat type of a specific URL.
4. UserDetect API: Checks whether your app is interacting with a fake user.
5. WifiDetect API: Checks whether the Wi-Fi to be connected is secure.
Why Security is required for Apps
Mobile app security is a measure to secure application from threats like malware and other digital frauds that risk critical personal and financial information from hackers to avoid all of these we need to integrate the safety detect.
What are all the restrictions exists?
Currently two restrictions are there WifiDetect and UserDetect.
1. WifiDetect function available only in Chinese mainland.
2. UserDetect function not available in Chinese mainland.
Advantages
1. Provides a Trusted Execution Environment (TEE) to check system integrity.
2. Makes building security into your app easy with a rapid integration wizard.
3. Checks security for a diversity of apps: e-commerce, finance, multimedia, and news.
Requirements
1. Any operating system(i.e. MacOS, Linux and Windows)
2. Any IDE with Flutter SDK installed (i.e. IntelliJ, Android Studio and VsCode etc.)
3. A little knowledge of Dart and Flutter.
4. A Brain to think
Setting up the project
1. Before start creating application we have to make sure we connect our project to AppGallery. For more information check this link
2. After that follow the URL for cross-platform plugins. Download required plugins.
3. Enable the Safety Detect in the Manage API section and add the plugin.
4. After completing all the above steps, you need to add the required kits’ Flutter plugins as dependencies to pubspec.yaml file. You can find all the plugins in pub.dev with the latest versions.
Code:
huawei_safetydetect:
path: ../huawei_safetydetect/
After adding them, run flutter pub get command. Now all the plugins are ready to use.
Note: Set multiDexEnabled to true in the android/app directory, so the app will not crash.
Why we need SysIntegrity API and How to Use?
The SysIntegrity API is called to check the system integrity of a device. If the device is not safe, appropriate measures are taken.
Before implementing this API we need to check device have latest version of HMS core must be installed on users device.
Obtain a nonce value will be used to determine whether the returned result corresponds to the request and did not encounter and replay attacks. The nonce value must contain a minimum of 16 bytes and is intended to be used only once. Request for the AppId as input parameters.
Code:
getAppId() async {
String appID = await SafetyDetect.getAppID;
setState(() {
appId = appID;
});
}
checkSysIntegrity() async {
Random secureRandom = Random.secure();
List randomIntegers = List<int>();
for (var i = 0; i < 24; i++) {
randomIntegers.add(secureRandom.nextInt(255));
}
Uint8List nonce = Uint8List.fromList(randomIntegers);
try {
String result = await SafetyDetect.sysIntegrity(nonce, appId);
List<String> jwsSplit = result.split(".");
String decodedText = utf8.decode(base64Url.decode(jwsSplit[1]));
showToast("SysIntegrityCheck result is: $decodedText");
} on PlatformException catch (e) {
showToast("Error occured while getting SysIntegrityResult. Error is : $e");
}
}
}
Why we need AppsCheck API and How to Use?
You can obtain all malicious applications and evaluate whether you can restrict the behaviour of your application based on the risk.
You can directly call the getMaliciousAppsList() method to get all the malicious apps.
Code:
void getMaliciousAppsList() async {
List<MaliciousAppData> maliciousApps = List();
maliciousApps = await SafetyDetect.getMaliciousAppsList();
setState(() {
showToast("malicious apps: ${maliciousApps.toString()}");
});
}
In the return from task, you will get a list of malicious applications. You can find out the package name, SHA256 value and category of an application in this list.
Why we need User Detect API and How to Use?
This API can help your app prevent batch registration, credential stuffing attacks, activity bonus hunting, and content crawling. If a user is a suspicious one or risky one, a verification code is sent to the user for secondary verification. If the detection result indicates that the user is a real one, the user can sign in to my app. Otherwise, the user is not allowed to MainPage.
Code:
void _signInHuawei() async {
final helper = new HmsAuthParamHelper();
helper
..setAccessToken()
..setIdToken()
..setProfile()
..setEmail()
..setAuthorizationCode();
try {
HmsAuthHuaweiId authHuaweiId =
await HmsAuthService.signIn(authParamHelper: helper);
StorageUtil.putString("Token", authHuaweiId.accessToken);
} on Exception catch (e) {}
}
userDetection() async {
try {
String token = await SafetyDetect.userDetection(appId);
print("User verification succeded, user token: $token");
if(token!=null){
userDetection();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePageScreen()),
);
}
} on PlatformException catch (e) {
print(
"Error occurred: " + e.code + ":" + SafetyDetectStatusCodes[e.code]);
}
}
Why we need URLCheck API and How to Use?
You can determine the dangerous urls using URL Check API. Currently UrlSafety API provide determinate MALWARE and PHISHING threats. When you visit a URL, this API checks whether the URL is a malicious one. If so, you can evaluate the risk and alert the user about the risk or block the URL.
Code:
InkWell(
onTap: () {
loadUrl();
},
child: Text(
'Visit: $url',
style:
TextStyle(color: textColor),
))
void loadUrl() async {
Future.delayed(const Duration(seconds: 5), () async {
urlCheck();
});
}
void urlCheck() async {
List<UrlThreatType> threatTypes = [
UrlThreatType.malware,
UrlThreatType.phishing
];
List<UrlCheckThreat> urlCheckResults =
await SafetyDetect.urlCheck(url, appId, threatTypes);
if (urlCheckResults.length == 0) {
showToast("No threat is detected for the URL");
} else {
urlCheckResults.forEach((element) {
print("${element.getUrlThreatType} is detected on the URL");
});
}
}
Why we need WifiDetect API and How to Use?
This API checks characteristics of the Wi-Fi and router to be connected, analyzes the Wi-Fi information, and returns the Wi-Fi detection results after classification, helping you prevent possible attacks to your app from malicious Wi-Fi. If attacks are detected app can interrupt the user operation or it will asks user permission.
Code:
@override
void initState() {
getWifiDetectStatus();
super.initState();
}
getWifiDetectStatus() async {
try {
WifiDetectResponse wifiDetectStatus =
await SafetyDetect.getWifiDetectStatus();
ApplicationUtils.displayToast(
'Wifi detect status is: ${wifiDetectStatus.getWifiDetectType.toString()}');
} on PlatformException catch (e) {
if (e.code.toString() == "19003") {
ApplicationUtils.displayToast(' The WifiDetect API is unavailable in this region');
}
}
}
Note: Currently this API supports Chinese mainland.
Demo
Tips & Tricks
1. Download latest HMS Flutter plugin.
2. Set minSDK version to 19 or later.
3. Do not forget to click pug get after adding dependencies.
4. Latest HMS Core APK is required.
Conclusion
These were some of the best practices that a mobile app developer must follow in order to have a fully secure and difficult-to-crack application.
In the near future, security will act as one of the differentiating and competing innovations in the app world, with customers preferring secure apps to maintain the privacy of their data over other mobile applications.
Thanks for reading! If you enjoyed this story, please click the Like button and Follow. Feel free to leave a Comment below.
Reference
Safety detect Kit URL
Checkout in forum
Have you ever marveled at the impressive technology in sci-fi movies, such as the floating touchscreen in Iron Man and the fingerprint and iris authentication in Mission: Impossible?
Such cutting-edge technology has already entered our day-to-day lives, with fingerprint and facial authentication being widely used.
Users are paying more and more attention to individual privacy protection and thus have higher requirements about app security, which can be guaranteed with the help of authentication based on the unique nature of fingerprints and facial data.
Fingerprint and facial authentication effectively reduces the risk of account theft and information leakage when used for unlocking devices, making payments, and accessing files.
Such an authentication mode can be realized with HUAWEI FIDO: it arms your app with FIDO2 client capabilities based on the WebAuthn standard, as well as the fingerprint and facial authentication capabilities of BioAuthn.
FIDO ensures that the authentication result is secure and reliable by checking the system integrity and using cryptographic key verification. It allows password-free authentication during sign-in, a general solution that can be easily integrated with the existing account infrastructure.
Let's see how to integrate the fingerprint and facial authentication capabilities in FIDO.
Perform the steps below:
Configure app information in AppGallery Connect.
Integrate the HMS Core SDK.
Integrate the BioAuthn-AndroidX SDK.
Click the hyperlinks of step 1 and 2 to learn more about them.
Note that in step 2 there are two SDKs:
Bioauthn-AndroidX: implementation 'com.huawei.hms:fido-bioauthn-androidx:5.2.0.301'
BioAuthn: implementation 'com.huawei.hms:fido-bioauthn:5.2.0.301'
They're slightly different from each other:
The BioAuthn-AndroidX SDK provides a unified UI for fingerprint authentication. You do not need to design a fingerprint authentication UI for your app, whereas the BioAuthn SDK requires you to design a fingerprint authentication UI for your app.
Below is the detailed description of the difference in the FAQs section of this kit:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
This article gives an introduction about how to integrate the BioAuthn-AndroidX SDK. You can download its demo here.
Integrating the BioAuthn-AndroidX SDKNotes:
The fingerprint and facial authentication capabilities cannot be used on a rooted device.
Before testing, make sure that you've enrolled facial data and a fingerprint in the testing device. Otherwise, an error code will be reported.
Go to Settings > Biometrics & password on the device to enroll facial data and a fingerprint.
Fingerprint AuthenticationTo use the fingerprint authentication capability, perform the following steps:
Initialize the BioAuthnPrompt object:
Code:
BioAuthnPrompt bioAuthnPrompt = new BioAuthnPrompt(this, ContextCompat.getMainExecutor(this), new BioAuthnCallback() {
@Override
public void onAuthError(int errMsgId, CharSequence errString) {
showResult("Authentication error. errorCode=" + errMsgId + ",errorMessage=" + errString);
}
@Override
public void onAuthSucceeded(BioAuthnResult result) {
showResult("Authentication succeeded. CryptoObject=" + result.getCryptoObject());
}
@Override
public void onAuthFailed() {
showResult("Authentication failed.");
}
});
Configure prompt information and perform authentication.
Code:
// Customize the prompt information.
BioAuthnPrompt.PromptInfo.Builder builder =
new BioAuthnPrompt.PromptInfo.Builder().setTitle("This is the title.")
.setSubtitle("This is the subtitle.")
.setDescription("This is the description.");
// The user is allowed to authenticate with methods other than biometrics.
builder.setDeviceCredentialAllowed(true);
BioAuthnPrompt.PromptInfo info = builder.build();
// Perform authentication.
bioAuthnPrompt.auth(info);
After the configuration is complete, fingerprint authentication can be performed on a screen similar to the following image:
Facial AuthenticationThere are many restrictions on using the facial authentication capability. For details, please refer to the corresponding FAQs.
Check whether the camera permission has been granted to your app. (Note that this permission is not needed on devices running EMUI 10.1 or later.)
Code:
int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
showResult("Grant the camera permission first.");
ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.CAMERA}, 1);
return;
}
Check whether the device supports facial authentication.
Code:
FaceManager faceManager = new FaceManager(this);
int errorCode = faceManager.canAuth();
if (errorCode != 0) {
resultTextView.setText("");
showResult("The device does not support facial authentication. errorCode=" + errorCode);
return;
}
Perform facial authentication.
Code:
int flags = 0;
Handler handler = null;
CryptoObject crypto = null;
faceManager.auth(crypto, cancellationSignal, flags, new BioAuthnCallback() {
@Override
public void onAuthError(int errMsgId, CharSequence errString) {
showResult("Authentication error. errorCode=" + errMsgId + ",errorMessage=" + errString
+ (errMsgId == 1012 ? " The camera permission has not been granted." : ""));
}
@Override
public void onAuthHelp(int helpMsgId, CharSequence helpString) {
showResult("This is the prompt information during authentication. helpMsgId=" + helpMsgId + ",helpString=" + helpString + "\n");
}
@Override
public void onAuthSucceeded(BioAuthnResult result) {
showResult("Authentication succeeded. CryptoObject=" + result.getCryptoObject());
}
@Override
public void onAuthFailed() {
showResult("Authentication failed.");
}
}, handler);
This is all the code for facial authentication. You can call it to perform this capability.
Note that there is no default UI for this capability. You need to design a UI as needed.
Application ScenariosFingerprint AuthenticationFingerprint authentication is commonly used before payments by users for security authentication.
It can also be integrated into file protection apps to allow only users passing fingerprint authentication to access relevant files.
Facial AuthenticationThis capability works well in scenarios where fingerprint authentication can be used. For file protection apps, facial authentication has a better performance than fingerprint authentication.
This is because such apps share a common flaw: they make it clear that a file is very important or sensitive.
Therefore, a hacker can access this file once they figure out a way to obtain the fingerprint authentication of the app, which can be done despite the difficulty in doing so.
To avoid this, in addition to fingerprint authentication, a file protection app can adopt facial authentication "secretly" — this capability does not require a UI. The app displays the real file after a user obtains both fingerprint and facial authentication, otherwise it will display a fake file.
In this way, it can improve the protection of user privacy.
The following is the sample code for developing such a function:
Code:
faceManager.auth(crypto, cancellationSignal, flags, new BioAuthnCallback() {
@Override
public void onAuthError(int errMsgId, CharSequence errString) {
if(isFingerprintSuccess){// Fingerprint authentication succeeded but facial authentication failed.
// Display a fake file.
showFakeFile();
}
}
@Override
public void onAuthHelp(int helpMsgId, CharSequence helpString) {
}
@Override
public void onAuthSucceeded(BioAuthnResult result) {
if(isFingerprintSuccess){// Fingerprint authentication succeeded.
// Display the real file.
showRealFile();
}else {// Fingerprint authentication failed.
// Display a fake file.
showFakeFile();
}
}
@Override
public void onAuthFailed() {
if(isFingerprintSuccess){// Fingerprint authentication succeeded but facial authentication failed.
// Display a fake file.
showFakeFile();
}
}
}, handler);
To learn more, please visit:
HUAWEI Developers official website
Development Guide
Reddit to join developer discussions
GitHub or Gitee to download the demo and sample code
Stack Overflow to solve integration problems
Follow our official account for the latest HMS Core-related news and updates.
Original Source