ColdFusion의 암호화 함수. Hash, Encrypt, Decrypt

최근에 개인정보보호와 관련하여 관련법이 강화되고 의무적으로 보안관련 이슈를 해결해야 하는 과정에서 DB암호화에 관한 부분이 홈페이지 분야에서 많이 대두 되고 있는 것 같습니다.

사실 DB암호화 솔루션의 경우 MySQL, MSSQL 등에 Plugin방식 등으로 탑재되는게 일반적이라고 할 수 있지만 전 그 역시 ActiveX적 사고에서 벗어나지 못한 일부 보안솔루션 회사들의 한계가 아닌가 싶어 아쉽습니다. 일단 뭔가를 열심히 서버에 설치해야 한다는 것. 

사실 DB를 암호화하는 가장 큰 이유는 유출된 데이터가 알 수 없는 코드로 암호화되어 개인정보 등이 노출되지 않도록 하기 위함입니다. 따라서 대부분의 개인정보는 암호화해서 저장되어야 하는데 암호화를 하는 방향에서 두가지로 나뉠 수 있습니다.

하나는 단방향암호화로서 일단 암호화를 하면 다시는 복호화가 불가능?하도록 하는 암호화와 또 하나는 암호화를 하되 필요시 복호화를 해서 내용을 확인해야 하는 암호화가 바로 그것이죠.

전자의 경우는 패스워드와 같이 일단 암호화를 하면 복호화가 안되도록 하는 곳에 주로 사용할 것 이고, 후자의 경우엔 이름이나 주소 등 다시 복호화해서 화면에 출력하거나 확인을 해야 하는 경우가 그 예가 될 수 있습니다.

