WPF & C# - 암호화 / 복호화 AES256 ( Encrypt / Decrypt )

2018. 8. 10. 10:57Programing (프로그래밍)/WPF & C# (C Sharp)

728x90
반응형


 WPF & C# - 암호화 / 복호화 AES256 ( Encrypt / Decrypt )



EncryptionAES256.zip




암호화 및 복호화가 가능한 알고리즘이다.

현재로선 패스워드를 모르면 복호화가 불가능하다.

아래 예제에서 에러발생을 없애기 위해 try / catch 로 감싸 주었다.


MainWindow.xaml



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<StackPanel VerticalAlignment="Center">
    <Label Height="40" Margin="5" Content="암호화 AES256" FontWeight="Bold" FontSize="24" HorizontalContentAlignment="Center" Background="DeepSkyBlue"></Label>
    <Grid Height="40" Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Content="Value" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" FontWeight="Bold" FontSize="14"></Label>
        <TextBox Grid.Column="1" x:Name="txtValue" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="16"/>
    </Grid>
 
    <Grid Height="40" Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Content="PassWord" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" FontWeight="Bold" FontSize="14"></Label>
        <TextBox Grid.Column="1" x:Name="txtPW" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="16"></TextBox>
    </Grid>
 
    <Button x:Name="btnEncrypt" Height="40" Content="암호화" Click="btnEncrypt_Click" Margin="5"/>
 
    <TextBox x:Name="txt01" Height="40" Margin="5" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="16" ></TextBox>
    <Button x:Name="btnDecrypt" Height="40" Content="복호화" Margin="5" Click="btnDecrypt_Click"/>
 
    <TextBox x:Name="txt02" Height="40" Margin="5" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="16"></TextBox>
</StackPanel>
cs




MainWindow.xaml.cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// 암호화 버튼 클릭
private void btnEncrypt_Click(object sender, RoutedEventArgs e)
{
    txt01.Text = EncryptString(txtValue.Text, txtPW.Text);
}
 
// 복호화 버튼 클릭
private void btnDecrypt_Click(object sender, RoutedEventArgs e)
{
    txt02.Text = DecryptString(txt01.Text, txtPW.Text);
}
 
// 암호화 AES256
private static string EncryptString(string InputText, string Password)
{
    string EncryptedData = "";
    try
    {
        // Rihndael class를 선언하고, 초기화
        RijndaelManaged RijndaelCipher = new RijndaelManaged();
 
        // 입력받은 문자열을 바이트 배열로 변환
        byte[] PlainText = System.Text.Encoding.Unicode.GetBytes(InputText);
 
        // 딕셔너리 공격을 대비해서 키를 더 풀기 어렵게 만들기 위해서 
        // Salt를 사용한다.
        byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
 
        // PasswordDeriveBytes 클래스를 사용해서 SecretKey를 얻는다.
        PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
 
        // Create a encryptor from the existing SecretKey bytes.
        // encryptor 객체를 SecretKey로부터 만든다.
        // Secret Key에는 32바이트
        // (Rijndael의 디폴트인 256bit가 바로 32바이트입니다)를 사용하고, 
        // Initialization Vector로 16바이트
        // (역시 디폴트인 128비트가 바로 16바이트입니다)를 사용한다.
        ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
 
        // 메모리스트림 객체를 선언,초기화 
        MemoryStream memoryStream = new MemoryStream();
 
        // CryptoStream객체를 암호화된 데이터를 쓰기 위한 용도로 선언
        CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
 
        // 암호화 프로세스가 진행된다.
        cryptoStream.Write(PlainText, 0, PlainText.Length);
 
        // 암호화 종료
        cryptoStream.FlushFinalBlock();
 
        // 암호화된 데이터를 바이트 배열로 담는다.
        byte[] CipherBytes = memoryStream.ToArray();
 
        // 스트림 해제
        memoryStream.Close();
        cryptoStream.Close();
 
        // 암호화된 데이터를 Base64 인코딩된 문자열로 변환한다.
        EncryptedData = Convert.ToBase64String(CipherBytes);
    }
    catch { MessageBox.Show("Faild Value"); }
    // 최종 결과를 리턴
    return EncryptedData;
}
 
// 복호화 AES256
private static string DecryptString(string InputText, string Password)
{
    string DecryptedData = "";   // 리턴값
    try
    {
        RijndaelManaged RijndaelCipher = new RijndaelManaged();
 
        byte[] EncryptedData = Convert.FromBase64String(InputText);
        byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
 
        PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
 
        // Decryptor 객체를 만든다.
        ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
 
        MemoryStream memoryStream = new MemoryStream(EncryptedData);
 
        // 데이터 읽기(복호화이므로) 용도로 cryptoStream객체를 선언, 초기화
        CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
 
        // 복호화된 데이터를 담을 바이트 배열을 선언한다.
        // 길이는 알 수 없지만, 일단 복호화되기 전의 데이터의 길이보다는
        // 길지 않을 것이기 때문에 그 길이로 선언한다.
        byte[] PlainText = new byte[EncryptedData.Length];
 
        // 복호화 시작
        int DecryptedCount = cryptoStream.Read(PlainText, 0, PlainText.Length);
 
        memoryStream.Close();
        cryptoStream.Close();
 
        // 복호화된 데이터를 문자열로 바꾼다.
        DecryptedData = Encoding.Unicode.GetString(PlainText, 0, DecryptedCount);
 
    }
    catch  { MessageBox.Show("Faild Value"); }
    // 최종 결과 리턴
    return DecryptedData;
}
cs



AES는 미국 정부에서 민감한 정보들을 암호화하는 데 사용되는 표준 암/복호화 알고리즘이다. 현재 업계 표준이고, 아직까지는 알려진 약점이 없는 가장 안전한 암/복호화 알고리즘이다. 최근에 일부 SI 프로젝트에서는 이 방식을 꼭 쓸 것을 요구하기도 한다.


출처 : http://lazydeveloper.net/1703266

728x90
반응형