C# 从现有私钥字符串创建 ssh-rsa 公钥

标签 c# rsa openssh public-key

我希望从现有私钥字符串创建 ssh-rsa 公钥

例如:

对于以下私有(private) rsa key 字符串:

    -----BEGIN RSA PRIVATE KEY-----     MIIEogIBAAKCAQEAvyN0aQKoYl/LAZ/1dQt0rWuSNyOty88k3439HT3rcT/vhaSk     d5lbnNKiYTzdDEkAxAnx4rxw6bEdD/8A9ISs0jy3pFRORFdbgBVFjIPR2NKbwVbs     9fcQNOQHcNslAyHA/yy57ktw+/6VyHYnHfXFlhkt1Jx4A1ubFIGzXttnXkwuNhdn     2JLJ5+JA3zRDJNBZR7p7NHVu9cRBwADm/WSzPqI6Sgs8kkU0eBcfy7qJRao3cmR5     95lLxkhFARufSW8lD/tCs2k99T2ZwZpKJpliA5VGjIC3iHhck3tpXs5w9sQ5Axhv     n1kTq5GKNi48r132KgRNJO+jIY0QSI60A6akbwIDAQABAoIBACCB3SiG5TBl7lbG     Z66SVjOwWdu627IP9st2kJfKkiJep1PpXndgw632PNugyE9wkwrETjkrp2B3WOQB     kJ4Feob/AJSYKf+Bg/RSqdNuD+B6YTcOm5pxfHYiWgmdm7ven75GUxDuD7cr4zmG     rrxvsj0G5z6Dpf2cNNHWBTWaxwfITaC8yXp6dx8o8V86/T0qrsEl+S0YJ5VQWt6L     I5GzipFNhhjcaemkOxDJg2T/g0FbpBEuj3RnwWNfRiiTCt+AuROg6/4M2oyLBE9W     e8n8KAUhZvRJA2dFwzZY38U9MfX9k9zIkJXtpkeghGx3M2zG3cQcFOaly6aFNHjr     QuEd6kECgYEA7NQgfqxuJ34kMnmtZeYccFGI6WUosuXUlgMhqU8CUnjIaRX8u8Ho     UjvjbezHNsI8tyH3vopgHNqTkcuElyuxKZQBTtUOFGG4a1HUS5tlo913DcnuSVIa     qL8kn3XVDHvuTr8tJbsb4KXrEMFfGoJBemU4ixSDiYWk/FdXvyyEEbECgYEAzpx6     JPOktmdaLf8U7snvlRY9daBqKfPqtKDxYgsC3xOp90Z3FMWQi5OyPmBsLGmjHxhe     YrPYQ3lbRh2JuRgZ7rTAxXN9dnDNgrh4tFjEEqQiFBCGlhP6syNM9Kx0YYNAoJN4     U29Tv71rxHJiFaLiRTh3Nopdn5ir4Raoj2fQgB8CgYBxCCFmNAfzA2plSNuwia5D     ETcmJejR0Y2v91imhRYXpJwKQ7s3JaorLXgzq9G82eG+ihDDOSn8O3o5GIh02h6Z     OJGTPW6V3bn2RrzrRQSyu+2pgBohlnUw2uGw1b1UUwX/QZFbs7zvcGELwy8P6OE1     eIAPKUBKb6W55jnz/VwfUQKBgGPTpQyPkAj1vNO2iLWrag/dtApOXJ0yljd5/8cA     TP3dsWShbk3h+yoFTbznt7xpuf//NTN5c8d+LkSdZvrAk18LhIyidX8xl4pOeTui     G/JpzXFmXrDKrHm7V6ZsYLrwwNwVBLFDe/KLojNDlPKhRbRuSONYTU4cZQeXfA/1     9/6/AoGAarF4JSdpzMzfacpLy2nsOM6XmL76B218uKANSHQy9k1X/Hp1u1StY8tQ     H4+DSrRUQBb4sdxkCRXVvMH3zttDGoIrSUvDqN3k4opcP8nmzMc/EDwD3xFgri/p     yBXBhE99r1B0p7fneXt58tTqtcevk5dQPzyF9SdsfUxD5PrnZRI=     -----END RSA PRIVATE KEY-----

