Intermediate: Integration of Data Security for Text Encryption and Decryption in Harmony OS App

Manoj Kumar
4 min readNov 12, 2021

--

Overview

In this article, I will create a demo app along with the integration of Data Security which is based on Harmony OS. I will provide the use case of Text Encryption and Decryption in Harmony OS application.

Data Security

HarmonyOS security subsystem provides security capabilities that makes your applications and devices more secure and help you to manage permissions. This subsystem has the following modules:

Application signature verification

To ensure the content integrity of applications, the system controls sources of the applications through application signatures and profiles. For a debugging application, the system uses the signature verification API to check whether the Unique Device Identifier (UDID) of the application matches that of the device, so as to ensure that the application is installed on the right device.

Application permission management

Application permissions determines that what system resources and capabilities an application can access. During application development, you need to declare the permissions that the application may require in the profile.json file. Static permissions need to be registered during application installation, while dynamic permissions usually involve sensitive information and need users’ dynamic authorization.

Trusted device group management

You can create and query a group of trusted devices that uses the same HUAWEI ID or a peer-to-peer group created by scanning a QR code or using OneHop. With this capability, distributed applications can perform trusted authentication between devices and request from the distributed virtual bus for secure sessions between devices.

Prerequisite

  1. Harmony OS phone
  2. Java JDK
  3. DevEco Studio
  4. AppGallery Account

App Development

Create a New Project.

Configure Project Gradle.

Configure App Gradle.

Configure Config.json

Create Activity class with XML UI.

MainAbility.java:

import com.harmonyos.demo.datasecurity.slice.MainAbilitySlice;import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
/**
* Data Security MainAbility
*/
public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
}
}

MainAbilitySlice.java:

package com.harmonyos.demo.datasecurity.slice;import ohos.samples.datasecurity.MainAbility;
import ohos.samples.datasecurity.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.security.keystore.KeyGenAlgorithmParaSpec;
import ohos.security.keystore.KeyStoreConstants;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Base64;
import java.util.Objects;
import java.util.Optional;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
/**
* MainAbilitySlice
*/
public class MainAbilitySlice extends AbilitySlice {
private static final String TAG = MainAbility.class.getSimpleName();
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG); private static final String PLAIN_TEXT = "Hello World!"; private static final String KEY_STORE = "HarmonyKeyStore"; private static final String KEY_PAIR_ALIAS = "HarmonyKeyPair"; private static final String ENCRYPT_ALGORITHM = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"; private static final String PROVIDER = "HarmonyKeyStoreBCWorkaround"; private static final String SIGNATURE_PADDING = "PSS"; private Text resultText; private String result; @Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_main_ability_slice);
initComponents();
}
private void initComponents() {
resultText = (Text) findComponentById(ResourceTable.Id_result_text);
Component encryptButton = findComponentById(ResourceTable.Id_encrypt_button);
Component decryptButton = findComponentById(ResourceTable.Id_decrypt_button);
encryptButton.setClickedListener(component -> encrypt());
decryptButton.setClickedListener(component -> decrypt());
}
private Optional<KeyPair> getSecKey() {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyStoreConstants.SEC_KEY_ALGORITHM_RSA,
KEY_STORE);
KeyGenAlgorithmParaSpec.Builder builder = new KeyGenAlgorithmParaSpec.Builder(
KEY_PAIR_ALIAS).setSecKeyUsagePurposes(
KeyStoreConstants.PURPOSE_CAN_ENCRYPT | KeyStoreConstants.PURPOSE_CAN_DECRYPT
| KeyStoreConstants.PURPOSE_CAN_SIGN | KeyStoreConstants.PURPOSE_CAN_VERIFY)
.addSecKeyCryptoAttr(KeyStoreConstants.CRYPTO_PARAMETER_BLOCK_MODE,
KeyStoreConstants.SEC_BLOCK_MODE_ECB)
.addSecKeyCryptoAttr(KeyStoreConstants.CRYPTO_PARAMETER_ENCRYPT_PADDING,
KeyStoreConstants.OPTIMAL_ASYMMETRIC_ENCRYPTION_PADDING)
.addSecKeyCryptoAttr(KeyStoreConstants.CRYPTO_PARAMETER_DIGEST,
KeyStoreConstants.DIGEST_ALGORITHM_SHA256)
.addSecKeyCryptoAttr(KeyStoreConstants.CRYPTO_PARAMETER_SIGNATURE_PADDING, SIGNATURE_PADDING);
KeyGenAlgorithmParaSpec keyGenAlgorithmParaSpec = builder.createKeyGenAlgorithmParaSpec();
keyPairGenerator.initialize(keyGenAlgorithmParaSpec);
return Optional.of(keyPairGenerator.generateKeyPair());
} catch (NoSuchProviderException | NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
HiLog.error(LABEL_LOG, "%{public}s", "getSecKey exception.");
return Optional.empty();
}
}
private void encrypt() {
try {
Optional<KeyPair> keyPairOptional = getSecKey();
if(keyPairOptional.isPresent()) {
KeyPair keyPair = keyPairOptional.get();
Cipher cipher = Cipher.getInstance(ENCRYPT_ALGORITHM, PROVIDER);
cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
byte[] bytes = cipher.doFinal(PLAIN_TEXT.getBytes(StandardCharsets.UTF_8));
result = Base64.getEncoder().encodeToString(bytes);
resultText.setText(result);
}
} catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException
| InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
HiLog.error(LABEL_LOG, "%{public}s", "encrypt exception.");
}
}
private void decrypt() {
if (Objects.isNull(result) || PLAIN_TEXT.equals(result)) {
HiLog.error(LABEL_LOG, "%{public}s", "result is null or " + PLAIN_TEXT.equals(result));
} else {
try {
KeyStore keyStore = KeyStore.getInstance(KEY_STORE);
keyStore.load(null);
Key key = keyStore.getKey(KEY_PAIR_ALIAS, null);
PrivateKey privateKey;
if (key instanceof PrivateKey) {
privateKey = (PrivateKey) key;
} else {
HiLog.error(LABEL_LOG, "key is not instance of PrivateKey.");
return;
}
byte[] bytes = Base64.getDecoder().decode(result);
Cipher cipher = Cipher.getInstance(ENCRYPT_ALGORITHM, PROVIDER);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
result = new String(cipher.doFinal(bytes)).trim();
resultText.setText(result);
} catch (KeyStoreException | CertificateException | IOException | NoSuchAlgorithmException
| UnrecoverableKeyException | NoSuchPaddingException | NoSuchProviderException
| InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) {
HiLog.error(LABEL_LOG, "%{public}s", "decrypt exception.");
}
}
}
}

