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

如何从id_rsa.pub文件导入公钥以使用RSACryptoServiceProvider加密

错误原因

ImportSubjectPublicKeyInfo方法仅支持X.509标准的SubjectPublicKeyInfo格式公钥,而ssh-keygen生成的id_rsa.pub属于OpenSSH自定义公钥格式,二者结构不兼容,因此会抛出ASN1 corrupted data错误。

解决方案

方案1:公钥格式转换(操作最简单)

不需要修改代码,只需要把OpenSSH格式的公钥转成X.509格式即可:

  • 打开Git Bash或者WSL终端,进入id_rsa.pub所在目录
  • 执行转换命令:ssh-keygen -f id_rsa.pub -e -m pkcs8 > pub.pem
  • 打开生成的pub.pem文件,删除首尾的-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----标记,剩余的Base64内容即可直接用于公钥导入

导入示例代码:

// 替换为pub.pem中提取的Base64公钥内容
var rsaPublicKey = @"转换后的Base64公钥内容";
using var rsa = new RSACryptoServiceProvider();
rsa.ImportSubjectPublicKeyInfo(Convert.FromBase64String(rsaPublicKey), out _);
// 加密示例
var rawData = System.Text.Encoding.UTF8.GetBytes("待加密的消息");
var encryptedData = rsa.Encrypt(rawData, System.Security.Cryptography.RSAEncryptionPadding.OaepSHA256);

方案2:代码直接解析OpenSSH公钥(无需额外转换)

如果不想手动转换格式,可以直接在代码中解析OpenSSH公钥的Base64内容,提取RSA参数后导入:

// 填写id_rsa.pub中去掉ssh-rsa前缀和结尾用户名注释的Base64部分
var sshRsaBase64 = @"AAAAB3NzaC1yc2EAAAADAQABAAABgQC17+CDVUZ4dGFmHsuCcPiH8mmKg6ysyKj54sgtNaLjkQXeC94HEfCfLiULDqqY462ImfnALWbGf3/zwSxC7/xH9Ak/oZnsOxZ07iDVFEuuGmujNvcOPjNKW1MQC0Qka/FjxhVxTCqOYUjY8iOYZ5aAxdKkRYMCwDxa4BPCsEVDyEfksxmRT28yaACucbaHk6IrAWRAMozXB6JuonyJ68wbUUZ5hjjuZLmvB1EOOD6ue5A96bo1a/zGOAtVPU8HmZIPAxxQp7fAwNPcY3RMS/ytwqw+39ve7oLCaKvkmbnNrn55IhWBV8MwpE8Sl2UV33T/anzoBAFh6XCi3WrGPtTbIA9vmW6WuCtTGKbQPSdYvy6b06hiqBiQQ3V1xQOtG6WqsaOWv5DgPoO8Z/1ajHWbJqy9tKJsVBDAwdG+3H3pZ4j8N2Qo1ZDE3vMRvvSsidxUpfrfxmH5XKl2Xx4jARBculflfShCsqo9xnWN0/YJfZeFPCIdy1R6Rn36jAl1FpE=";
var pubBytes = Convert.FromBase64String(sshRsaBase64);

using var ms = new MemoryStream(pubBytes);
using var reader = new BinaryReader(ms);

// 读取公钥类型校验
var typeLen = ReadBigEndianInt32(reader);
var pubType = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(typeLen));
if (pubType != "ssh-rsa") throw new InvalidOperationException("非RSA类型SSH公钥");

// 读取公钥指数
var expLen = ReadBigEndianInt32(reader);
var exponent = reader.ReadBytes(expLen);

// 读取模数
var modLen = ReadBigEndianInt32(reader);
var modulus = reader.ReadBytes(modLen);

// 导入RSA参数
using var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(new RSAParameters
{
    Modulus = modulus.Skip(1).ToArray(), // 跳过前导填充0
    Exponent = exponent
});

// 后续直接调用加密方法即可

// 辅助方法:读取大端序32位整数
static int ReadBigEndianInt32(BinaryReader reader)
{
    var bytes = reader.ReadBytes(4);
    if (BitConverter.IsLittleEndian) Array.Reverse(bytes);
    return BitConverter.ToInt32(bytes, 0);
}
注意事项
  • 加密时建议使用RSAEncryptionPadding.OaepSHA256等高安全性填充方式,不推荐使用过时的Pkcs1填充
  • 跨端解密时需保证两端填充算法完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:27:03