PowerShell中ConvertFrom-SecureString用SecureKey时字符串被截断问题
问题根因
该截断行为是PowerShell 5.1版本的已知缺陷,仅在使用-SecureKey参数时触发,PowerShell 7及以上版本已修复该问题。
底层的异常逻辑如下:
- 当
ConvertFrom-SecureString/ConvertTo-SecureString接收-SecureKey参数传入的SecureString对象时,会先将SecureString解密为明文字符串,再转换为字节数组作为AES密钥使用。 - 5.1版本中,内置的加解密逻辑在处理超过32字符的明文时,错误地截断了加密输出,导致解密后只能拿到前32位明文内容。
- 你提到的SecureKey长度为16字符属于正常配置,本身不是问题诱因,仅和采用的AES加密等级(16字节对应AES-128)相关。
修复方案
方案1(最推荐,全版本兼容):改用-Key参数替代-SecureKey
如果可以直接获取AES密钥的字节数组,不需要将密钥转为SecureString再传入-SecureKey,直接将字节数组传入-Key参数即可完全规避该问题,示例代码如下:
# 先将base64格式的AES密钥转为字节数组 $AESKey = [Convert]::FromBase64String($base64FormatAesKey) # 加密流程 $stringToSecure = 'ThisIsMySuperStrongVeryLongPassword' $originSecureString = ConvertTo-SecureString -String $stringToSecure -AsPlainText -Force $encryptedString = ConvertFrom-SecureString -SecureString $originSecureString -Key $AESKey # 解密流程 $decryptedSecureString = ConvertTo-SecureString -String $encryptedString -Key $AESKey $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ('dummy@cat.com', $decryptedSecureString) # 验证输出,可得到完整原始密码 $Credential.GetNetworkCredential().Password
方案2:升级PowerShell版本
直接升级到PowerShell 7.0及以上版本,该版本已经修复了-SecureKey参数对应的截断缺陷,原有代码无需修改即可正常运行。
方案3(仅适用于必须留在PowerShell 5.1且必须用-SecureKey的场景)
自行实现基于AES的SecureString加解密逻辑,不依赖内置参数的缺陷实现。
内容的提问来源于stack exchange,提问作者Tadeáš Bucha
相关产品推荐
相关产品推荐

