728x90
반응형
728x170
▶ MainWindow.xaml
<Window x:Class="TestProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800"
Height="600"
Title="TOTP(Time-based One-Time Password) 사용하기"
FontFamily="나눔고딕코딩"
FontSize="16">
<Grid>
<StackPanel Margin="10">
<GroupBox Name="keyGroup" Header="공유 키"
Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0"
VerticalAlignment="Center"
Content="키 길이" />
<TextBox Name="keyLengthTextBox" Grid.Row="0" Grid.Column="2"
VerticalAlignment="Center"
Width="50"
Height="25"
HorizontalContentAlignment="Right"
VerticalContentAlignment="Center"
Text="20" />
<Button Name="createKeyButton" Grid.Row="0" Grid.Column="4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Width="100"
Height="30"
Content="키 생성" />
<Label Grid.Row="2" Grid.Column="0"
VerticalAlignment="Center"
Content="생성 키" />
<TextBox Name="keyTextBox" Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="3"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Width="300"
Height="25"
VerticalContentAlignment="Center"
Text="" />
</Grid>
</GroupBox>
<GroupBox Header="TOPT 코드"
Margin="0 10 0 0"
Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Name="createCodeButton" Grid.Column="0"
VerticalAlignment="Center"
Width="100"
Height="30"
Content="코드 생성" />
<Label Grid.Row="0" Grid.Column="2"
VerticalAlignment="Center"
Content="TOPT 코드" />
<TextBox Name="codeTextBox" Grid.Column="4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Width="150"
Height="25"
VerticalContentAlignment="Center"
Text="" />
</Grid>
</GroupBox>
<GroupBox Header="검증"
Margin="0 10 0 0"
Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Name="validateButton" Grid.Column="0"
VerticalAlignment="Center"
Width="100"
Height="30"
Content="검증" />
<Label Grid.Column="2"
VerticalAlignment="Center"
Content="검증 결과" />
<TextBox Name="resultTextBox" Grid.Column="4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Width="100"
Height="25"
VerticalContentAlignment="Center"
IsReadOnly="True"
Text="" />
</Grid>
</GroupBox>
</StackPanel>
</Grid>
</Window>
728x90
▶ MainWindow.xaml.cs
using System.Windows;
using System.Windows.Controls;
using OtpNet;
namespace TestProject
{
/// <summary>
/// 메인 윈도우
/// </summary>
public partial class MainWindow : Window
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// TOTP
/// </summary>
private Totp totp = null;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary>
/// 생성자
/// </summary>
public MainWindow()
{
InitializeComponent();
this.createKeyButton.Click += createKeyButton_Click;
this.keyTextBox.TextChanged += keyTextBox_TextChanged;
this.createCodeButton.Click += createCodeButton_Click;
this.validateButton.Click += validateButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 키 생성 버튼 클릭시 처리하기 - createKeyButton_Click(sender, e)
/// <summary>
/// 키 생성 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void createKeyButton_Click(object sender, RoutedEventArgs e)
{
this.keyTextBox.Clear();
int keyLength;
if(!int.TryParse(this.keyLengthTextBox.Text, out keyLength))
{
MessageBox.Show(this, "키 길이 항목을 입력해 주시기 바랍니다.", "확인", MessageBoxButton.OK, MessageBoxImage.Information);
this.keyLengthTextBox.Focus();
this.keyLengthTextBox.SelectAll();
return;
}
if(keyLength < 10 || keyLength > 30)
{
MessageBox.Show(this, "키 길이 항목의 값을 10 ~ 30 사이에서 입력해 주시기 바랍니다.", "확인", MessageBoxButton.OK, MessageBoxImage.Information);
this.keyLengthTextBox.Focus();
this.keyLengthTextBox.SelectAll();
return;
}
byte[] keyByteArray = KeyGeneration.GenerateRandomKey(keyLength);
string key = Base32Encoding.ToString(keyByteArray);
this.keyTextBox.Text = key;
this.keyTextBox.Focus();
this.keyTextBox.SelectAll();
Clipboard.SetText(key);
}
#endregion
#region 키 텍스트 박스 텍스트 변경시 처리하기 - keyTextBox_TextChanged(sender, e)
/// <summary>
/// 키 텍스트 박스 텍스트 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void keyTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
string key = this.keyTextBox.Text.Trim();
byte[] keyByteArray = Base32Encoding.ToBytes(key);
this.totp = new Totp(keyByteArray);
}
#endregion
#region 코드 생성 버튼 클릭시 처리하기 - createCodeButton_Click(sender, e)
/// <summary>
/// 코드 생성 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void createCodeButton_Click(object sender, RoutedEventArgs e)
{
this.codeTextBox.Clear();
string key = this.keyTextBox.Text.Trim();
if(string.IsNullOrWhiteSpace(key))
{
MessageBox.Show(this, "공유 키 항목을 입력해 주시기 바랍니다.", "확인", MessageBoxButton.OK, MessageBoxImage.Information);
this.keyTextBox.Focus();
this.keyTextBox.SelectAll();
return;
}
byte[] keyByteArray = Base32Encoding.ToBytes(key);
Totp totp = new Totp(keyByteArray);
string code = totp.ComputeTotp();
this.codeTextBox.Text = code;
this.codeTextBox.Focus();
this.codeTextBox.SelectAll();
Clipboard.SetText(code);
}
#endregion
#region 검증 버튼 클릭시 처리하기 - validateButton_Click(sender, e)
/// <summary>
/// 검증 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void validateButton_Click(object sender, RoutedEventArgs e)
{
this.resultTextBox.Clear();
string key = this.keyTextBox.Text.Trim();
if(string.IsNullOrWhiteSpace(key))
{
MessageBox.Show(this, "공유 키 항목을 입력해 주시기 바랍니다.", "확인", MessageBoxButton.OK, MessageBoxImage.Information);
this.keyTextBox.Focus();
this.keyTextBox.SelectAll();
return;
}
string code = this.codeTextBox.Text.Trim();
if(string.IsNullOrWhiteSpace(code))
{
MessageBox.Show(this, "TOPT 코드 항목을 입력해 주시기 바랍니다.", "확인", MessageBoxButton.OK, MessageBoxImage.Information);
this.codeTextBox.Focus();
this.codeTextBox.SelectAll();
return;
}
bool result = this.totp.VerifyTotp(code, out long timeStepMatched, VerificationWindow.RfcSpecifiedNetworkDelay);
this.resultTextBox.Text = result ? "VALID" : "INVALID";
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] Dispatcher 클래스 : DisableProcessing 메소드를 사용해 디스패처 비활성하기 (0) | 2021.05.01 |
---|---|
[C#/WPF] Dispatcher 클래스 : PushFrame 메소드를 사용해 UI 업데이트 하기 (0) | 2021.04.30 |
[C#/WPF] Dispatcher 클래스 : BeginInvoke 메소드 사용하기 (0) | 2021.04.30 |
[C#/WPF] ScrollViewer 클래스 : 애니메이션 스크롤 뷰어 사용하기 (0) | 2021.04.28 |
[C#/WPF] UWP API 사용하기 (0) | 2021.04.26 |
[C#/WPF] Dispatcher 클래스 : Invoke 메소드를 사용해 UI 업데이트 하기 (0) | 2021.04.22 |
[C#/WPF] 관리자 권한으로 실행하기 (0) | 2021.04.03 |
[C#/WPF] 가상 키보드 사용하기 (0) | 2021.03.27 |
[C#/WPF] HTML을 XAML로 변환하기 (0) | 2021.03.20 |
[C#/WPF] LogicalTreeHelper 클래스 : GetChildren 정적 메소드를 사용해 논리적 자식 열거 가능형 구하기 (0) | 2021.03.20 |
댓글을 달아 주세요