如何在PowerShell脚本中加密Azure存储账户密钥解决403认证报错
报错根因
现有脚本触发两类报错的直接原因如下:
ConvertFrom-SecureString基于Windows DPAPI加密导出的字符串,仅能在同一台Windows设备、同一个运行脚本的用户身份下解密,跨设备、跨用户读取到的是无效乱码,并非原始存储密钥,传入存储上下文后自然触发403鉴权失败- 脚本存在多处语法/拼写错误:
New-AzStorageConext拼写错误(正确为New-AzStorageContext)、Test-Path未传入待检测路径参数、AddDAys拼写错误(正确为AddDays)、$ConfigFile路径存在无效双斜杠 - 从配置文件读取的
$SharePassword是加密后的字符串,并非Base64格式的原始存储密钥,直接传入-StorageAccountKey参数就会触发“输入不是有效的Base64字符串”错误;另外构造PSCredential时用单引号包裹变量,会导致变量不被解析,写法本身无效。
安全实现方案
以下两种方案均不需要在脚本中硬编码明文存储密钥,符合安全要求:
方案1:本地DPAPI加密存储(单设备单用户运行场景)
适配你最初的加密思路,补全解密逻辑即可,不需要额外依赖Azure AD权限。
- 首次执行一次密钥初始化操作,输入存储密钥后会加密保存到本地文件,仅当前运行用户可解密:
Read-Host -AsSecureString "输入存储账户密钥" | ConvertFrom-SecureString | Out-File -FilePath "C:\test_blob\storage_key.sec"
- 正式业务脚本逻辑:
# 基础参数配置 $StorageAccountName = 'test_acc' $Container = 'test' $DestinationFolder = 'C:\Users\user1\Blobs' $KeyPath = "C:\test_blob\storage_key.sec" # 校验密钥文件 if (-not (Test-Path $KeyPath)) { Write-Host "密钥文件不存在,请先执行初始化步骤生成:$KeyPath" exit 1 } # 读取并解密存储密钥 $secureKey = Get-Content $KeyPath | ConvertTo-SecureString $keyPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureKey) $storageKey = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($keyPtr) [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($keyPtr) # 创建存储上下文(修正原拼写错误) $Context = New-AzStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKey # 查询符合时间条件的Blob $ListBlob = Get-AzStorageBlob -Context $Context -Container $Container | Where-Object {$_.LastModified -lt (Get-Date).AddDays(-1)}
注意:该方案生成的加密文件不能跨设备、跨用户使用,否则解密会失败。
方案2:Azure AD身份鉴权(生产环境优先推荐)
完全弃用存储账户密钥,从根源避免密钥泄露风险,是官方推荐的安全访问方式。
- 提前给运行脚本的身份(用户账号、服务主体、虚拟机托管标识均可)分配目标存储账户的存储Blob数据读取者权限,权限范围覆盖目标容器。
- 脚本无需存储任何密钥,直接用登录身份创建上下文:
# 未登录Az环境时先执行登录,托管标识场景可跳过该步骤 Connect-AzAccount # 基础参数配置 $StorageAccountName = 'test_acc' $Container = 'test' $DestinationFolder = 'C:\Users\user1\Blobs' # 用当前Azure AD身份创建上下文,无需传入存储密钥 $Context = New-AzStorageContext -StorageAccountName $StorageAccountName -UseConnectedAccount # 查询符合时间条件的Blob $ListBlob = Get-AzStorageBlob -Context $Context -Container $Container | Where-Object {$_.LastModified -lt (Get-Date).AddDays(-1)}
原有脚本的额外修正点
- 不建议用XML格式存储DPAPI加密串,直接导出为文本文件即可,减少不必要的格式解析逻辑
- 配置文件路径
C:\Users\\config_file.xml的双斜杠属于无效路径,需要补全用户目录或用$env:USERPROFILE拼接通用路径 - 初始化
$ListBlob空数组的操作无必要,Get-AzStorageBlob返回结果可直接赋值给变量。
内容的提问来源于stack exchange,提问作者SakZepelin
相关产品推荐
相关产品推荐