main_ability.xml:

<?xml version="1.0" encoding="utf-8"?><DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical">
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_parent"
ohos:alignment="horizontal_center"
ohos:orientation="horizontal"
ohos:top_margin="50vp">
<Button
ohos:id="$+id:encrypt_button"
ohos:height="40vp"
ohos:width="160vp"
ohos:background_element="$graphic:button_background"
ohos:padding="10vp"
ohos:text="$string:encrypt"
ohos:text_alignment="center"
ohos:text_size="16fp"/>
<Button
ohos:id="$+id:decrypt_button"
ohos:height="40vp"
ohos:width="160vp"
ohos:background_element="$graphic:button_background"
ohos:left_margin="15vp"
ohos:padding="10vp"
ohos:text="$string:decrypt"
ohos:text_alignment="center"
ohos:text_size="16fp"/>
</DirectionalLayout>
<DirectionalLayout
ohos:height="40vp"
ohos:width="match_parent"
ohos:orientation="horizontal"
ohos:top_margin="20vp">
<Text
ohos:height="match_content"
ohos:width="match_content"
ohos:left_padding="15vp"
ohos:text="$string:plain_text"
ohos:text_size="16fp"/>
<Text
ohos:id="$+id:plaintext_text"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="$string:hello_world"
ohos:text_color="#708095"
ohos:text_size="16fp"/>
</DirectionalLayout>
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_parent"
ohos:orientation="vertical">
<Text
ohos:height="match_content"
ohos:width="match_content"
ohos:left_padding="15vp"
ohos:text="$string:result"
ohos:text_size="16fp"/>
<Text
ohos:id="$+id:result_text"
ohos:height="match_content"
ohos:width="match_parent"
ohos:enabled="false"
ohos:left_margin="20vp"
ohos:multiple_lines="true"
ohos:right_margin="20vp"
ohos:text_color="#708095"
ohos:text_size="16fp"/>
</DirectionalLayout>
</DirectionalLayout>

App Build Result

​​​​​​​

Tips and Tricks

Parameters can be set: key alias, length, usage (purposes), parameter set for key encryption, attribute set for key access control, and key accessibility period after user authentication.

Conclusion

In this article, we have learned how to integrate Data Security in Harmony OS application. In this application, I have explained that how to encrypt text and decrypt text in Harmony OS based application.

Thanks for reading this article. Be sure to like and comments to this article, if you found it helpful. It means a lot to me.

References

Harmony OS Doc:

https://developer.harmonyos.com/en/docs/documentation/doc-references/overview-0000001054518986

--

--

Manoj Kumar
Manoj Kumar

No responses yet