본문으로 바로가기

[펌] RSA 암호화 기법

category .NET/C#.NET 2017. 1. 25. 09:08


웹쪽 자바스크립트 라이브러리 다운로드

http://www-cs-students.stanford.edu/~tjw/jsbn/


[펌] 위치

http://blog.naver.com/103hana/10166459171

 ----------------------------------------------------------------------------------------------------------------------------------------------------------


----내가 작성한 코드-----


----C#----

//hex -> byte[] 변경

public static byte[] StringToByteArray(string hex)

{

return Enumerable.Range(0, hex.Length)

.Where(x => x % 2 == 0)

.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))

.ToArray();

}

//복호화

static public byte[] RSADecrypt(byte[] DataToDecrypt, string RSAKeyInfo, bool DoOAEPPadding)

{

try

{

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

rsa.FromXmlString(RSAKeyInfo);

return rsa.Decrypt(DataToDecrypt, DoOAEPPadding);

}

catch (CryptographicException e)

{

Console.WriteLine(e.ToString());

return null;

}

}

//암호화

static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)

{

try

{

byte[] encryptedData;

using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())

{

rsa.ImportParameters(RSAKeyInfo);

encryptedData = rsa.Encrypt(DataToEncrypt, DoOAEPPadding);

}

return encryptedData;

}

catch (CryptographicException e)

{

Console.WriteLine(e.Message);

return null;

}

}


public string generatePublicKey()

{

JavaScriptSerializer js = new JavaScriptSerializer();

    Dictionary<string, string> d = new Dictionary<string, string>();

byte[] ubytes = StringToByteArray(securedUser); // hex -> byte[] 바꾼다 (자바스크립트 rsa암호화한 값을 hex 16진수로 반환한다)

string publicModulus = string.Empty;

string publicExponent = string.Empty;

 

// 암호화 개체 생성

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

 

// 개인키 생성

RSAParameters privateKey = RSA.Create().ExportParameters(true);

rsa.ImportParameters(privateKey);

string privateKeyText = rsa.ToXmlString(true) ; // 개인키 xml로 저장

 

// 공개키 생성

RSAParameters publicKey = new RSAParameters();

publicKey.Modulus = privateKey.Modulus;

publicKey.Exponent = privateKey.Exponent;

rsa.ImportParameters(publicKey);

 

for (int i = 0; i < privateKey.Modulus.Length; i++) // byte[] -> hex 16진수 바꿔준다 (자바스크립트에서 rsa암호화할때 hex 16진수로 암호화를 만든다)

{

publicModulus += privateKey.Modulus[i].ToString("X2");

}

for (int i = 0; i < privateKey.Exponent.Length; i++) // byte[] -> hex 바꿔준다

{

publicExponent += privateKey.Exponent[i].ToString("X2");

}

var sessionId = HttpContext.Current.Session.SessionID;

 

HttpContext.Current.Session[sessionId + "ResPrivateKey"] = privateKeyText; // 개인키 세션 저장

//Response.Write(publicModulus + "/" + publicExponent);// html 공개키 전송

//Response.End();

 

d.Add("publicModulus", publicModulus);

d.Add("publicExponent", publicExponent);

return js.Serialize(d);

}


public string auth()

{

string privatekey = HttpContext.Current.Session[sessionId + "ResPrivateKey"].ToString();

byte[] ubytes = StringToByteArray(securedVal); // hex -> byte[] 바꾼다 (자바스크립트 rsa암호화한 값을 hex 16진수로 반환한다)

byte[] decData = RSADecrypt(ubytes, privatekey, false);//복호화

}

----javascript----

먼저 , 아래 스크립트 를 include 하고 합니다.(순서중요)

<script type="text/javascript" src="share/js/jquery-1.8.3.min.js"></script>

<script type="text/javascript" src="share/js/rsa/jsbn.js"></script>

<script type="text/javascript" src="share/js/rsa/rsa.js"></script>

<script type="text/javascript" src="share/js/rsa/prng4.js"></script>

<script type="text/javascript" src="share/js/rsa/rng.js"></script>

<script type="text/javascript" src="share/js/login.js"></script>


var _this = this;

_this.submitEncryptedForm = function (username, password) {

        var _promise = $.when(this.getRSA());

        _promise.done(function (data) {

            console.log('_promise');

            var objData = JSON.parse(data.d);

            var rsa = new RSAKey();    -- 1. RSAKey 객체 생성

            rsa.setPublic(objData.publicModulus, objData.publicExponent);    -- 2. 공개키 전송

            var urlToHandler = "Service/LoginService.svc/auth";

            var parmData = {};

            parmData.securedUser = rsa.encrypt(username);    -- 3. 암호화

            parmData.securedUserPwd = rsa.encrypt(password);

            $.ajax({

                type: "POST",

                url: urlToHandler,

                cache: false,

                data: JSON.stringify(parmData),  //WCF 웹 메소드에 검색 요청 파라미터 제공

                contentType: "application/json; charset=utf-8",

                dataType: "json",                       //Json 데이터 타입으로 결과 데이터 Return

                success: function (msg) {

                    var objsuc = JSON.parse(msg.d);

                    if (objsuc.suc == "1") location.href = "index.aspx";

                    else {

                        alert("ID/비밀번호가 틀렸습니다.");

                    }

                },

                error: function (xhr, status, error) {

                    alert('정보를 수신하는데 오류가 있습니다.');

                }

            });

        });

        _promise.fail(function (jqXHR, textStatus) {

            console.log('_promise error');

            alert('정보를 수신하는데 오류가 있습니다.');

        });   

    }

 

    _this.validateEncryptedForm = function () {

       

        var username = $('input:text[name="txtid"]')[0].value;

        var password = $('input:password[name="txtpwd"]')[0].value;

        if (!username || !password) {

            alert("ID/비밀번호를 입력해주세요.");

            $('input:text[name="txtid"]')[0].focus();

            return false;

        }

 

        try {

            _this.submitEncryptedForm(username, password);

        } catch (err) {

            alert(err);

        }

        return false;

    }

 

-- RSA 공개키 요청 부분

    _this.getRSA = function () {

        var urlToHandler = "Service/LoginService.svc/generatePublicKey";

        return $.ajax({

            type: "POST",

            url: urlToHandler,

            cache: false,

            contentType: "application/json; charset=utf-8",

            dataType: "json"                       //Json 데이터 타입으로 결과 데이터 Return

        });

    }


** 실행 순서

1. validateEncryptedForm(); 실행

2. submitEncryptedForm(); 실행

3. getRSA() ; 공개키 요청 ( C#쪽 generatePublicKey() 함수 실행 )

4. submitEncryptedForm() 함수 내부에서 공개키를 가지고 암호화 후 전송 ( c#쪽 auth() 함수 실행)

'.NET > C#.NET' 카테고리의 다른 글

제네릭 코드의 default 키워드  (0) 2014.05.09
IEnumerable을 지원할 경우 Linq활용  (0) 2014.03.18
[펌] C#] GetType의 활용  (0) 2014.02.24
BackgroundWorker 사용 방법 입니다.  (0) 2014.01.23
멀티 쓰레드 구현  (0) 2014.01.23