You need to enable JavaScript to run this app. 基于Angular实现加密文件上传Azure Container及端侧解密的技术咨询
优惠活动
大模型
产品
解决方案
定价
更多

基于Angular实现加密文件上传Azure Container及端侧解密的技术咨询

Angular 端 Azure Blob 加密图片上传与解密查看实现方案

基于你已有的Azure Blob基础上传、拉取能力,以下采用客户端AES对称加密方案实现需求,无需修改Azure服务端配置:

1. 加密图片上传至Azure Container

实现步骤:

  • 安装加密依赖:npm install crypto-js @types/crypto-js
  • 封装AES加密工具方法,这里采用安全性更高的GCM模式,支持数据完整性校验:
import * as CryptoJS from 'crypto-js';

// 生产环境密钥请从后端鉴权接口拉取,禁止硬编码在前端代码中
const AES_SECRET_KEY = '替换为你的32位长度AES256密钥';

/**
 * 加密文件为Blob
 * @param file 原始上传图片文件
 * @returns 加密后的Blob对象
 */
const encryptImageFile = (file: File): Promise<Blob> => {
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    fileReader.onload = (loadEvent) => {
      try {
        const fileContent = CryptoJS.lib.WordArray.create(loadEvent.target?.result as ArrayBuffer);
        // GCM模式推荐使用12字节随机IV
        const iv = CryptoJS.lib.WordArray.random(12);
        const encryptResult = CryptoJS.AES.encrypt(fileContent, AES_SECRET_KEY, {
          iv: iv,
          mode: CryptoJS.mode.GCM,
          padding: CryptoJS.pad.NoPadding
        });
        // 将IV拼接在加密数据开头,解密时需要读取
        const combineData = iv.concat(encryptResult.ciphertext);
        const encryptBlob = new Blob(
          [combineData.toString(CryptoJS.enc.Latin1)],
          { type: file.type }
        );
        resolve(encryptBlob);
      } catch (err) {
        reject(err);
      }
    };
    fileReader.onerror = () => reject(fileReader.error);
    fileReader.readAsArrayBuffer(file);
  });
};
  • 改造原有上传逻辑:用户选择上传图片后,先调用encryptImageFile得到加密Blob,将该Blob代替原始文件传入你现有的Azure上传方法即可,上传时建议保留原始文件的Content-Type元数据,方便后续解密渲染。

2. 拉取加密图片解密后查看

实现步骤:

  • 封装对应的AES解密工具方法:
/**
 * 解密加密Blob为原始图片Blob
 * @param encryptBlob 从Azure拉取的加密图片Blob
 * @returns 解密后的原始图片Blob
 */
const decryptImageBlob = (encryptBlob: Blob): Promise<Blob> => {
  return new Promise((resolve, reject) => {
    const blobReader = new FileReader();
    blobReader.onload = (loadEvent) => {
      try {
        const arrayBuffer = loadEvent.target?.result as ArrayBuffer;
        // 读取前12字节为加密时的IV
        const iv = CryptoJS.lib.WordArray.create(arrayBuffer.slice(0, 12));
        // 剩余部分为加密数据
        const cipherText = CryptoJS.lib.WordArray.create(arrayBuffer.slice(12));
        
        const decryptResult = CryptoJS.AES.decrypt(
          { ciphertext: cipherText } as CryptoJS.lib.CipherParams,
          AES_SECRET_KEY,
          { iv: iv, mode: CryptoJS.mode.GCM, padding: CryptoJS.pad.NoPadding }
        );
        
        // 解密结果转Blob
        const decryptedUint8 = new Uint8Array(decryptResult.words.length * 4);
        for (let i = 0; i < decryptResult.words.length; i++) {
          decryptedUint8[i * 4] = (decryptResult.words[i] >> 24) & 0xff;
          decryptedUint8[i * 4 + 1] = (decryptResult.words[i] >> 16) & 0xff;
          decryptedUint8[i * 4 + 2] = (decryptResult.words[i] >> 8) & 0xff;
          decryptedUint8[i * 4 + 3] = decryptResult.words[i] & 0xff;
        }
        resolve(new Blob([decryptedUint8], { type: encryptBlob.type }));
      } catch (err) {
        reject(err);
      }
    };
    blobReader.onerror = () => reject(blobReader.error);
    blobReader.readAsArrayBuffer(encryptBlob);
  });
};
  • 改造原有拉取查看逻辑:从Azure拉取到加密图片Blob后,调用decryptImageBlob得到解密后的原始Blob,通过URL.createObjectURL(decryptBlob)生成临时访问链接,赋值给img标签的src属性即可正常显示图片。
  • 优化提示:图片渲染完成后调用URL.revokeObjectURL(临时链接)释放内存,避免内存泄漏。

安全注意:前端硬编码密钥存在泄露风险,生产环境建议将密钥存储在后端服务,用户完成身份鉴权后再返回对应密钥,也可配合Azure Key Vault托管密钥实现更高安全等级的加密逻辑。

内容的提问来源于stack exchange,提问作者GMAC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 17:09:03