[C#/WINFORM] RNGCryptoServiceProvider 클래스 : GetBytes 메소드를 사용해 임시 패스워드 생성기 만들기
C#/WinForm 2022. 11. 5. 23:54728x90
반응형
728x170
■ RNGCryptoServiceProvider 클래스의 GetBytes 메소드를 사용해 임시 패스워드 생성기를 만드는 방법을 보여준다.
▶ MainForm.cs
using System;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 소문자 목록
/// </summary>
private const string LOWER_CASE_CHARACTER_LIST = "abcdefghijklmnopqrstuvwxyz";
/// <summary>
/// 대문자 목록
/// </summary>
private const string UPPER_CASE_CHARACTER_LIST = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/// <summary>
/// 숫자 문자 목록
/// </summary>
private const string NUMBER_CHARACTER_LIST = "0123456789";
/// <summary>
/// 특수 문자 목록
/// </summary>
private const string SPECIAL_CHARACTER_LIST = @"~!@#$%^&*():;[]{}<>,.?/\|";
/// <summary>
/// RNG 암호 서비스 공급자
/// </summary>
private RNGCryptoServiceProvider rngCryptoServiceProvider = new RNGCryptoServiceProvider();
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
this.allowLowercaseCheckBox.CheckedChanged += allowLowercaseCheckBox_CheckedChanged;
this.requireLowercaseCheckBox.CheckedChanged += requireLowercaseCheckBox_CheckedChanged;
this.allowUppercaseCheckBox.CheckedChanged += allowUppercaseCheckBox_CheckedChanged;
this.requireUppercaseCheckBox.CheckedChanged += requireUppercaseCheckBox_CheckedChanged;
this.allowNumberChceckBox.CheckedChanged += allowNumberChceckBox_CheckedChanged;
this.requireNumberCheckBox.CheckedChanged += requireNumberCheckBox_CheckedChanged;
this.allowSpecialCharacterCheckBox.CheckedChanged += allowSpecialCharacterCheckBox_CheckedChanged;
this.requireSpecialCharacterCheckBox.CheckedChanged += requireSpecialCharacterCheckBox_CheckedChanged;
this.allowUnderscoreCharacterCheckBox.CheckedChanged += allowUnderscoreCharacterCheckBox_CheckedChanged;
this.requireUnderscoreCharacterCheckBox.CheckedChanged += requireUnderscoreCharacterCheckBox_CheckedChanged;
this.allowWhitespaceCharacterCheckBox.CheckedChanged += allowWhitespaceCharacterCheckBox_CheckedChanged;
this.requireWhitespaceCharacterCheckBox.CheckedChanged += requireWhitespaceCharacterCheckBox_CheckedChanged;
this.allowOtherCheckBox.CheckedChanged += allowOtherCheckBox_CheckedChanged;
this.requireOtherCheckBox.CheckedChanged += requireOtherCheckBox_CheckedChanged;
this.generateButton.Click += generateButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 소문자 허용 체크 박스 체크 변경시 처리하기 - allowLowercaseCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 소문자 허용 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void allowLowercaseCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(!this.allowLowercaseCheckBox.Checked)
{
this.requireLowercaseCheckBox.Checked = false;
}
}
#endregion
#region 소문자 필수 체크 박스 체크 변경시 처리하기 - requireLowercaseCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 소문자 필수 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void requireLowercaseCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(this.requireLowercaseCheckBox.Checked)
{
this.allowLowercaseCheckBox.Checked = true;
}
}
#endregion
#region 대문자 허용 체크 박스 체크 변경시 처리하기 - allowUppercaseCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 대문자 허용 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void allowUppercaseCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(!this.allowUppercaseCheckBox.Checked)
{
this.requireUppercaseCheckBox.Checked = false;
}
}
#endregion
#region 대문자 필수 체크 박스 체크 변경시 처리하기 - requireUppercaseCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 대문자 필수 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void requireUppercaseCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(this.requireUppercaseCheckBox.Checked)
{
this.allowUppercaseCheckBox.Checked = true;
}
}
#endregion
#region 숫자 허용 체크 박스 체크 변경시 처리하기 - allowNumberChceckBox_CheckedChanged(sender, e)
/// <summary>
/// 숫자 허용 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void allowNumberChceckBox_CheckedChanged(object sender, EventArgs e)
{
if(!this.allowNumberChceckBox.Checked)
{
this.requireNumberCheckBox.Checked = false;
}
}
#endregion
#region 숫자 필수 체크 박스 체크 변경시 처리하기 - requireNumberCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 숫자 필수 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void requireNumberCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(requireNumberCheckBox.Checked)
{
this.allowNumberChceckBox.Checked = true;
}
}
#endregion
#region 특수 문자 허용 체크 박스 체크 변경시 처리하기 - allowSpecialCharacterCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 특수 문자 허용 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void allowSpecialCharacterCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(!this.allowSpecialCharacterCheckBox.Checked)
{
this.requireSpecialCharacterCheckBox.Checked = false;
}
}
#endregion
#region 특수 문자 필수 체크 박스 체크 변경시 처리하기 - requireSpecialCharacterCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 특수 문자 필수 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void requireSpecialCharacterCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(this.requireSpecialCharacterCheckBox.Checked)
{
this.allowSpecialCharacterCheckBox.Checked = true;
}
}
#endregion
#region 밑줄 문자 허용 체크 박스 체크 변경시 처리하기 - allowUnderscoreCharacterCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 밑줄 문자 허용 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void allowUnderscoreCharacterCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(!this.allowUnderscoreCharacterCheckBox.Checked)
{
this.requireUnderscoreCharacterCheckBox.Checked = false;
}
}
#endregion
#region 밑줄 문자 체크 박스 체크 변경시 처리하기 - requireUnderscoreCharacterCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 밑줄 문자 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void requireUnderscoreCharacterCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(this.requireUnderscoreCharacterCheckBox.Checked)
{
this.allowUnderscoreCharacterCheckBox.Checked = true;
}
}
#endregion
#region 공백 문자 허용 체크 박스 체크 변경시 처리하기 - allowWhitespaceCharacterCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 공백 문자 허용 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void allowWhitespaceCharacterCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(!this.allowWhitespaceCharacterCheckBox.Checked)
{
this.requireWhitespaceCharacterCheckBox.Checked = false;
}
}
#endregion
#region 공백 문자 필수 체크 박스 체크 변경시 처리하기 - requireWhitespaceCharacterCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 공백 문자 필수 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void requireWhitespaceCharacterCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(this.requireWhitespaceCharacterCheckBox.Checked)
{
this.allowWhitespaceCharacterCheckBox.Checked = true;
}
}
#endregion
#region 기타 허용 체크 박스 체크 변경시 처리하기 - allowOtherCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 기타 허용 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void allowOtherCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(!this.allowOtherCheckBox.Checked)
{
this.requireOtherCheckBox.Checked = false;
}
}
#endregion
#region 기타 필수 체크 박스 체크 변경시 처리하기 - requireOtherCheckBox_CheckedChanged(sender, e)
/// <summary>
/// 기타 필수 체크 박스 체크 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void requireOtherCheckBox_CheckedChanged(object sender, EventArgs e)
{
if(this.requireOtherCheckBox.Checked)
{
this.allowOtherCheckBox.Checked = true;
}
}
#endregion
#region 생성하기 버튼 클릭시 처리하기 - generateButton_Click(sender, e)
/// <summary>
/// 생성하기 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void generateButton_Click(object sender, EventArgs e)
{
try
{
this.passwordTextBox.Text = GetRandomPassword();
Clipboard.Clear();
Clipboard.SetText(this.passwordTextBox.Text);
}
catch(Exception exception)
{
MessageBox.Show(exception.Message);
}
this.passwordTextBox.SelectAll();
this.passwordTextBox.Focus();
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 임의 정수 값 구하기 - GetRandomIntegerValue(minimumValue, maximumValue)
/// <summary>
/// 임의 정수 값 구하기
/// </summary>
/// <param name="minimumValue">최소 값</param>
/// <param name="maximumValue">최대 값</param>
/// <returns>임의 정수 값</returns>
private int GetRandomIntegerValue(int minimumValue, int maximumValue)
{
uint scale = uint.MaxValue;
while(scale == uint.MaxValue)
{
byte[] byteArray = new byte[4];
this.rngCryptoServiceProvider.GetBytes(byteArray);
scale = BitConverter.ToUInt32(byteArray, 0);
}
return (int)(minimumValue + (maximumValue - minimumValue) * (scale / (double)uint.MaxValue));
}
#endregion
#region 임의 문자 구하기 - GetRandomCharacter(source)
/// <summary>
/// 임의 문자 구하기
/// </summary>
/// <param name="source">소스 문자열</param>
/// <returns>임의 문자</returns>
private string GetRandomCharacter(string source)
{
return source.Substring(GetRandomIntegerValue(0, source.Length - 1), 1);
}
#endregion
#region 문자열 임의로 섞기 - RandomizeString(source)
/// <summary>
/// 문자열 임의로 섞기
/// </summary>
/// <param name="source">소스 문자열</param>
/// <returns>임의로 섞은 문자열</returns>
private string RandomizeString(string source)
{
string target = string.Empty;
while(source.Length > 0)
{
int index = GetRandomIntegerValue(0, source.Length - 1);
target += source.Substring(index, 1);
source = source.Remove(index, 1);
}
return target;
}
#endregion
#region 임의 패스워드 구하기 - GetRandomPassword()
/// <summary>
/// 임의 패스워드 구하기
/// </summary>
/// <returns>임의 패스워드</returns>
private string GetRandomPassword()
{
string other = this.otherTextBox.Text;
if(this.requireOtherCheckBox.Checked && (other.Length < 1))
{
MessageBox.Show
(
this,
"You cannot require characters from a blank string.",
"ERROR",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
this.otherTextBox.Focus();
return this.passwordTextBox.Text;
}
StringBuilder allowedStringBuilder = new StringBuilder();
if(this.allowLowercaseCheckBox.Checked)
{
allowedStringBuilder.Append(LOWER_CASE_CHARACTER_LIST);
}
if(this.allowUppercaseCheckBox.Checked)
{
allowedStringBuilder.Append(UPPER_CASE_CHARACTER_LIST);
}
if(this.allowNumberChceckBox.Checked)
{
allowedStringBuilder.Append(NUMBER_CHARACTER_LIST);
}
if(this.allowSpecialCharacterCheckBox.Checked)
{
allowedStringBuilder.Append(SPECIAL_CHARACTER_LIST);
}
if(this.allowUnderscoreCharacterCheckBox.Checked)
{
allowedStringBuilder.Append("_");
}
if(this.allowWhitespaceCharacterCheckBox.Checked)
{
allowedStringBuilder.Append(" ");
}
if(this.allowOtherCheckBox.Checked)
{
allowedStringBuilder.Append(other);
}
string allowed = allowedStringBuilder.ToString();
int minimumLength = int.Parse(minimumLengthTextBox.Text);
int maximumLength = int.Parse(maximumLengthTextBox.Text);
int passwordLength = GetRandomIntegerValue(minimumLength, maximumLength);
string password = string.Empty;
if(this.requireLowercaseCheckBox.Checked && (password.IndexOfAny(LOWER_CASE_CHARACTER_LIST.ToCharArray()) == -1))
{
password += GetRandomCharacter(LOWER_CASE_CHARACTER_LIST);
}
if(requireUppercaseCheckBox.Checked && (password.IndexOfAny(UPPER_CASE_CHARACTER_LIST.ToCharArray()) == -1))
{
password += GetRandomCharacter(UPPER_CASE_CHARACTER_LIST);
}
if(requireNumberCheckBox.Checked && (password.IndexOfAny(NUMBER_CHARACTER_LIST.ToCharArray()) == -1))
{
password += GetRandomCharacter(NUMBER_CHARACTER_LIST);
}
if(requireSpecialCharacterCheckBox.Checked && (password.IndexOfAny(SPECIAL_CHARACTER_LIST.ToCharArray()) == -1))
{
password += GetRandomCharacter(SPECIAL_CHARACTER_LIST);
}
if(requireUnderscoreCharacterCheckBox.Checked && (password.IndexOfAny("_".ToCharArray()) == -1))
{
password += "_";
}
if(requireWhitespaceCharacterCheckBox.Checked && (password.IndexOfAny(" ".ToCharArray()) == -1))
{
password += " ";
}
if(requireOtherCheckBox.Checked && (password.IndexOfAny(other.ToCharArray()) == -1))
{
password += GetRandomCharacter(other);
}
while(password.Length < passwordLength)
{
password += allowed.Substring(GetRandomIntegerValue(0, allowed.Length - 1), 1);
}
password = RandomizeString(password);
return password;
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] ElementHost 클래스 : PropertyMap 속성을 사용해 WPF 엘리먼트 속성 매핑 설정하기 (0) | 2023.01.01 |
---|---|
[C#/WINFORM] ElementHost 클래스 : WPF 복합 컨트롤 호스트하기 (0) | 2023.01.01 |
[C#/WINFORM] ElementHost 클래스 : WPF 복합 컨트롤 사용하기 (0) | 2023.01.01 |
[C#/WINFORM/.NET6] 이미지 RTF 구하기 (0) | 2022.10.30 |
[C#/WINFORM/.NET6] 마우스 이벤트 발생시키기 (0) | 2022.10.22 |
[C#/WINFORM/.NET6] Point 구조체 : 선의 왼쪽 포인트 여부 구하기 (0) | 2022.10.19 |
[C#/WINFORM/.NET6] 별점(Star Rating) 그리기 (0) | 2022.10.14 |
[C#/WINFORM/.NET6] 비주얼 스튜디오 2022에서 단일 실행 파일 배포하기 (0) | 2022.10.10 |
[C#/WINFORM/.NET6] ISynchronizeInvoke 인터페이스 : InvokeRequired 코드 패턴 자동화하기 (0) | 2022.10.09 |
[C#/WINFORM/.NET6] MethodInvoker 대리자 : InvokeRequired 코드 패턴 자동화하기 (0) | 2022.10.09 |
댓글을 달아 주세요