C# 从现有私钥字符串创建 ssh-rsa public 密钥
C# create ssh-rsa public key from existing private key string
我希望从现有的私钥字符串创建一个 ssh-rsa public 密钥
例如:
对于以下私有 rsa 密钥字符串:
-----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 密钥格式有点复杂。此外,.NET 没有直接获取这种格式的密钥的方法。然而,这样的事情会起作用(我在 .NET 6 控制台应用程序中尝试过,并得到了 public 键,这正是你想要的。):
// 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
块结束。最后,我们将该值与左侧的 ssh-rsa 词和评论(这是在 Key comment 文本字段中输入的值连接起来如果您使用右侧的 PuTTY 密钥生成器)。
此代码很大程度上受到了 SshKeyGenerator 库代码的启发。不幸的是,库本身不支持密钥导入。另一方面,如果你想要随机生成 SSH 私有和 public 密钥对,直接使用库可能会更容易和更方便。
我希望从现有的私钥字符串创建一个 ssh-rsa public 密钥
例如:
对于以下私有 rsa 密钥字符串:
-----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 密钥格式有点复杂。此外,.NET 没有直接获取这种格式的密钥的方法。然而,这样的事情会起作用(我在 .NET 6 控制台应用程序中尝试过,并得到了 public 键,这正是你想要的。):
// 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
块结束。最后,我们将该值与左侧的 ssh-rsa 词和评论(这是在 Key comment 文本字段中输入的值连接起来如果您使用右侧的 PuTTY 密钥生成器)。
此代码很大程度上受到了 SshKeyGenerator 库代码的启发。不幸的是,库本身不支持密钥导入。另一方面,如果你想要随机生成 SSH 私有和 public 密钥对,直接使用库可能会更容易和更方便。