본문 바로가기

보안 취약점/파라메터 변조

ClientSide 암호화, ServerSide 복호화 예제 (Javascript & C#)

  웹 개발을 하다보면 중요 정보를 서버쪽에 전송해야 할 일이 생깁니다. 특히 로그인 페이지의 패스워드 같은 경우에는 유출될 경우 큰 보안적 이슈를 야기합니다. 사이트에 SSL을 적용하는 등 다양한 방법이 있지만, 소개해드릴 내용은, Javascript로 암호화된 값을 서버측(C#)에서 복호화하는 방법을 소개시켜드리려고 합니다.


공개키 알고리즘이란?


공개 키 암호 방식(公開 - 暗號 方式, public-key cryptography)은 암호 방식의 한 종류로 사전에 비밀 키를 나눠가지지 않은 사용자들이 안전하게 통신할 수 있도록 한다. 공개 키 암호 방식에서는 공개 키와 비밀 키가 존재하며, 공개 키는 누구나 알 수 있지만 그에 대응하는 비밀 키는 키의 소유자만이 알 수 있어야 한다. 공개 키 암호를 구성하는 알고리즘은 대칭 키 암호 방식과 비교하여 비대칭 암호(非對稱暗號)라고 부르기도 한다. 이중 가장 대중적으로 알려진 방식이 RSA 알고리즘.


[출처] 위키피디아


1.  첨부된 압축파일을 풀어 js를 인클루드 시켜줍니다.

     - 해당 js들은 C#의 라이브러리들을 JabaScript로 컨버팅한 것들입니다.

     - 오픈소스 저작권이 적용되는 파일입니다.

JocysComJavaScriptClasses.zip

[출처] http://www.jocys.com/Common/JsClasses/Documents/


2. 클라이언트 RSA 알고리즘 적용 예제 

      - 1번의 js들을 페이지에 인클루드 시킵니다.

      - RSA 암호화하는 함수를 아래의 예제와 같이 만들어줍니다.

      - 공개키-개인키는 반드시 서버쪽에서 생성 후 관리하여야 합니다. 

      - 패스워드 정보등을 서버측으로 전달하기 이전에 암호화 하여 전달하여 주면 됩니다.

      - 유의해야 할 사항으로는, 1번의 js들을 인클루드 시 다른 js와 충돌이 발생 할 수 있으므로 별도의

        iframe을 삽입하여 사용하는 방법도 검토해보아야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        //RSA 암호화
        function RSAEncription(pPlainText) {
            try {
                //페이지 로드 시 서버쪽에서 생성한 공개키
                var pPublicKey = "<RSAKeyValue><Modulus>qcVJiqprbMKyT/xGVB82wrGE3D1uhsNLVplc+l865JZL40RydDx3qe64P2qqSdYeQRpwVELn7yM3RkpHWPWvJBm7gP2aEK2p5K2LoJ6Ht7y0AFs8ahjTqeMnOhI0EygW0bPazH+Py9m9EexiIF81t+F2rgYQHINELIQoWZNAKHk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
                var doOaepPadding = true//패딩
                var sEncryptData = "";
                var rsa = new System.Security.Cryptography.RSACryptoServiceProvider();
                rsa.FromXmlString(pPublicKey);
                var decryptedBytes = System.Text.Encoding.UTF8.GetBytes(pPlainText);
                var encryptedBytes = rsa.Encrypt(decryptedBytes, doOaepPadding);
                sEncryptData = System.Convert.ToBase64String(encryptedBytes); //암호화된 
                return sEncryptData;
            }
            catch(e){
                alert(e.message);
            }
        }
cs


3. 서버측 RSA 알고리즘 적용 예제

      - 클라이언트에서 암호화된 내용을 서버측에서 복호화 하는 예제입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  public static string RSAdecrypt(String Input, bool IsOaepPadding = true)
    {
        string Output = "";
        //Encode Encrypt Text
        byte[] encryptedBytes = System.Convert.FromBase64String(Input);
 
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
 
        //Private Key Import
        RSA.FromXmlString("개인키 xml 정보");
 
        // Decrypt Value
        byte[] decryptedBytes = RSA.Decrypt(encryptedBytes, IsOaepPadding);
 
        // Decode Decrypt Text 
        Output = System.Text.Encoding.UTF8.GetString(decryptedBytes);
 
        return Output;
    }
cs



4. 클라이언트에서 암호화하고 서버측에서 복호화하는 간단한 예만 들었으나, 실제 운영 환경에 적용하려면 아래의 사항을 추가로 고려해보아야 합니다.

    - 인클루드 하는 JS들과 현재 사용하고있는 JS들 간의 충돌은 없는지

    - 공개키 및 개인키 정보는 서버쪽에서 어떻게 관리를 할지

    - 저작권 확인

    - 암호화된 값을 서버측으로 전달할 때 Post방식일 경우에는 상관없으나 Get방식일 경우 클라이언

      트 측에서 encodeURIComponent()함수를 통하여 인코딩을 해주어야 합니다.

      (+등의 특수문자는 ASP.NET 서버측에서 받을때 공백으로 변환되기 때문)