使用ConvertFrom-SecureString的-SecureKey参数时遇密钥无效问题求助
问题描述
我尝试在PowerShell中使用ConvertFrom-SecureString的-SecureKey参数,操作步骤如下:
- 创建字节数组
$length = 256 $byte = $length / 8 $key = New-Object Byte[] $byte $null = [Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($key)
- 将字节数组转换为字符串再转为SecureString
$keyString = [System.BitConverter]::ToString($key) $secureKeyString = convertto-securestring $keyString -asPlainText -force
- 最终将该SecureString作为SecureKey使用
convertfrom-securestring (convertto-securestring "stringToProtect" -asplaintext -force) -secureKey $secureKeyString
执行后抛出异常:the specified key is not valid. Valid key length settings are either 128 bits, 192 bits, or 256 bits.
我尝试了其他字节数组转字符串的方式,例如:
[System.Text.Encoding]::ASCII.GetString($Key)
但最终仍得到相同的异常,请问我哪里操作错误?
问题原因及解决方法
核心错误在于把字节数组转成普通字符串再转SecureString的过程,破坏了原密钥的字节结构。
-SecureKey参数要求的SecureString,本质是要还原出原始的256位(32字节)密钥字节数组,但你用BitConverter.ToString()或者ASCII编码转字符串时,会改变字节的原始内容:
BitConverter.ToString($key)会把每个字节转成十六进制字符串(比如0A-1B-2C),转成SecureString再还原时,得到的字节数远大于32,不符合要求;- ASCII编码转换会把不可打印的字节转成默认字符,丢失原始字节信息,同样导致还原后的密钥长度或内容错误。
正确的做法是直接把原始字节数组转成SecureString,不需要经过普通字符串中间步骤:
正确操作步骤
- 创建256位密钥字节数组(这一步没问题)
$keyLengthBits = 256 $keyBytes = New-Object Byte[] ($keyLengthBits / 8) [Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($keyBytes)
- 直接将字节数组转换为SecureString
$secureKey = [System.Security.SecureString]::new() foreach ($byte in $keyBytes) { $secureKey.AppendChar([char]$byte) }
- 使用该SecureKey加密字符串
$plainTextSecureString = ConvertTo-SecureString "stringToProtect" -AsPlainText -Force $encryptedString = ConvertFrom-SecureString $plainTextSecureString -SecureKey $secureKey
补充说明
如果需要保存密钥到文件,不要转成普通字符串,而是直接保存字节数组,或者用ConvertFrom-SecureString把SecureKey本身加密后保存(可以用DPAPI,不需要额外密钥):
# 保存SecureKey到文件 ConvertFrom-SecureString $secureKey | Out-File "C:\temp\encryptedKey.txt" # 读取密钥时 $savedSecureKey = Get-Content "C:\temp\encryptedKey.txt" | ConvertTo-SecureString
内容的提问来源于stack exchange,提问作者Toni
相关产品推荐
相关产品推荐

