PowerShell 5中导入RSA公钥实现字符串加密的技术问题
PowerShell 5中导入RSA公钥实现字符串加密的技术问题
兄弟,我太懂你这种憋屈的感觉了——PowerShell 5里确实没有那些PS7+才有的便捷RSA密钥导入方法,之前我也踩过这个坑!你想导入现成的PEM格式公钥来加密密码,得绕个弯手动处理ASN.1编码的密钥数据,下面给你一步步讲怎么实现:
核心问题原因
你遇到的报错本质是:PowerShell 5基于.NET Framework,而ImportFromPem、ImportRSAPublicKey这些便捷方法都是.NET Core/.NET 5+才引入的,所以在PS5里根本找不到这些方法。我们只能手动解析PEM公钥的底层ASN.1结构,提取RSA的核心参数(模数和指数)来完成导入。
完整实现步骤与代码
1. 清理PEM格式的公钥
首先要把PEM公钥里的头尾标记、换行符都去掉,只保留纯Base64编码的密钥内容:
# 替换成你的实际PEM公钥 $publicKeyPem = @" -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxQ...(省略部分内容) -----END PUBLIC KEY----- "@ # 清理PEM格式,提取纯Base64字符串 $cleanedBase64 = $publicKeyPem -replace "-----BEGIN PUBLIC KEY-----", "" ` -replace "-----END PUBLIC KEY-----", "" ` -replace "\s", ""
2. 解析ASN.1结构提取RSA参数
PEM公钥本质是DER编码的ASN.1结构(SubjectPublicKeyInfo),我们需要从中解析出RSA公钥的模数和指数:
# 把Base64转成字节数组 $keyBytes = [System.Convert]::FromBase64String($cleanedBase64) # 初始化ASN.1读取器 $reader = New-Object System.Security.Cryptography.AsnReader($keyBytes, [System.Security.Cryptography.AsnEncodingRules]::DER) # 读取SubjectPublicKeyInfo序列 $spkiSequence = $reader.ReadSequence() # 跳过算法标识符部分(我们只需要后面的公钥内容) $spkiSequence.ReadSequence() # 读取RSA公钥的原始字节 $rsaPublicKeyBytes = $spkiSequence.ReadOctetString() # 解析RSA公钥的模数和指数 $rsaReader = New-Object System.Security.Cryptography.AsnReader($rsaPublicKeyBytes, [System.Security.Cryptography.AsnEncodingRules]::DER) $rsaSequence = $rsaReader.ReadSequence() $modulus = $rsaSequence.ReadIntegerBytes() $exponent = $rsaSequence.ReadIntegerBytes()
3. 导入参数到RSACryptoServiceProvider
把提取到的模数和指数封装成RSAParameters对象,再导入到RSA加密实例中:
$rsaParams = New-Object System.Security.Cryptography.RSAParameters $rsaParams.Modulus = $modulus $rsaParams.Exponent = $exponent # 创建RSA加密实例并导入参数 $rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider $rsa.ImportParameters($rsaParams)
4. 加密用户输入的密码
现在就可以用这个RSA实例加密用户输入的密码了,最后输出加密后的Base64字符串:
# 安全读取用户密码(不显示明文) $passwordSecure = Read-Host "请输入密码" -AsSecureString # 把SecureString转成明文(仅用于加密,加密后立即丢弃) $passwordPlain = [System.Net.NetworkCredential]::new("", $passwordSecure).Password # 加密密码(这里用PKCS#1 v1.5填充,需要和私钥解密方式一致) $encryptedBytes = $rsa.Encrypt([System.Text.Encoding]::UTF8.GetBytes($passwordPlain), $false) # 转成Base64格式输出 $encryptedBase64 = [System.Convert]::ToBase64String($encryptedBytes) Write-Output $encryptedBase64
注意事项
- 如果你的私钥使用OAEP填充解密,需要把
Encrypt方法的第二个参数改成$true。 - 处理
SecureString转明文时要注意安全,加密完成后建议立即清空相关变量。
备注:内容来源于stack exchange,提问作者Lakitna