사실 KISA에서도 이와 관련한 암호화방법에 관련된 기술자료를 오래전에 배포한 적이 있습니다.(참조 : http://seed.kisa.or.kr/iwt/ko/guide/EgovGuideDetail.do?bbsId=BBSMSTR_000000000011&nttId=37&pageIndex=1&searchCnd=&searchWrd=

위 자료의 요지는 앞에서 설명드린 단방향 암호화기법과 양방향암호화, 그리고 주로 쓰이는 ASP, JSP에서의 구현방법에 대한 내용입니다만, 여기서는 ColdFusion에서의 기법에 대해 몇자 적어보려 합니다.

타 웹 개발 언어와 마찬가지로 ColdFusion(CFML)에서도 Hash()함수등의 암호화 함수와 여러 국제적 표준의 알고리즘을 지원합니다. 그중 몇가지를 소개하고자 합니다.

Hash()

ColdFusion에서 사용하는 해시함수입니다. 대부분의 언어와 마찬가지로 사용법은 비슷합니다. 예제를 하나 만들어 보죠.

"안녕하세요?" 라는 평문을 Hash()함수로 암호화하면 다음과 같이 할 수 있습니다. Adobe ColdFusion의 Standard버전에서는 CFMX_COMPAT, MD5, SHA, SHA-256, SHA-384, SHA-512의 알고리즘을 지원하며 Enterprise버전에서는 좀 더 강화된 알고리즘을 지원합니다.(참조 : http://help.adobe.com/en_US/ColdFusion/10.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c52.html)

<cfset hashDemo = Hash("안녕하세요?", "SHA-512", "UTF-8")>
<cfoutput>#hashDemo#</cfoutput>

위 실행 결과는

9F7384FE6552F1C7A9871C487B1760D011528BC58F556E3F27C6450C7FEB0C15C59AFDF13AB01
8E565764CB5AA35E15A9B7F48EDB745F92A33522FC57C3B6BA6

와 같은 문자열로 암호화 되어서 반환됩니다. 

위와 같이 해시함수로 암호화하면 이 암호를 푸는 인증키가 없기 때문에 해독이 불가능?합니다. (모든 알고리즘은 언젠가는 해독되게 마련이라 99%라고 할 수 있겠네요.)  이와같은 해시함수로 암호화된 데이터는 비밀번호 등 다시는 확인이 불가능한 데이터를 처리할 때 주로 사용합니다. 이 경우 사용자에게 입력받은 데이터를 해시함수로 암호화하여 저장된 데이터와 비교하여 정확한 값입력을 비교할 수 있습니다. 

Encrypt() Decrypt()

Encrypt()함수는 Decrypt()함수와 함께 보안키기반 암호화 함수입니다. 함수에 사용할 보안키를 임의로 생성한 후 해당 보안키로 문자열을 암호화 또는 복호화 합니다. 따라서 해당 보안키를 모르면 복호화가 불가능합니다. 두 함수 역시 다양한 알고리즘을 지원합니다만 각 Adobe ColdFusion에서 지원하는 알고리즘이 다르므로 기술문서를 참조해야 합니다. 보안키를 생성할 때는 GenerateSecretKey()함수를 이용해 임의로 난수 생성합니다. 역시 예제를 하나 살펴보죠.

Encrypt 함수참조 : http://help.adobe.com/en_US/ColdFusion/10.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c2f.html

Decrypt 함수참조 : http://help.adobe.com/en_US/ColdFusion/10.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c1c.html

예제 데모보기 : 암호화데모

<!--- AES 알고리즘 사용 --->
<cfset algorithm = "AES">

<!--- Hex 인크딩 사용 --->
<cfset encoding = "Hex">

<!--- 임의의 보안키생성 --->
<cfset encryptKey = "#generateSecretKey(algorithm)#">

<cfset strForEncrypt = "안녕하세요?">
<cfset encryptstr = encrypt(strForEncrypt, encryptKey, algorithm, encoding)>
<cfset decryptstr = decrypt(encryptstr, encryptKey, algorithm, encoding)>

<cfoutput>
<strong>보안키 :</strong> #encryptKey#<br />
<strong>문자열 :</strong> #strForEncrypt#<br />
<strong>암호화 :</strong> #encryptstr#<br />
<strong>복호화 :</strong> #decryptstr#<br />
</cfoutput>

Encrypt()와 Decrypt()함수는 개인정보 중 이름, 주소, 연락처, 이메일 등을 암호화하여 저장하고 필요시에 복호화해서 사용합니다. 중요한 것은 암호화시 사용한 보안키를 잘 보관해야 한다는것입니다. 이 키가 쉽게 노출된다면 복호화 역시 쉽게 될 수 있으니까요. 위에서 언급한 KISA에서 배포되는 자료에서도 해시함수나 블록암호알고리즘시 사용하는 SALT 또는 비밀키(보안키)를 안전한 곳에 잘 보관해야 하며 필요에 따라서는 외부에서 가져오길 권장합니다. DB암호화 솔루션 업체들의 개념을 보면 이 비밀키(보안키)와 같은 인증요소를 정책으로 지정하고 필요시에 인증을 거친 후 요청하도록 구성되어 있는 제품도 있었습니다.

자, ColdFusion에서도 Hash()와 Encrypt(), Decrypt()함수로 암호화 및 복호화를 할 수 있습니다. 국제적으로 공인받은 알고리즘을 사용하므로 시스템자체가 해킹되거나 취약점으로 인해 보안키가 노출되지 않도록만 한다면 간단하게 데이터를 암호화 할 수 있습니다. 하나만 더 붙히면 이와같이 평문의 문자열을 암호화할때 함수실행 전 단계에서 유출될 수 있으므로 SSL과 같은 보안서버의 구축 역시 필수겠죠?

EncryptBinary() DecryptBinary()

그렇다면 이렇게 문자열은 암호화해서 DB에 넣어두고 열심히 나름 보안을 챙겼다고 합시다. 그럼 사용자가 업로드한 파일은? 가령 개인정보가 적혀있는 이력서.doc파일이 업로드되었다고 해 봅시다. 대부분은 웹루트 하위 디렉토리에 파일이 저장되는 구조로 웹어플리케이션을 구성합니다. 이런 구조는 인증절차(로그인과 같은)을 거쳐 다운로드하도록 구성했어도 구글과 같은 검색엔진에 의해 충분히 해당 디렉토리와 파일이 그대로 노출됩니다. 업로드시 파일명을 변경한다 해도 파일자체를 숨기지는 못합니다. 

따라서 파일 업로드와 같은 경우에는 웹루트가 아닌 다른 곳에 파일을 저장하고, 다운로드시 해당 파일을 불러와 다운로드시켜주는 로직으로 구성해야 합니다. ColdFusion에서의 이와 관련된 이전의 제 글이 있으니 참조바랍니다. (http://archives.nooree.com/blog/post.cfm/coldfusion-dilemma-web-browser)

그런데 어떤 경우로 웹루트에 파일을 저장해야 한다고 가정해 봅시다. 그런 경우에는 파일 자체를 암호화 해줘야 합니다. 함부러 열어볼 수 없도록 말이죠. 이를 위해 ColdFusion에서는 EncryptBinary()와 DecryptBinary() 두 함수를 지원합니다. 사용법은 Encrypt()와 Decrypt()함수와 거의 동일 합니다. 문자열 대신 바이너리파일을 대입하는 것이죠.

EncryptBinary 함수참조 : http://help.adobe.com/en_US/ColdFusion/10.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-6e75.html

DecryptBinary 함수참조 : http://help.adobe.com/en_US/ColdFusion/10.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-6e77.html

가령 업로드된 파일이 JPG이미지 파일일 경우 EncryptBinary()로 암호화 해버리면 해당 파일을 다운로드 해가더라도 이미지파일로 인식할 수 없어 열어 볼 수 없습니다. 역시 예제하나 살펴보죠. 

<!--- AES 알고리즘 사용 --->
<cfset algorithm = "AES">

<!--- Hex 인크딩 사용 --->
<cfset encoding = "Hex">

<!--- 임의의 보안키생성 --->
<cfset encryptKey = "#generateSecretKey(algorithm)#">

<!--- 암호화할 파일 로드 --->
<cffile file="#ExpandPath('./sampleppt.pptx')#" action="readBinary" variable="sampleFile"> 

<!--- 파일암호화 --->
<cfset fileEncrypt = encryptBinary(#sampleFile#, encryptKey, algorithm)>
<!--- 암호화된 파일을 저장 --->
<cffile file="#ExpandPath('./sampleppt_enc.pptx')#" action="write" output="#fileEncrypt#"> 

<!--- 파일복호화 --->
<cfset fileDecrypt = DecryptBinary(#fileEncrypt#, encryptKey, algorithm)>
<!--- 복호화된 파일을 저장 --->
<cffile file="#ExpandPath('./sampleppt_dec.pptx')#" action="write" output="#fileDecrypt#"> 

위 코드에서 쓰인 PPT샘플외에 다양한 이미지, 텍스트파일을 직접 다운로드하여 열어 보시길 바랍니다. (마우스 오른쪽 다른 이름으로 저장하시길 바랍니다.) 

원본 이미지 : sampleimage.png
암호화된 이미지 : sampleimage_enc.png (이미지 파일이 볼 수 있나요?)
​복호화된 이미지 : sampleimage_dec.png (복호화된 원본과 같은 이미지)

원본 텍스트파일 : samplefile.txt
암호화된 텍스트파일 : samplefile_enc.txt (열리나요?)
복호화된 텍스트파일 : samplefile_dec.txt

원본 PPT파일 : sampleppt.pptx
암호화된 PPT파일 : sampleppt_enc.pptx (열리나요?)
복호화된 PPT파일 : sampleppt_dec.pptx

별거 아닌걸 디게 거창하게 이야기했습니다만 웹의 특성상 오픈된 시스템이므로 구현시 꼼꼼한 자세가 필요해 보닙니다. 문자열에 대한 암호화 뿐만 아니라 보안키에 대한 보관방법, 업로드되는 파일의 암호화 등 웹개발자는 신경쓸 것이 참 많습니다. ^^

There are no comments yet. - 아직 댓글이 없습니다.

Leave a Comment

Leave this field empty:




Powered by

© 2010-2018 NOOREE.COM