文档首页/ 数据加密服务 DEW/ 最佳实践/ 密钥管理/ 使用加密SDK进行本地文件加解密
更新时间:2024-03-28 GMT+08:00

使用加密SDK进行本地文件加解密

文件加密,指通过指定算法对文本信息进行加密,使其无法被窃取或修改。

加密SDK(Encryption SDK)是一个客户端密码库,提供了数据的加解密、文件流加解密等功能,旨在帮助客户专注于应用程序的核心功能,而不用关心数据加密和解密的实现过程,用户只需调用加解密接口即可轻松实现海量数据加解密。

更多详情请访问:详情参考

应用场景

对大型文件、图片等数据通过HTTPS请求到KMS服务进行保护时会消耗大量网络资源,降低加密效率。

解决方案

加密SDK通过文件流分段信封加密的原理进行加密。

数据加密通过KMS生成的数据密钥在SDK内部进行,内存中分段加解密文件无需将数据通过网络传输后再进行加解密,保证了文件加密的安全性和正确性。

对于大型文件,SDK执行加密过程中,将文件分段读取到内存中,通过加解密写到目标文件后再进行下一段文件读取和加解密,直至完成整个文件的加解密。

操作流程

操作步骤

  1. 获取AK/SK:

    • ACCESS_KEY: 华为账号Access Key,获取方式请参见获取AK/SK
    • SECRET_ACCESS_KEY: 华为账号Secret Access Key,获取方式请参见获取AK/SK
    • 认证用的ak和sk直接写到代码中有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全。
    • 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。

  2. 获取region相关信息。

    1. 登录管理控制台
    2. 鼠标移动至右上方的用户名,在下拉列表中选择“我的凭证”
    3. 获取“项目ID”(PROJECT_ID)和“项目”(REGION)。
      图1 获取项目ID和项目
    4. 单击页面左侧,选择安全与合规 > 数据加密服务,默认进入“密钥管理”界面。
    5. 获取当前Region需要使用的主密钥ID(KEYID)。
      图2 获取主密钥ID
    6. 获取当前Region需要使用的终端节点(ENDPOINT)。

      终端节点(Endpoint)即调用API的请求地址,不同服务不同区域的终端节点不同,您可以从地区和终端节点中查询所有服务的终端节点。

      图3 获取终端节点

  3. 文件加解密。

    public class KmsEncryptFileExample {
    
        private static final String ACCESS_KEY = System.getenv("HUAWEICLOUD_SDK_AK");
        private static final String SECRET_ACCESS_KEY = System.getenv("HUAWEICLOUD_SDK_SK");
        private static final String PROJECT_ID = "<projectId>";
        private static final String REGION = "<region>";
        private static final String KEYID = "<keyId>";
        public static final String ENDPOINT = "<endpoint>";
    
        public static void main(String[] args) throws IOException {
            // 源文件路径
            String encryptFileInPutPath = args[0];
            // 加密后密文文件路径
            String encryptFileOutPutPath = args[1];
            // 解密后文件路径
            String decryptFileOutPutPath = args[2];
            // 加密上下文
            Map<String, String> encryptContextMap = new HashMap<>();
            encryptContextMap.put("encryption", "context");
            encryptContextMap.put("simple", "test");
            encryptContextMap.put("caching", "encrypt");
            // 构建加密配置
            HuaweiConfig config = HuaweiConfig.builder().buildSk(SECRET_ACCESS_KEY)
                    .buildAk(ACCESS_KEY)
                    .buildKmsConfig(Collections.singletonList(new KMSConfig(REGION, KEYID, PROJECT_ID, ENDPOINT)))
                    .buildCryptoAlgorithm(CryptoAlgorithm.AES_256_GCM_NOPADDING)
                    .build();
            HuaweiCrypto huaweiCrypto = new HuaweiCrypto(config);
            // 设置密钥环
            huaweiCrypto.withKeyring(new KmsKeyringFactory().getKeyring(KeyringTypeEnum.KMS_MULTI_REGION.getType()));
            // 加密文件
            encryptFile(encryptContextMap, huaweiCrypto, encryptFileInPutPath, encryptFileOutPutPath);
            // 解密文件
            decryptFile(huaweiCrypto, encryptFileOutPutPath, decryptFileOutPutPath);
        }
    
        private static void encryptFile(Map<String, String> encryptContextMap, HuaweiCrypto huaweiCrypto, 
                                        String encryptFileInPutPath, String encryptFileOutPutPath) throws IOException {
            // fileInputStream 加密后文件对应的输入流
            FileInputStream fileInputStream = new FileInputStream(encryptFileInPutPath);
            // fileOutputStream 源文件对应的输出流
            FileOutputStream fileOutputStream = new FileOutputStream(encryptFileOutPutPath);
            // 加密
            huaweiCrypto.encrypt(fileInputStream, fileOutputStream, encryptContextMap);
            fileInputStream.close();
            fileOutputStream.close();
        }
    
        private static void decryptFile(HuaweiCrypto huaweiCrypto, String decryptFileInPutPath, String decryptFileOutPutPath) throws IOException {
            // in 源文件对应的输入流
            FileInputStream fileInputStream = new FileInputStream(decryptFileInPutPath);
            // out 加密后文件对应的输出流
            FileOutputStream fileOutputStream = new FileOutputStream(decryptFileOutPutPath);
            // 解密
            huaweiCrypto.decrypt(fileInputStream, fileOutputStream);
            fileInputStream.close();
            fileOutputStream.close();
        }
    }