You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PowerShell 5中导入RSA公钥实现字符串加密的技术问题

PowerShell 5中导入RSA公钥实现字符串加密的技术问题

兄弟,我太懂你这种憋屈的感觉了——PowerShell 5里确实没有那些PS7+才有的便捷RSA密钥导入方法,之前我也踩过这个坑!你想导入现成的PEM格式公钥来加密密码,得绕个弯手动处理ASN.1编码的密钥数据,下面给你一步步讲怎么实现:

核心问题原因

你遇到的报错本质是:PowerShell 5基于.NET Framework,而ImportFromPemImportRSAPublicKey这些便捷方法都是.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

火山引擎 最新活动