我希望得到以下输出:

   ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/I3RpAqhiX8sBn/V1C3Sta5I3I63LzyTfjf0dPetxP++FpKR3mVuc0qJhPN0MSQDECfHivHDpsR0P/wD0hKzSPLekVE5EV1uAFUWMg9HY0pvBVuz19xA05Adw2yUDIcD/LLnuS3D7/pXIdicd9cWWGS3UnHgDW5sUgbNe22deTC42F2fYksnn4kDfNEMk0FlHuns0dW71xEHAAOb9ZLM+ojpKCzySRTR4Fx/LuolFqjdyZHn3mUvGSEUBG59JbyUP+0KzaT31PZnBmkommWIDlUaMgLeIeFyTe2leznD2xDkDGG+fWROrkYo2LjyvXfYqBE0k76MhjRBIjrQDpqRv administrator@LovelyTrust

我尝试了几种方法,但不幸的是没有给我想要的输出,例如,我能够使用我的私钥生成 RSA 对象:

    public static string ExtractPublicKeyFromPrivate(string privateKey)
    {
        var rsa = RSA.Create();
        rsa.ImportFromPem(privateKey.ToCharArray());
        return ""
    }

但两者

rsa.ExportRSAPublicKey()
rsa.ExportSubjectPublicKeyInfo()

没有给我想要的输出,有什么想法吗?

最佳答案

SSH key 格式有点复杂。而且,.NET 没有直接获取这种格式的 key 的方法。但是,这样的方法是可行的(我在 .NET 6 控制台应用程序中尝试过,并完全按照您想要的方式获得了公钥。):

// See https://aka.ms/new-console-template for more information
using System.Security.Cryptography;
using System.Text;

static byte[] ToBytes(int i)
{
    byte[] bytes = BitConverter.GetBytes(i);

    if (BitConverter.IsLittleEndian)
    {
        Array.Reverse(bytes);
    }

    return bytes;
}

string privateKey = "-----BEGIN RSA PRIVATE KEY-----     MIIEogIBAAKCAQEAvyN0aQKoYl/LAZ/1dQt0rWuSNyOty88k3439HT3rcT/vhaSk     d5lbnNKiYTzdDEkAxAnx4rxw6bEdD/8A9ISs0jy3pFRORFdbgBVFjIPR2NKbwVbs     9fcQNOQHcNslAyHA/yy57ktw+/6VyHYnHfXFlhkt1Jx4A1ubFIGzXttnXkwuNhdn     2JLJ5+JA3zRDJNBZR7p7NHVu9cRBwADm/WSzPqI6Sgs8kkU0eBcfy7qJRao3cmR5     95lLxkhFARufSW8lD/tCs2k99T2ZwZpKJpliA5VGjIC3iHhck3tpXs5w9sQ5Axhv     n1kTq5GKNi48r132KgRNJO+jIY0QSI60A6akbwIDAQABAoIBACCB3SiG5TBl7lbG     Z66SVjOwWdu627IP9st2kJfKkiJep1PpXndgw632PNugyE9wkwrETjkrp2B3WOQB     kJ4Feob/AJSYKf+Bg/RSqdNuD+B6YTcOm5pxfHYiWgmdm7ven75GUxDuD7cr4zmG     rrxvsj0G5z6Dpf2cNNHWBTWaxwfITaC8yXp6dx8o8V86/T0qrsEl+S0YJ5VQWt6L     I5GzipFNhhjcaemkOxDJg2T/g0FbpBEuj3RnwWNfRiiTCt+AuROg6/4M2oyLBE9W     e8n8KAUhZvRJA2dFwzZY38U9MfX9k9zIkJXtpkeghGx3M2zG3cQcFOaly6aFNHjr     QuEd6kECgYEA7NQgfqxuJ34kMnmtZeYccFGI6WUosuXUlgMhqU8CUnjIaRX8u8Ho     UjvjbezHNsI8tyH3vopgHNqTkcuElyuxKZQBTtUOFGG4a1HUS5tlo913DcnuSVIa     qL8kn3XVDHvuTr8tJbsb4KXrEMFfGoJBemU4ixSDiYWk/FdXvyyEEbECgYEAzpx6     JPOktmdaLf8U7snvlRY9daBqKfPqtKDxYgsC3xOp90Z3FMWQi5OyPmBsLGmjHxhe     YrPYQ3lbRh2JuRgZ7rTAxXN9dnDNgrh4tFjEEqQiFBCGlhP6syNM9Kx0YYNAoJN4     U29Tv71rxHJiFaLiRTh3Nopdn5ir4Raoj2fQgB8CgYBxCCFmNAfzA2plSNuwia5D     ETcmJejR0Y2v91imhRYXpJwKQ7s3JaorLXgzq9G82eG+ihDDOSn8O3o5GIh02h6Z     OJGTPW6V3bn2RrzrRQSyu+2pgBohlnUw2uGw1b1UUwX/QZFbs7zvcGELwy8P6OE1     eIAPKUBKb6W55jnz/VwfUQKBgGPTpQyPkAj1vNO2iLWrag/dtApOXJ0yljd5/8cA     TP3dsWShbk3h+yoFTbznt7xpuf//NTN5c8d+LkSdZvrAk18LhIyidX8xl4pOeTui     G/JpzXFmXrDKrHm7V6ZsYLrwwNwVBLFDe/KLojNDlPKhRbRuSONYTU4cZQeXfA/1     9/6/AoGAarF4JSdpzMzfacpLy2nsOM6XmL76B218uKANSHQy9k1X/Hp1u1StY8tQ     H4+DSrRUQBb4sdxkCRXVvMH3zttDGoIrSUvDqN3k4opcP8nmzMc/EDwD3xFgri/p     yBXBhE99r1B0p7fneXt58tTqtcevk5dQPzyF9SdsfUxD5PrnZRI=     -----END RSA PRIVATE KEY-----";

