본문 바로가기

알고리즘 & 자료구조/암호화 알고리즘

[암호학] 다중 치환 암호_비제네르(Vigenere) 암호

다중 치환 암호(Polyalphabetic Substitution Cipher)

  •   하나의 문자가 서로 다른 여러 문자로 매핑

 

비제네르 암호

  •   암호 간격을 문자마다 서로 다른 간격으로 이동시킨 것.
  •   동일한 문자가 각각 다른 문자로 암호화 될 수 있는 다중치환 방식

       ex) "ABCDEF" 를 암호화 하기 위해 키로 "BCD"를 사용

         1. 키가 평문보다 작다면 평문의 길이만큼 Key를 반복

           "BCDBCD"

         2. 평문의 각 문자에 매핑되는 Key 문자의 인덱스만큼 문자를 평행 이동

          첫 문자가 'A'이고, 매핑되는 Key는 'B' 이므로 'A' + 1 = 'B' 가 암호문자

          두번째 문자가 'B' 이고 매핑되는 키는 'C' 이므로 'B' + 2 = 'D' 가 암호문자가 된다.  

 

A B C D E F
B(+1) C(+2) D(+3) B(+1) C(+2) D(+3)
A+1 B+2 C+3 D+1 E+2 F+3
B D F E G I
public class VigenereCipher
    {
        public static string Encrypt(string message, string key) {
            char[] a = message.ToCharArray();
            char[] k = key.ToCharArray();
            int kIndex = -1;

            for (int i = 0; i < a.Length; i++) {
                if (char.IsWhiteSpace(a[i])) continue;

                kIndex = (kIndex >= k.Length - 1) ? 0 : kIndex + 1;
                int iKey = k[kIndex] - 'A';

                a[i] = (char)('A' + ((a[i] - 'A') + iKey) % 26);
                
            }
        
            return new string(a);
        }


        public static string Decrypt(string cipher, string key)
        {
            char[] a = cipher.ToCharArray();
            char[] k = key.ToCharArray();
            int kIndex = -1;

            for (int i = 0; i < a.Length; i++) {
                if (char.IsWhiteSpace(a[i])) continue;

                kIndex = (kIndex >= k.Length - 1) ? 0 : kIndex + 1;
                int iKey = k[kIndex] - 'A';

                a[i] = (char)('A' + (a[i] - 'A' - iKey + 26) % 26);

            }

            return new string(a);
        }
        internal static void HowToTest()
        {
            string message = "ATTACK WEST CASTLE".ToUpper();
            string key = "JULIA".ToUpper();
            string cipher = VigenereCipher.Encrypt(message, key);
            string plain = VigenereCipher.Decrypt(cipher, key);

            Console.WriteLine($"{message},{cipher},{plain}");
            Debug.Assert(message == plain);

        }
    }

- 메인메서드

        var encryptvigenere = VigenereCipher.Encrypt("HELLO", "BOB");
        var decryptVigenere = VigenereCipher.Decrypt(encryptvigenere, "BOB");

        Console.WriteLine("비제네르 암호화:" + encryptvigenere);
        Console.WriteLine("비제네르 복호화:" + decryptVigenere);

- 결과