diff --git a/security/DataSecurity/README.md b/security/DataSecurity/README.md new file mode 100644 index 0000000000000000000000000000000000000000..79a6513cf2da9a2e321fba0012c28c38799aa161 --- /dev/null +++ b/security/DataSecurity/README.md @@ -0,0 +1,3 @@ +# Data Security + +- You can call encryption and decryption APIs to protect the security of your applications. \ No newline at end of file diff --git a/security/DataSecurity/README_zh.md b/security/DataSecurity/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..feea55eda3c9398900960f3e25fef6e2594beb9b --- /dev/null +++ b/security/DataSecurity/README_zh.md @@ -0,0 +1,3 @@ +# 数据安全 + +- 支持开发者调用安全加解密接口来达到安全防护作用。 \ No newline at end of file diff --git a/security/DataSecurity/build.gradle b/security/DataSecurity/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..e76a14f743baa5377849b43abf29dd0fe29b6478 --- /dev/null +++ b/security/DataSecurity/build.gradle @@ -0,0 +1,34 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 4 + } +} +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } + dependencies { + classpath 'com.huawei.ohos:hap:2.4.4.2' + } +} +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } +} \ No newline at end of file diff --git a/security/DataSecurity/entry/build.gradle b/security/DataSecurity/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..1324a93eda46cb945cc94de68b1cb0d1bcca10d1 --- /dev/null +++ b/security/DataSecurity/entry/build.gradle @@ -0,0 +1,18 @@ +apply plugin: 'com.huawei.ohos.hap' +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 4 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) +} diff --git a/security/DataSecurity/entry/src/main/config.json b/security/DataSecurity/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..e5f1bf7961cfd58bfd326458704b96bcbf9365ef --- /dev/null +++ b/security/DataSecurity/entry/src/main/config.json @@ -0,0 +1,48 @@ +{ + "app": { + "bundleName": "ohos.samples.datasecurity", + "version": { + "code": 1000000, + "name": "1.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "ohos.samples.datasecurity", + "name": ".MainAbility", + "reqCapabilities": [ + "video_support" + ], + "deviceType": [ + "default" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree":false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "formsEnabled": false, + "name": ".MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "$string:app_name", + "type": "page", + "launchType": "standard" + } + ] + } +} \ No newline at end of file diff --git a/security/DataSecurity/entry/src/main/java/ohos/samples/datasecurity/MainAbility.java b/security/DataSecurity/entry/src/main/java/ohos/samples/datasecurity/MainAbility.java new file mode 100644 index 0000000000000000000000000000000000000000..7d407bfa3d75cd5f940cf75c3a76c990d18c2492 --- /dev/null +++ b/security/DataSecurity/entry/src/main/java/ohos/samples/datasecurity/MainAbility.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.datasecurity; + +import ohos.samples.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()); + } +} diff --git a/security/DataSecurity/entry/src/main/java/ohos/samples/datasecurity/slice/MainAbilitySlice.java b/security/DataSecurity/entry/src/main/java/ohos/samples/datasecurity/slice/MainAbilitySlice.java new file mode 100644 index 0000000000000000000000000000000000000000..10d7084db161127d8e85b796d53555666a591055 --- /dev/null +++ b/security/DataSecurity/entry/src/main/java/ohos/samples/datasecurity/slice/MainAbilitySlice.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.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 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 keyPairOptional = getSecKey(); + 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)); + return; + } else { + try { + KeyStore keyStore = KeyStore.getInstance(KEY_STORE); + keyStore.load(null); + Key key = keyStore.getKey(KEY_PAIR_ALIAS, null); + PrivateKey privateKey = null; + 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."); + } + } + } +} + diff --git a/security/DataSecurity/entry/src/main/resources/base/element/string.json b/security/DataSecurity/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..af0198f6c2c5a821e4952404ada8cced67ceb58d --- /dev/null +++ b/security/DataSecurity/entry/src/main/resources/base/element/string.json @@ -0,0 +1,12 @@ +{ + "string": [ + { + "name": "app_name", + "value": "DataSecurity" + }, + { + "name": "mainability_description", + "value": "hap sample empty page" + } + ] +} \ No newline at end of file diff --git a/security/DataSecurity/entry/src/main/resources/base/graphic/button_background.xml b/security/DataSecurity/entry/src/main/resources/base/graphic/button_background.xml new file mode 100644 index 0000000000000000000000000000000000000000..6501645111d9237119d38999c7d9889d11905434 --- /dev/null +++ b/security/DataSecurity/entry/src/main/resources/base/graphic/button_background.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/security/DataSecurity/entry/src/main/resources/base/layout/main_ability_slice.xml b/security/DataSecurity/entry/src/main/resources/base/layout/main_ability_slice.xml new file mode 100644 index 0000000000000000000000000000000000000000..73157ddcd4fea75b4c464c74f1d5c4b35c56a610 --- /dev/null +++ b/security/DataSecurity/entry/src/main/resources/base/layout/main_ability_slice.xml @@ -0,0 +1,98 @@ + + + + + + + +