var rsa = RSA.Create();
rsa.ImportFromPem(privateKey.ToCharArray());

byte[] sshrsaBytes = Encoding.Default.GetBytes("ssh-rsa");
byte[] n = rsa.ExportParameters(false).Modulus;
byte[] e = rsa.ExportParameters(false).Exponent;
string buffer64;

using (var ms = new MemoryStream())
{
    ms.Write(ToBytes(sshrsaBytes.Length), 0, 4);
    ms.Write(sshrsaBytes, 0, sshrsaBytes.Length);
    ms.Write(ToBytes(e.Length), 0, 4);
    ms.Write(e, 0, e.Length);
    ms.Write(ToBytes(n.Length + 1), 0, 4);
    ms.Write(new byte[] { 0 }, 0, 1);
    ms.Write(n, 0, n.Length);
    ms.Flush();
    buffer64 = Convert.ToBase64String(ms.ToArray());
}

string comment = "administrator@LovelyTrust";
string publicKey = $"ssh-rsa {buffer64} {comment}";
Console.WriteLine(publicKey);

ToBytes 方法只是检查机器的字节顺序,并在必要时将字节转换为正确的顺序。

我们首先创建一个 RSA 对象并导入私钥,就像您所做的那样。之后,我提到的复杂部分开始,并持续到 using block 结束。最后,我们将该值与左侧的 ssh-rsa 单词和注释(如果您使用 PuTTY key 生成器,则这是在 Key comment 文本字段中输入的值)连接起来右边。

这段代码很大程度上受到SshKeyGenerator代码的启发。图书馆。不幸的是,该库本身不支持 key 导入。另一方面,如果您想要随机生成 SSH 私钥和公钥对,直接使用该库可能会更容易、更方便。

关于C# 从现有私钥字符串创建 ssh-rsa 公钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71636404/

相关文章:

perl - Perl : implementing socket programming ( system() never returns)

azure - Fabric 不断要求使用 SSH 连接输入密码

c# - 如何使用 ANTLR 获得正确的编码?

java - RSA 中 1024 位 key 长度的实数

java - 从字符串创建自定义 RSA key

来自 RSAPrivateKeySpec javax.crypto.BadPaddingException : Decryption error 的 Java RSA key

windows - 如何在 Windows 上使用 SSH 详细模式运行 git 命令?

c# - 如何解密字符串

c# - 如何使用 LINQ MVC 基于 AND 条件应用搜索过滤

c# - 更好的求和方式