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.
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.
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.