Building a Program
This section provides a file encryption/decryption package. You can create a function with the sample code in this package.
Creating a Deployment Package
This example uses a Java 8 function to encrypt/decrypt files. For details about function development, see Developing Functions in Java. Figure 1 shows the sample code directory. The service code is not described.
FileEncryptAndDecrypt is the function execution entry point. The entry function in FileEncryptAndDecrypt contains the following code:
package com.huawei.kms; import com.huawei.services.runtime.Context; import com.huawei.services.runtime.entity.s3obs.S3ObsTriggerEvent; import com.huaweicloud.sdk.core.auth.BasicCredentials; import com.huaweicloud.sdk.kms.v1.KmsClient; import com.huaweicloud.sdk.kms.v1.model.*; import com.obs.services.ObsClient; import com.obs.services.exception.ObsException; import com.obs.services.model.ObsObject; import javax.crypto.Cipher; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.nio.file.Files; import java.security.SecureRandom; public class FileEncryptAndDecrypt { private String objectKey; private String inputPath; private String outputPath; public String encrypt(S3ObsTriggerEvent event, Context context){ objectKey = event.getObjectKey(); inputPath = "/tmp/" + objectKey; outputPath = "/tmp/" + objectKey + ".encrypt"; // Initialize OBS class. obsClientHandler client = new obsClientHandler(); client.init(context); client.setObjectInfo(objectKey, inputPath, outputPath); // Download files from the specified OBS bucket. client.downloadFile(); // Initialize KMS class. KmsClientHandler kms = new KmsClientHandler(); kms.init(context); kms.setPath(inputPath, outputPath); // Encrypt files. kms.encryptFile(); // Upload files. client.uploadFile(); return "ok"; } public String decrypt(S3ObsTriggerEvent event, Context context){ objectKey = event.getObjectKey(); inputPath = "/tmp/" + objectKey; outputPath = "/tmp/" + objectKey + ".decrypt"; // Initialize OBS class. obsClientHandler client = new obsClientHandler(); client.init(context); client.setObjectInfo(objectKey, inputPath, outputPath); // Download files from the specified OBS bucket. client.downloadFile(); // Initialize KMS class. KmsClientHandler kms = new KmsClientHandler(); kms.init(context); kms.setPath(inputPath, outputPath); // Encrypt files. kms.decryptFile(); // Upload files. client.uploadFile(); return "ok"; } static class KmsClientHandler { // DEW API version. Currently fixed to v1.0. private static final String KMS_INTERFACE_VERSION = "v1.0"; private static final String AES_KEY_BIT_LENGTH = "256"; private static final String AES_KEY_BYTE_LENGTH = "32"; private static final String AES_ALG = "AES/GCM/PKCS5Padding"; private static final String AES_FLAG = "AES"; private static final int GCM_TAG_LENGTH = 16; private static final int GCM_IV_LENGTH = 12; private String ACCESS_KEY; private String SECRET_ACCESS_KEY; private String PROJECT_ID; private String KMS_ENDPOINT; private String keyId; private String cipherText; private String inputPath; private String outputPath; private Context context; private KmsClient kmsClient = null; void init(Context context) { this.context = context; } void initKmsClient() { if (kmsClient == null) { ACCESS_KEY = context.getAccessKey(); SECRET_ACCESS_KEY = context.getSecretKey(); PROJECT_ID = context.getProjectID(); KMS_ENDPOINT = context.getUserData("kms_endpoint"); keyId = context.getUserData("kms_key_id"); cipherText = context.getUserData("cipher_text"); final BasicCredentials auth = new BasicCredentials().withAk(ACCESS_KEY).withSk(SECRET_ACCESS_KEY).withProjectId(PROJECT_ID); kmsClient = kmsClient.newBuilder().withCredential(auth).withEndpoint(KMS_ENDPOINT).build(); } } byte[] getEncryptPlainKey() { final CreateDatakeyRequest createDatakeyRequest = new CreateDatakeyRequest().withVersionId(KMS_INTERFACE_VERSION) .withBody(new CreateDatakeyRequestBody().withKeyId(keyId).withDatakeyLength(AES_KEY_BIT_LENGTH)); final CreateDatakeyResponse createDatakeyResponse = kmsClient.createDatakey(createDatakeyRequest); final String cipherText = createDatakeyResponse.getCipherText(); return hexToBytes(createDatakeyResponse.getPlainText()); } byte[] hexToBytes(String hexString) { final int stringLength = hexString.length(); assert stringLength > 0; final byte[] result = new byte[stringLength / 2]; int j = 0; for (int i = 0; i < stringLength; i += 2) { result[j++] = (byte) Integer.parseInt(hexString.substring(i, i + 2), 16); } return result; } public void setPath(String inputPath, String outputPath) { this.inputPath = inputPath; this.outputPath = outputPath; } public void encryptFile() { final File outEncryptFile = new File(outputPath); final File inFile = new File(inputPath); final byte[] iv = new byte[GCM_IV_LENGTH]; final SecureRandom secureRandom = new SecureRandom(); secureRandom.nextBytes(iv); doFileFinal(Cipher.ENCRYPT_MODE, inFile, outEncryptFile, getEncryptPlainKey(), iv); } byte[] getDecryptPlainKey() { final CreateDatakeyRequest createDatakeyRequest = new CreateDatakeyRequest().withVersionId(KMS_INTERFACE_VERSION) .withBody(new CreateDatakeyRequestBody().withKeyId(keyId).withDatakeyLength(AES_KEY_BIT_LENGTH)); // Create a data key. final CreateDatakeyResponse createDatakeyResponse = kmsClient.createDatakey(createDatakeyRequest); final DecryptDatakeyRequest decryptDatakeyRequest = new DecryptDatakeyRequest().withVersionId(KMS_INTERFACE_VERSION) .withBody(new DecryptDatakeyRequestBody().withKeyId(keyId).withCipherText(createDatakeyResponse.getCipherText() ).withDatakeyCipherLength(AES_KEY_BYTE_LENGTH)); return hexToBytes(kmsClient.decryptDatakey(decryptDatakeyRequest).getDataKey()); } public void decryptFile() { final File outEncryptFile = new File(outputPath); final File inFile = new File(inputPath); final byte[] iv = new byte[GCM_IV_LENGTH]; final SecureRandom secureRandom = new SecureRandom(); secureRandom.nextBytes(iv); doFileFinal(Cipher.DECRYPT_MODE, inFile, outEncryptFile, getDecryptPlainKey(), iv); } /** // * Encrypt/Decrypt files. // * // * @param cipherMode Encryption mode. Options: Cipher.ENCRYPT_MODE and Cipher.DECRYPT_MODE. // * @param infile Files before encryption/decryption. // * @param outFile Files after encryption/decryption. // * @param keyPlain Plaintext key // * @param iv Initialize vector. // */ void doFileFinal(int cipherMode, File infile, File outFile, byte[] keyPlain, byte[] iv) { try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(infile.toPath())); BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(outFile.toPath()))) { final byte[] bytIn = new byte[(int) infile.length()]; final int fileLength = bis.read(bytIn); assert fileLength > 0; final SecretKeySpec secretKeySpec = new SecretKeySpec(keyPlain, AES_FLAG); final Cipher cipher = Cipher.getInstance(AES_ALG); final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * Byte.SIZE, iv); cipher.init(cipherMode, secretKeySpec, gcmParameterSpec); final byte[] bytOut = cipher.doFinal(bytIn); bos.write(bytOut); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } } static class obsClientHandler { private ObsClient obsClient = null; private String inputBucketName; private String outputBucketName; private String objectKey; private Context context; private String localInPath; private String localOutPath; public void init(Context context) { this.context = context; } void initObsclient() { if (obsClient == null) { inputBucketName = context.getUserData("input_bucket"); outputBucketName = context.getUserData("output_bucket"); String ACCESS_KEY = context.getAccessKey(); String SECRET_ACCESS_KEY = context.getSecretKey(); String OBS_ENDPOINT = context.getUserData("obs_endpoint"); obsClient = new ObsClient(ACCESS_KEY, SECRET_ACCESS_KEY, OBS_ENDPOINT); } } public void setObjectInfo(String objectKey, String inPath, String outPath) { this.objectKey = objectKey; localInPath = inPath; localOutPath = outPath; } public void downloadFile() { initObsclient(); try { ObsObject obsObject = obsClient.getObject(inputBucketName, objectKey); InputStream inputStream = obsObject.getObjectContent(); byte[] b = new byte[1024]; int len; FileOutputStream fileOutputStream = new FileOutputStream("/tmp/" + objectKey); while ((len = inputStream.read(b)) != -1) { fileOutputStream.write(b); } inputStream.close(); fileOutputStream.close(); } catch (ObsException ex) { ex.printStackTrace(); } catch (IOException e) { throw new RuntimeException(e); } } public void uploadFile() { try { // Local path of the files to upload. File names must be specified. FileInputStream fis = new FileInputStream(new File("/tmp/" + objectKey + ".encrypt")); obsClient.putObject(outputBucketName, objectKey, fis); fis.close(); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } } }
Creating a Function
When creating a function, specify an agency with OBS and DEW access permissions so that FunctionGraph can invoke these two services.
- Log in to the FunctionGraph console, and choose Functions > Function List in the navigation pane.
- Click Create Function.
- Click Create from scratch and configure the function information.
After setting the basic information, click Create.
- For Function Type, select Event Function.
- For Function Name, enter fss_examples_dew.
- For Agency, select serverless_trust.
- For Runtime, select Java 8.
- On the details page of function fss_examples_dew, configure the following information:
- On the Code tab, choose Upload > Local JAR, upload the compiled sample code JAR package, and click OK.
- Choose Configuration > Basic Settings, set the following parameters, and click Save.
- For Memory, select 128.
- For Execution Timeout, enter 3.
- For Handler, enter com.huawei.kms.FileEncryptAndDecrypt.encrypt.
- For App, retain the default value default.
- Description: Enter File encryption and decryption.
- Choose Configuration > Environment Variables, set environment variables, and click Save.
dew_endpoint: DEW endpoint
dew_key_id: Master key ID
input_bucket: OBS bucket for storing uploaded files
output_bucket: OBS bucket for storing encrypted/decrypted files
obs_endpoint: OBS endpoint
Table 1 Environment variables Environment Variable
Description
dew_endpoint
DEW endpoint. To obtain the DEW endpoint, see Regions and Endpoints.
dew_key_id
User master key ID.
input_bucket
OBS bucket for storing input files.
output_bucket
OBS bucket for storing encrypted and uploaded files.
obs_endpoint
OBS endpoint. To obtain the OBS endpoint, see Regions and Endpoints.
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
For any further questions, feel free to contact us through the chatbot.
Chatbot