Skip to content

Commit b14de17

Browse files
committed
feature: support to generate RSA (4096-bits) SSH key
Signed-off-by: leo <longshuang@msn.cn>
1 parent 864c42b commit b14de17

5 files changed

Lines changed: 61 additions & 13 deletions

File tree

src/Models/SSHKeyPair.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.IO;
34
using System.Security.Cryptography;
45

56
namespace SourceGit.Models
67
{
8+
public record SSHKeyType(string Name, string Description, string Cmdline)
9+
{
10+
public static readonly List<SSHKeyType> Supported = [
11+
new SSHKeyType("ED25519", "Recommended", "-t ed25519"),
12+
new SSHKeyType("RSA", "4096 Bits", "-t rsa -b 4096"),
13+
];
14+
}
15+
716
public class SSHKeyPair
817
{
918
public string PrivateKeyPath { get; set; }

src/Resources/Locales/en_US.axaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,14 +903,15 @@
903903
<x:String x:Key="Text.SSHKeyHelper" xml:space="preserve">Open SSH Key Helper</x:String>
904904
<x:String x:Key="Text.SSHKeyHelper.ConfirmDeletion" xml:space="preserve">Do you really want to delete the following keys?</x:String>
905905
<x:String x:Key="Text.SSHKeyHelper.Fingerprint" xml:space="preserve">Fingerprint</x:String>
906-
<x:String x:Key="Text.SSHKeyHelper.Generator" xml:space="preserve">Generate SSH Key (ED25519)</x:String>
906+
<x:String x:Key="Text.SSHKeyHelper.Generator" xml:space="preserve">Generate SSH Key</x:String>
907907
<x:String x:Key="Text.SSHKeyHelper.Generator.ConfirmPassphrase" xml:space="preserve">Confirm Passphrase:</x:String>
908908
<x:String x:Key="Text.SSHKeyHelper.Generator.Email" xml:space="preserve">Email:</x:String>
909909
<x:String x:Key="Text.SSHKeyHelper.Generator.Email.Placeholder" xml:space="preserve">Required.</x:String>
910910
<x:String x:Key="Text.SSHKeyHelper.Generator.Name" xml:space="preserve">Key Name:</x:String>
911911
<x:String x:Key="Text.SSHKeyHelper.Generator.Name.Placeholder" xml:space="preserve">Required. For example: id_github</x:String>
912912
<x:String x:Key="Text.SSHKeyHelper.Generator.Passphrase" xml:space="preserve">Passphrase:</x:String>
913913
<x:String x:Key="Text.SSHKeyHelper.Generator.Start" xml:space="preserve">GENERATE</x:String>
914+
<x:String x:Key="Text.SSHKeyHelper.Generator.Type" xml:space="preserve">Type:</x:String>
914915
<x:String x:Key="Text.SSHKeyHelper.Generator.UsePassphrase" xml:space="preserve">Use passphrase for private key</x:String>
915916
<x:String x:Key="Text.SSHKeyHelper.Path" xml:space="preserve">Path</x:String>
916917
<x:String x:Key="Text.SSHKeyHelper.PublicKey" xml:space="preserve">Public Key</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,14 +907,15 @@
907907
<x:String x:Key="Text.SSHKeyHelper" xml:space="preserve">打开SSH密钥工具</x:String>
908908
<x:String x:Key="Text.SSHKeyHelper.ConfirmDeletion" xml:space="preserve">您确定要删除以下SSH密钥吗?</x:String>
909909
<x:String x:Key="Text.SSHKeyHelper.Fingerprint" xml:space="preserve">SHA-256 指纹</x:String>
910-
<x:String x:Key="Text.SSHKeyHelper.Generator" xml:space="preserve">生成ED25519格式的SSH密钥</x:String>
910+
<x:String x:Key="Text.SSHKeyHelper.Generator" xml:space="preserve">生成SSH密钥</x:String>
911911
<x:String x:Key="Text.SSHKeyHelper.Generator.ConfirmPassphrase" xml:space="preserve">再次确认口令:</x:String>
912912
<x:String x:Key="Text.SSHKeyHelper.Generator.Email" xml:space="preserve">邮箱:</x:String>
913913
<x:String x:Key="Text.SSHKeyHelper.Generator.Email.Placeholder" xml:space="preserve">必填项</x:String>
914914
<x:String x:Key="Text.SSHKeyHelper.Generator.Name" xml:space="preserve">密钥文件名:</x:String>
915915
<x:String x:Key="Text.SSHKeyHelper.Generator.Name.Placeholder" xml:space="preserve">必填项,如:id_github</x:String>
916916
<x:String x:Key="Text.SSHKeyHelper.Generator.Passphrase" xml:space="preserve">输入口令:</x:String>
917917
<x:String x:Key="Text.SSHKeyHelper.Generator.Start" xml:space="preserve">生 成</x:String>
918+
<x:String x:Key="Text.SSHKeyHelper.Generator.Type" xml:space="preserve">密钥类型:</x:String>
918919
<x:String x:Key="Text.SSHKeyHelper.Generator.UsePassphrase" xml:space="preserve">为私钥文件设置口令</x:String>
919920
<x:String x:Key="Text.SSHKeyHelper.Path" xml:space="preserve">文件路径</x:String>
920921
<x:String x:Key="Text.SSHKeyHelper.PublicKey" xml:space="preserve">公钥内容</x:String>

src/ViewModels/SSHKeyGenerator.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ namespace SourceGit.ViewModels
1010
{
1111
public partial class SSHKeyGenerator : ObservableValidator
1212
{
13+
public Models.SSHKeyType Type
14+
{
15+
get => _type;
16+
set => SetProperty(ref _type, value);
17+
}
18+
1319
[Required(ErrorMessage = "Name is required.")]
1420
[RegularExpression(@"^[a-zA-Z0-9_\-]+$", ErrorMessage = "Name can only contain letters, numbers, underscores, and hyphens.")]
1521
public string Name
@@ -98,12 +104,13 @@ public Models.SSHKeyPair Run()
98104
if (HasErrors)
99105
return null;
100106

107+
var type = _type?.Cmdline ?? "-t ed25519";
101108
var dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".ssh");
102109
var passphrase = _usePassphrase ? _passphrase : string.Empty;
103110
var keyFile = Path.Combine(dir, _name);
104111
var start = new ProcessStartInfo();
105112
start.FileName = "ssh-keygen";
106-
start.Arguments = $"-q -t ed25519 -N {passphrase.Quoted()} -C {_email.Quoted()} -f {keyFile.Quoted()}";
113+
start.Arguments = $"-q {type} -N {passphrase.Quoted()} -C {_email.Quoted()} -f {keyFile.Quoted()}";
107114
start.UseShellExecute = false;
108115
start.CreateNoWindow = true;
109116

@@ -130,6 +137,7 @@ public Models.SSHKeyPair Run()
130137
[GeneratedRegex(@"^[0-9a-zA-Z_\-\@\#\$\%\!\&\+\=]+$")]
131138
private static partial Regex REG_PSWD_FORMAT();
132139

140+
private Models.SSHKeyType _type = Models.SSHKeyType.Supported[0];
133141
private string _name;
134142
private string _email;
135143
private bool _usePassphrase;

src/Views/SSHKeyHelper.axaml

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@
150150
</ContentControl>
151151
</Grid>
152152

153-
<!-- Popup -->
153+
<!-- Generator Popup -->
154154
<Border Grid.Row="1"
155155
IsVisible="{Binding Generator, Mode=OneWay, Converter={x:Static ObjectConverters.IsNotNull}}">
156156
<ContentControl Content="{Binding Generator}">
@@ -170,54 +170,83 @@
170170
Classes="bold"
171171
Text="{DynamicResource Text.SSHKeyHelper.Generator}"/>
172172

173-
<Grid Margin="0,16,0,0" RowDefinitions="32,32,Auto,Auto,32" ColumnDefinitions="160,*">
173+
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32,Auto,Auto,32" ColumnDefinitions="160,*">
174174
<TextBlock Grid.Row="0" Grid.Column="0"
175+
HorizontalAlignment="Right" VerticalAlignment="Center"
176+
Margin="0,0,8,0"
177+
Text="{DynamicResource Text.SSHKeyHelper.Generator.Type}"/>
178+
<ComboBox Grid.Row="0" Grid.Column="1"
179+
Height="28" Padding="8,0"
180+
VerticalAlignment="Center" HorizontalAlignment="Stretch"
181+
ItemsSource="{Binding Source={x:Static m:SSHKeyType.Supported}}"
182+
SelectedItem="{Binding Type, Mode=TwoWay}"
183+
Grid.IsSharedSizeScope="True">
184+
<ComboBox.ItemTemplate>
185+
<DataTemplate DataType="m:SSHKeyType">
186+
<Grid Height="20" VerticalAlignment="Center">
187+
<Grid.ColumnDefinitions>
188+
<ColumnDefinition Width="*" SharedSizeGroup="KeyTypeNameColumn"/>
189+
<ColumnDefinition Width="Auto" SharedSizeGroup="KeyTypeDescColumn"/>
190+
</Grid.ColumnDefinitions>
191+
192+
<TextBlock Grid.Column="0" Text="{Binding Name, Mode=OneWay}"/>
193+
<TextBlock Grid.Column="1"
194+
Text="{Binding Description, Mode=OneWay}"
195+
Margin="8,0"
196+
FontSize="11"
197+
Foreground="{DynamicResource Brush.FG2}"/>
198+
</Grid>
199+
</DataTemplate>
200+
</ComboBox.ItemTemplate>
201+
</ComboBox>
202+
203+
<TextBlock Grid.Row="1" Grid.Column="0"
175204
HorizontalAlignment="Right" VerticalAlignment="Center"
176205
Margin="0,0,8,0"
177206
Text="{DynamicResource Text.SSHKeyHelper.Generator.Name}"/>
178-
<TextBox Grid.Row="0" Grid.Column="1"
207+
<TextBox Grid.Row="1" Grid.Column="1"
179208
Height="28"
180209
CornerRadius="3"
181210
VerticalAlignment="Center"
182211
Watermark="{DynamicResource Text.SSHKeyHelper.Generator.Name.Placeholder}"
183212
Text="{Binding Name, Mode=TwoWay}"/>
184213

185-
<TextBlock Grid.Row="1" Grid.Column="0"
214+
<TextBlock Grid.Row="2" Grid.Column="0"
186215
HorizontalAlignment="Right" VerticalAlignment="Center"
187216
Margin="0,0,8,0"
188217
Text="{DynamicResource Text.SSHKeyHelper.Generator.Email}"/>
189-
<TextBox Grid.Row="1" Grid.Column="1"
218+
<TextBox Grid.Row="2" Grid.Column="1"
190219
Height="28"
191220
CornerRadius="3"
192221
VerticalAlignment="Center"
193222
Watermark="{DynamicResource Text.SSHKeyHelper.Generator.Email.Placeholder}"
194223
Text="{Binding Email, Mode=TwoWay}"/>
195224

196-
<TextBlock Grid.Row="2" Grid.Column="0"
225+
<TextBlock Grid.Row="3" Grid.Column="0"
197226
HorizontalAlignment="Right" VerticalAlignment="Center"
198227
Margin="0,0,8,0"
199228
Text="{DynamicResource Text.SSHKeyHelper.Generator.Passphrase}"
200229
IsVisible="{Binding UsePassphrase, Mode=OneWay}"/>
201-
<TextBox Grid.Row="2" Grid.Column="1"
230+
<TextBox Grid.Row="3" Grid.Column="1"
202231
Height="28" Margin="0,2"
203232
CornerRadius="3"
204233
VerticalAlignment="Center"
205234
Text="{Binding Passphrase, Mode=TwoWay}"
206235
IsVisible="{Binding UsePassphrase, Mode=OneWay}"/>
207236

208-
<TextBlock Grid.Row="3" Grid.Column="0"
237+
<TextBlock Grid.Row="4" Grid.Column="0"
209238
HorizontalAlignment="Right" VerticalAlignment="Center"
210239
Margin="0,0,8,0"
211240
Text="{DynamicResource Text.SSHKeyHelper.Generator.ConfirmPassphrase}"
212241
IsVisible="{Binding UsePassphrase, Mode=OneWay}"/>
213-
<TextBox Grid.Row="3" Grid.Column="1"
242+
<TextBox Grid.Row="4" Grid.Column="1"
214243
Height="28" Margin="0,2"
215244
CornerRadius="3"
216245
VerticalAlignment="Center"
217246
Text="{Binding ConfirmedPassphrase, Mode=TwoWay}"
218247
IsVisible="{Binding UsePassphrase, Mode=OneWay}"/>
219248

220-
<CheckBox Grid.Row="4" Grid.Column="1"
249+
<CheckBox Grid.Row="5" Grid.Column="1"
221250
Content="{DynamicResource Text.SSHKeyHelper.Generator.UsePassphrase}"
222251
IsChecked="{Binding UsePassphrase, Mode=TwoWay}"/>
223252
</Grid>

0 commit comments

Comments
 (0)