You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PowerShell生成与OpenSSL兼容的加密RSA私钥?

问题:PowerShell生成OpenSSL兼容加密私钥遇ASN1错误,无ExportRSAPrivateKey()可用,能否实现转换?

我尝试使用Stack Overflow用户Topaco提供的代码,在PowerShell中生成与OpenSSL格式一致的加密私钥,但运行时出现以下ASN1编码错误:

6788:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:./crypto/asn1/tasn_dec.c:1294: 
6788:error:0D06C03A:asn1 encoding routines:ASN1_D2I_EX_PRIMITIVE:nested asn1 error:./crypto/asn1/tasn_dec.c:830: 
6788:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:./crypto/asn1/tasn_dec.c:749:Field=n, Type=RSA 
6788:error:0D09A00D:asn1 encoding routines:d2i_PrivateKey:ASN1 lib:./crypto/asn1/d2i_pr.c:99: 
6788:error:0907B00D:PEM routines:PEM_READ_BIO_PRIVATEKEY:ASN1 lib:./crypto/pem/pem_pkey.c:125:

同时我无法使用ExportRSAPrivateKey()函数。我已从PFX格式证书中导出非加密RSA私钥(格式为-----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY-----),希望将其转换为-----BEGIN ENCRYPTED PRIVATE KEY-----...-----END ENCRYPTED PRIVATE KEY-----格式的加密私钥。服务器未安装且不打算安装OpenSSL,请问能否通过PowerShell实现该需求?


解决方案

可以通过PowerShell实现,核心是利用.NET类库手动处理PKCS#8标准的ASN.1编码和加密逻辑,避开ExportRSAPrivateKey()的限制,步骤如下:

1. 加载未加密RSA私钥

先将PEM格式的私钥转换为可操作的RSA对象:

# 读取本地PEM私钥文件
$rsaPrivateKeyPem = Get-Content -Path "path/to/your/rsa_private_key.pem" -Raw
# 清理PEM头部、尾部和空白字符
$cleanedPem = $rsaPrivateKeyPem -replace "-----BEGIN RSA PRIVATE KEY-----", "" `
                               -replace "-----END RSA PRIVATE KEY-----", "" `
                               -replace "\s", ""
# 转换为字节数组并导入到RSA对象
$keyBytes = [Convert]::FromBase64String($cleanedPem)
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider
$rsa.ImportPkcs8PrivateKey($keyBytes, [ref]$null)

2. 生成OpenSSL兼容的加密私钥

严格遵循PKCS#8加密私钥标准,用PBKDF2生成密钥、AES-256-CBC加密私钥,再组装符合OpenSSL要求的ASN.1结构:

# 设置加密参数
$password = "your_secure_password"
$salt = [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes(16)
$iterations = 10000 # OpenSSL默认迭代次数

# 用PBKDF2生成AES密钥和IV
$keyDerivation = New-Object System.Security.Cryptography.Rfc2898DeriveBytes($password, $salt, $iterations)
$aesKey = $keyDerivation.GetBytes(32) # AES-256密钥长度
$iv = $keyDerivation.GetBytes(16)

# 导出PKCS#8格式的未加密私钥
$pkcs8RawBytes = $rsa.ExportPkcs8PrivateKey()

# AES-256-CBC加密私钥
$aes = New-Object System.Security.Cryptography.AesManaged
$aes.Key = $aesKey
$aes.IV = $iv
$aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
$encryptor = $aes.CreateEncryptor()
$encryptedKeyBytes = $encryptor.TransformFinalBlock($pkcs8RawBytes, 0, $pkcs8RawBytes.Length)

# 组装完整的PKCS#8加密私钥ASN.1结构
$asnWriter = New-Object System.Security.Cryptography.AsnWriter([System.Security.Cryptography.AsnEncodingRules]::BER)
$asnWriter.PushSequence()
    # EncryptedPrivateKeyInfo版本
    $asnWriter.WriteInteger(0)
    # 加密算法标识符(包含PBKDF2参数)
    $asnWriter.PushSequence()
        $asnWriter.WriteObjectIdentifier("1.2.840.113549.1.5.12") # PBKDF2 OID
        $asnWriter.PushSequence()
            $asnWriter.WriteOctetString($salt)
            $asnWriter.WriteInteger($iterations)
            $asnWriter.WriteInteger(32) # 导出密钥长度
            # 嵌套AES-256-CBC算法参数
            $asnWriter.PushSequence()
                $asnWriter.WriteObjectIdentifier("2.16.840.1.101.3.4.1.42") # AES-256-CBC OID
                $asnWriter.PushSequence()
                    $asnWriter.WriteOctetString($iv)
                $asnWriter.PopSequence()
            $asnWriter.PopSequence()
        $asnWriter.PopSequence()
    $asnWriter.PopSequence()
    # 加密后的私钥数据
    $asnWriter.WriteOctetString($encryptedKeyBytes)
$asnWriter.PopSequence()

# 转换为PEM格式
$encryptedPkcs8Bytes = $asnWriter.Encode()
$encryptedPem = "-----BEGIN ENCRYPTED PRIVATE KEY-----`n" + `
                [Convert]::ToBase64String($encryptedPkcs8Bytes, [System.Base64FormattingOptions]::InsertLineBreaks) + `
                "`n-----END ENCRYPTED PRIVATE KEY-----"

# 保存到本地文件
$encryptedPem | Out-File -Path "path/to/encrypted_private_key.pem" -Encoding ASCII

3. 原ASN1错误说明

你之前遇到的错误,是因为生成的PKCS#8结构不符合OpenSSL的预期——要么缺少PBKDF2参数的嵌套封装,要么ASN.1标签类型错误。上面的代码严格遵循PKCS#8标准和OpenSSL的加密私钥格式,可避免此类问题。


内容的提问来源于stack exchange,提问作者Ekta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 06:15:13