상호연결성과 개방성에 의해 주도돼 온 임베디드 시스템에서 보안이 점점 더 중요해지고 있다. 이 글에서는 고성능 컴퓨팅 플랫폼의 보안에 대한 ARM 트러스트존(TrustZone) 기술, 시스템 전체를 고찰하는 접근법을 중점적으로 다루고, 어떻게 이러한 기술을 이용해 보안 시스템을 구축할 수 있는지를 설명한다.
글 | 아툴 버마(Atul Verma), 사업 전략 및 개발 매니저
멀티코어 프로세서, 텍사스 인스트루먼트
요약
스마트폰이나 태블릿, 셋톱박스 같은 컨수머 디바이스는 물론 무선 셀룰러 망이나 감시 제어 데이터 수집(SCADA) 시스템 같은 인프라 분야에 이르기까지, 보안은 도난 방지뿐 아니라 돌발 고장을 예방하는 데 있어서도 중요한 사항이다. 차량 간, 차량과 통신 인프라 간의 연결 등 갈수록 모든 것이 연결되어 가고 있는 시점에서, 불과 몇 년 전까지 만해도 존재하지 않았던 새로운 보안 사항들이 무엇보다 중요해지고 있다. 여전히 위험성이 높은 해커와 악질적인 프로그래머들은 최대한의 충격과 손해를 일으키기 위한 행위를 서슴지 않고 있다. 임베디드 시스템은 차세대 공격 벡터의 중심점이 될 것이다. 따라서 점차 증가하고 있는 이러한 공격을 막아 내는 데 있어 필수적인 것은 유연하고 비용 효율적이며 프로그래밍이 가능한 보안 솔루션이다.
서론
시스템을 구동하는 환경과 애플리케이션에 따라 중요한 보안 목적이 한 가지 이상 결정될 것이다. 예를 들어 보안 인증, 암호화, 거부 조치는 상업적 거래를 처리하는 시스템에 무엇보다 중요하지만, 원자력 발전소를 보호하는 보안 시스템에 절대적으로 중요한 것은 물리적 보호 수단이다. 수많은 보안 사항들이 여러 문헌에서 광범위하게 다루어지고 있지만, 이는 이 글의 범위를 벗어난 것이다. 이 글의 주요 초점은 상호연결성과 개방성에 의해 주도되어 온 임베디드 시스템에서 점점 더 중요해지고 있는 보안에 관심을 갖도록 하는 것이다. 또한 고성능 컴퓨팅 플랫폼의 보안에 대한 ARM 트러스트존(TrustZone) 기술, 시스템 전체를 고찰하는 접근법을 중점적으로 다루고, 어떻게 이러한 기술을 이용해 보안 시스템을 구축할 수 있는지를 설명한다. 트러스트존은 TI의 키스톤(KeyStone) 아키텍처에 의해 지원된다. 이 글은 트러스트존 프레임워크를 구현하는데 있어서 중요한 키스톤의 다양한 아키텍처 특징을 설명한다. 하드웨어 이외에 소프트웨어 역시 트러스트존의 기능적 요소들을 지원하는데 있어서 중요한 역할을 수행한다. 이 글에서는 TI가 제공하는 트러스트존의 특징과 개발자들이 구현할 수 있는 여타의 특징들을 간략하게 소개한다.
구동력
임베디드 디바이스 부문에서 몇 가지 요인들이 보안 우려를 증대시키고 있으며, 디바이스 신뢰도가 핵심적인 설계 요소가 되고 있다.
- 오픈소스 소프트웨어의 광범위한 이용: 리눅스™ 운영체제(OS)가 다양한 산업 분야에서 오픈소스의 채택을 자극함에 따라 임베디드 시스템 개발 시 오픈소스 소프트웨어의 이용이 급속히 증가하고 있다. OS와는 별도로 오픈소스 소프트웨어는 데이터베이스, 비전 라이브러리, 통신 스택과 같은 거의 모든 애플리케이션 분야에서도 이용이 가능하다. 낮은 비용과 시장 적기 출시(time-to-market)의 장점을 비롯한 풍부한 기능들은 산업계에서 오픈소스 개발을 채택하는 주요 이유이기도 하다. 이러한 이점에도, 오픈소스 소프트웨어는 해커를 포함해 소프트웨어의 약점을 악용할 방법을 찾아내려는 사람들에게 광범위하게 이용될 수 있으므로, 오픈소스 소프트웨어는 본질적으로 폐쇄적인 독점 시스템보다 취약하다.
- 디바이스의 상호연결성: 임베디드 디바이스는 점점 더 인터넷에 연결되고, 상호 연결되면서 유용한 정보망이 구축되고 있다. 그러나 이러한 부가가치에는 상당한 비용이 든다. 고립되고 분리된 디바이스는 안전할 수 있지만, 대부분의 네트워크와 연결된 디바이스에는 외부 공격으로부터 보호해 줄 수 있는 추가적인 기능이 필요하다.
- 임베디드 디바이스의 광범위한 이용: 마이크로프로세서 및 마이크로컨트롤러 같은 임베디드 부품 덕분에 사물기반 인터넷(IOT) 분야의 도래를 알리는 새로운 애플리케이션의 수가 끊임없이 증가하고 있다. 세탁기와 냉장고와 같은 가전 제품에도 첨단 진단 기능과 여타의 편리한 기능들을 제공하기 위한 스마트 프로세서가 장착되고 있다. 이러한 경향은 특히, 민감한 프라이버시 문제와 개인 자료를 다루는 애플리케이션에 이용되는 디바이스에 관한 보안 우려를 증대시키고 있다.
임베디드 시스템의 보안 시나리오
보안 시나리오는 최종 애플리케이션에 따라 다양하다. 예를 들어, 판매 시점 관리(POS) 터미널을 위해 고려해야 하는 보안 사항은 트래픽 감시 시스템과 상당히 다를 수 있다. 임베디드 시스템은 물리적 접근성으로 인해 고유한 보안 우려가 제기된다. 방화벽에 의해 충분히 보호되는 인터넷 서버는 랩 어택(lab attacks)에 대한 우려가 거의 없지만, 유저 프레미스(user premises)에 배치되는 소형 셀룰러 기지국에는 실제로 위협이 된다. 더욱이 이러한 디바이스들은 지적재산(IP) 가치로 인해 정교해진 공격의 매력적인 표적이 되고 있다. 아래 목록에는 명확하게 다루어져 있지 않더라도, 다음의 항목들에서는 임베디드 제품 제조업체들에게 골칫거리가 될 수 있는 일반적인 보안 우려사항을 중점적으로 고찰한다.
1. 비인가 소프트웨어 실행
비인가 소프트웨어가 실행되면 경쟁자들이 하드웨어 설계에 아무런 비용도 들이지 않고 저렴한 가격의 위조품들을 시장에 출시할 수 있게 된다. 이는 휴대전화 제조업체와 장기 서비스 계약에 대한 소비자의 의무가 다할 때까지 모바일 디바이스의 구매 가격에 보조금을 지급하는 통신사에게 중대한 문제다. 비인가 소프트웨어가 실행되면 보조금이 지원된 휴대전화가 다른 네트워크 상에서 이용되거나 다른 국가에서 이용될 수 있어 원래 통신사는 합법적인 수익을 얻을 수 없게 된다. 해커가 임베디드 디바이스로 비인가 소프트웨어를 실행한다는 것은 특히 군대나 항공우주 분야 애플리케이션의 국가 기밀이나 장비 정보가 유출될 수 있다는 점에서 더욱 심각하다.
2. 역설계(Reverse engineering)
인터넷에서 무료로 쉽게 이용할 수 있는 몇몇 툴 및 기술이 유용하고 가치있는 정보들을 빼내기 위해 임베디드 소프트웨어를 역설계하는 데 이용될 수 있다. 디셈블러(disassemble, 파일 시스템 추출용 툴)가 주요 사례이다. 이러한 첨단 유틸리티들은 중요한 소프트웨어 요소들이 어떻게 구현되는지를 분석하는 데에도 이용될 수 있다. 역설계로 인해 시스템은 공격에 취약해질 뿐 아니라 벤더의 IP도 노출되어 도용당할 수 있다.
3. 의도하지 않은 악성 코드 실행
이것은 물론 임베디드 시스템의 상호연결성과 관련이 있으며, 시스템의 유연성과 업그레이드 용이성에도 중요하다. 악성 코드나 트로이 목마(trojan)는 손상된 서버나 중간자 공격(MITM) 또는 불만을 가진 내부 직원의 공격으로 인해 임베디드 디바이스에 설치될 수 있다. 이러한 코드는 파괴적인 행동을 수행하거나 합법적인 소프트웨어를 변조하거나 또는 유용한 정보를 도용할 수 있다.
4. 거래 안정성
접근 코드, PIN, 은행 계좌번호, 기타 민감한 정보는 인터넷 상의 안전한 거래를 위해 필수적이다. 이러한 것들이 충분히 보호되지 못한다면, 악성 소프트웨어 코드가 이러한 정보들을 도용하고, 인증되지 않은 부과금이 증가할 수 있다.
임베디드 디바이스에 필요한 것은 이러한 다수의 보안 문제들을 시스템 차원에서 처리하는 종합적인 솔루션이다. 디바이스 판매업자들은 제조업체가 보안키를 교환할 수 있는 안전하고 확장이 가능한 프로세서를 공급해야 한다. 또한 이러한 키들을 자신들의 임베디드 디바이스에 프로그래밍할 수 있어야 한다. 이 외에도 디바이스 내부의 요소들과 시스템 소프트웨어는 보안 속성을 인식하고 접근을 제어하는 프레임워크를 제공해야 한다. ARM의 트러스트존은 그러한 프레임워크 가운데 하나이다. 이것은 실리콘과 소프트웨어로 구성되어 있어 안전한 솔루션을 구축하는 강력한 토대를 제공한다.
트러스트존 소개
임베디드 환경에서의 보안에 대한 전통적인 접근법은 접근과 실행 환경을 신중하게 제어하는 별도의 보안 프로세스를 필요로 한다. 이러한 접근법은 상당히 안전하지만 많은 단점들도 있다. 그 중에서도 특히 주목할 만한 것은 높은 시스템 비용과 프로그래밍이 가능하지 않다는 것이다. 이러한 단점들을 완화시켜주는 트러스트존 기술이란 코어텍스™-A15 프로세서를 포함해 ARM에 의해 구현되는 보안 확장을 의미한다. 트러스트존은 실행 환경에서 시작해 시스템의 버스와 IP 블록 전체로 보안이 확장되는 시스템 전체를 고찰하는 접근법이다. 하드웨어를 기반으로 하기 때문에 트러스트존은 보안 소프트웨어의 상위층을 구축할 수 있는 강력한 토대를 제공한다. 안전한 실행 환경(Trusted Execu-
tion Environment, TEE)은 글로벌 플랫폼에 의해 구현되는 것으로, 이에 관한 자세한 사항은 다음 항목에서 다룬다.
트러스트존은 하드웨어 기반 보안에 핵심적인 다음의 기본적인 요소들을 제공한다.
- 별도의 보안 환경: 트러스트존은 프로세서 코어를 두 개의 가상 코어로 분할한다. 하나는 노멀 월드(normal world)에서 실행되고, 다른 하나는 시큐어 월드(secure world)에서 작업을 수행한다(그림 1). 이러한 메커니즘은 본질적으로 사용자 모드와 커널(Kernal) 모드의 전통적인 경계 이외에 또 다른 수준의 실행 특권(execution privilege)도 생성한다. 두 월드 간의 변환은 모니터 모드 소프트웨어를 통해 신중하게 제어된다. 또한 각각의 가상 프로세서는 명백하게 분리되어 있는 노멀 페이지 테이블과 시큐어 페이지 테이블 변환을 유지할 수 있도록 자신의 가상 메모리 관리 유닛(Memory Management Unit, MMU)에 접근한다. 캐시 메모리에는 추가적인 태그 비트들이 있어 시큐어 월드 코어나 노멀 월드 코어에 의해 캐시된 콘텐츠를 구분해준다. 이런 식으로 노멀 월드 마스터에서 캐시된 안전한 콘텐츠에 접근하는 것을 거부할 수 있다.
- 보안 인식 버스와 주변장치: 내부 버스에는 보안 접근과 비보안 접근을 쉽게 구분할 수 있도록 보안 인식이 구축돼 있다. 따라서 시스템 내에서 상이한 버스 마스터에 대한 조건적 접근을 승인하거나 승인하지 않을 수 있다. 이와 유사한 방법으로, 상이한 주변장치들을 안전하게 보호할 수 있다. 예를 들어, 안전한 마스터만 특정 주변장치에 접근할 것을 허용할 수 있다. 버스와 주변장치의 보안 특성을 이렇게 결합시키면, 합법적으로 안전한 소프트웨어에만 접근을 허용하고, 악성 코드가 키 입력 트래핑과 민감한 정보를 도용하지 못하도록 해 키보드를 안전하게 보호할 수 있다.
- 시큐어 인터럽트: 정교한 보안 솔루션의 설계를 돕기 위해 트러스트존은 안전한 주변장치와의 인터페이스를 위해 시큐어 인터럽트를 제공한다. 이러한 인터럽트들은 또한 서비스 거부 공격으로부터 시큐어 월드 소프트웨어를 보호하기 위해 보다 높은 우선순위로 배정될 수 있다.
- 보안 인식 디버그: 안전한 소프트웨어를 디버그 할 수 있는 능력도 중요하지만, JTAG 포트를 통해 디바이스에 접근할 수 있는 사람이 보안 코드에 접근할 수 없도록 하는 것 또한 중요하다. 그래서 트러스트존 아키텍처는 별도의 신호를 제공해 디바이스가 물리적으로 신뢰할 수 있는 위치, 신뢰할 수 있는 소프트웨어가 개발되고 있는 위치에 있고, 생산 디바이스에서 비활성화되어 있을 때, 시큐어 월드를 디버깅할 수 있는 것과 같이 안전한 노멀 월드 소프트웨어를 디버깅할 수 있도록 제어한다.
트러스트존은 하드웨어 기반 보안에 기본적인 요소들을 제공하지만, 이러한 기능들을 완전히 활용하고 강력한 보안 솔루션을 구축할 수 있으려면 상위의 소프트웨어 레이어가 필요하다.
안전한 솔루션 구축
하드웨어 인프라가 강력한 보안 토대를 쌓는데 핵심적인 요소인 것과 마찬가지로 소프트웨어 아키텍처 역시 안전한 솔루션을 만드는 데 있어 무엇보다 중요하다. 가능한 소프트웨어 아키텍처에는 몇 가지가 있지만, 구체적인 보안 설계와 복잡성은 대부분 애플리케이션의 이용 사례와 보호해야 하는 자산의 가치에 따라 결정된다. 전체적인 소프트웨어 아키텍처와 상관없이 안전한 솔루션을 구현하는 데에는 소프트웨어의 세 가지 핵심적인 요소가 필요하다. 즉, 디바이스를 시작하기 위한 안전한 부스트, 안전한 노멀 월드를 관리하는 플랫폼 소프트웨어, 사용자에게 서비스를 제공하는 안전한 애플리케이션이 필요하다.
안전한 부스트
안전한 솔루션의 출발점은 디바이스가 처음으로 부팅될 때이다. 그 이유는 훼손된 환경에서 작동되면 다른 모든 런타임 보안 대책들이 잠재적으로 우회될 가능성이 있기 때문이다. 보안은 가능한 부트 프로세스 초기에 시작되어야 하므로, 온칩 ROM 코드가 안전한 부트 프로세스에서 중요한 역할을 수행한다. 이는 제조업체의 개인 키로 서명된 신뢰할 수 있는 소프트웨어 이미지를 불러온다. 제조업체의 개인 키의 공용 카운터파트(public counter-part)는 제조를 하는 동안 단 한 번 디바이스에 프로그래밍된다. 그 뒤에 소프트웨어의 신뢰할 수 있는 OEM 이미지가 보조 부트 로더(boot loader)를 부팅하고 다음으로 높은 수준의 운영체제가 부팅된다. 이러한 방식은 완벽한 트러스트 체인을 설정할 수 있게 해준다. 즉, 첫 번째 레벨의 부품에 또 다른 임베디드 공용 키가 있어 로드 등을 수행하는 다음 레벨의 부품으로 인가된다. 그러한 안전한 트러스트 체인은 안전한 애플리케이션을 로딩하는 데까지 확장될 수 있다. 그림 2는 전형적인 안전한 부트 흐름을 설명한 것이다.
플랫폼 소프트웨어
트러스트존은 노멀 월드와 시큐어 월드를 분리할 수 있는 하드웨어 기능을 제공하므로, 이러한 기능을 활용하는 소프트웨어 아키텍처는 이와 유사한 파티셔닝(partitioning)을 수행할 것이다. 이러한 모델에서는 시큐어 월드가 안전한 주변장치와의 인터페이싱을 포함해 모든 보안 관련 기능을 수행한다. 노멀 월드는 여타의 모든 작업을 처리한다. 시큐어 월드는 또한 모든 안전한 애플리케이션을 호스트하고, 모니터 코드를 통해 신중하게 중개된 서비스를 노멀 월드에 상주하는 클라이언트에 제공할 수 있다. 한 가지 핵심적인 요소는 시큐어 월드가 종합적인 검사를 마친 코드만을 실행할 수 있도록 제한하는 것이다. 예를 들어, 인터넷에서 애플리케이션으로 다운로드받은 임의의 코드를 시큐어 월드 내부에서 실행하는 것이 불가능해진다. 이러한 방식을 통해 멀웨어나 트로이 목마로 인한 손상이 노멀 월드로 제한되므로 디바이스에 대한 공격 범위가 제한된다.
의미 있는 보안을 제공하려면 시큐어 월드가 복잡한 소프트웨어를 실행해서는 안 된다. 일부 경우에는 여분의 소프트웨어가 추가적인 취약점을 감추어 실제로 보안 목표를 저해한다. 보안 애플리케이션 소프트웨어의 선정과 이의 구현은 사용자 애플리케이션과 사용 시나리오에 좌우될 것이다. 구현은 완전히 선점 가능하고 정교한 OS에서부터 노멀 월드에 주문형(on-demand) 서비스를 제공하는 수동 라이브러리들에 이를 수 있다. 트러스트존 아키텍처는 선점 가능하고 안전한 OS를 구축할 수 있는 안전한 타이머와 보안 인식 인터럽트 컨트롤러를 제공한다.
애플리케이션
안전한 애플리케이션을 포팅(porting)하는 데 어려움을 깨달은 ARM은 트러스트존 API(TrustZone API, TZAPI)라고 하는 표준화된 애플리케이션 프로그래밍 인터페이스(Appli-cation Programming Interface, API)를 공개했다. 이 API는 기본적인 트러스트존 구현에 투명한 상위 레이어 애플리케이션을 구축한다. 이러한 작업을 수행함으로써 글로벌 플랫폼은 두 개의 부분으로 분할되는 안전한 실행 환경(Trusted Execution Environment, TEE) API(그림 3)를 정의했다.
- TEE 클라이언트 API는 노멀 월드에서 실행되며, 시큐어 월드와 통신을 하고, 시큐어 월드로부터 서비스를 활용할 수 있도록 애플리케이션을 위한 휴대형 방식을 제공한다.
- TEE 내부 API는 시큐어 월드에 상주하며, 안전한 OS에 의해 제공되는 기능들에 접근할 수 있도록 안전한 태스크릿(taskelets)과 애플리케이션을 위해 표준화된 방식을 제공한다.
그림 3에 제시되어 있는 것처럼 보안 환경은 모든 민감한 정보를 저장하며(이는 하드웨어가 버스 접근 시 안전한 비트가 켜지는 마스터에만 접근을 허용할 것임을 의미한다), 신뢰할 수 있는 애플리케이션을 위한 실행 환경을 제공한다. 신뢰할 수 있는 애플리케이션은 TEE 내부 API를 통해 보안 리소스에 접근한다.
키스톤 Ⅱ 아키텍처
키스톤 Ⅱ란 통합 ARM 코어텍스-A15 클러스터를 특징으로 하는 텍사스 인스트루먼트의 고성능 디바이스용 시스템온칩(SoC) 아키텍처를 말한다. 그림 4는 이러한 키스톤 Ⅱ 제품군 디바이스 가운데 하나이다.
ARM 라이선스는 트러스트존의 일부인 보안 확장을 모두 구현하지 않도록 선택할 수 있다. TI의 SoC 키스톤 Ⅱ 제품군은 트러스트존에 의해 지정되는 것들 이외에 다수의 보안 특성을 구현한다. 이러한 기능들 중 일부는 다음과 같다.
- 코어팩: 키스톤 Ⅱ 아키텍처 내부의 ARM 코어텍스-A15 코어들은 트러스트존 프레임워크의 일환인 ARM에 의해 지정되는 보안 확장을 구현한다. 또한 TI의 C66x DSP는 상이한 메모리 보호 영역을 활성화하는 보안 확장을 구현한다.
- 보안 부트: 키스톤 Ⅱ 내부의 ROM 코드는 외부 매체에 저장된 암호화되고 서명된 코드 이미지로부터 디바이스를 부팅할 수 있는 단계적 부트 프로세스를 지원한다.
- 보안 인식 상호연결: 테라넷(Teranet)이라고 하는 고속 내부 버스는 보안 속성을 지니고 있으므로 안전한 마스터와 안전하지 않은 마스터를 구분할 수 있다. 이를 메모리 보호 유닛과 결합시키면 일부 주변장치에 보안 접근을 선별적으로 허용하는 데 이용할 수 있다.
- 키 저장 공간: 키스톤 Ⅱ 디바이스는 멀티 프로그래밍이 가능한 EFUSE 영역을 제공해 다양한 커스터머 키(customer keys) 및 해시(hash)를 안전하게 저장할 수 있다. OTP(one-time programmable) 메모리 또한 사용자가 다른 부수적인 정보를 프로그래밍하는 데 이용할 수 있다. 이 외에 TI는 서드파티 및 하청업체가 생산을 하는 경우에도 제조업체가 자신들의 키를 안전한 방법으로 프로그래밍할 수 있도록 제조 흐름을 공개하고 있다.
- 디버그: 키스톤 Ⅱ 디바이스는 JTAG 인터페이스를 완전히 비활성화시키거나 제한된 접근을 제공해 안전한 디버깅을 활성화하거나 비활성화시킬 수 있다.
- 안전한 인터럽트: 키스톤 Ⅱ 디바이스는 인터럽트를 안전 또는 보통으로 분류해 첨단 기능을 갖춘 시큐어 월드 소프트웨어에 권한을 부여할 수 있다.
- 암호화된 외부 접근: 성능 상의 불이익을 초래하지 않고 모든 외부 메모리 인터페이스가 다양한 종류의 랩 어택(lab attack)을 예방하는 데 유용한 암호화된 데이터 버스를 지원한다.
- 보안 액셀러레이터: 키스톤 Ⅱ 디바이스에는 온칩 보안 액셀러레이터가 있어서 AES, DES, 3DES, SHA1, SHA2, MD5와 트루 RNG(True Random Number Generation)을 포함해 다양한 암호화 방식을 지원한다. 보안 소프트웨어 지원 이외에도, 이러한 액셀러레이터들은 부트 코드에 의해 안전한 부트 프로세스를 지원하고, 소프트웨어 이미지를 효율적으로 해독하는 데 이용할 수 있다.
보안 솔루션에 대한 사용자 요구는 애플리케이션에 따라 달라지지만, 키스톤 Ⅱ 디바이스는 강력한 보안 솔루션을 구축하는 데 필요한 하드웨어 요소들을 제공한다는 것을 쉽게 알 수 있다.
다수의 사용자에게는 안전한 부트와 공개 제조 흐름(open manufacturing flow)으로도 충분할 것이다. 충분히 안전한 커널을 구현하는 경우, 사용자는 오픈 버추얼라이제이션(Open Vir-
tualization)이라고 하는 무료 오픈소스 구현을 활용하거나 풍부한 지식을 가진 파트너의 강력한 네트워크에 접속해 첨단 보안 커널 기능을 구축할 수 있다.
결론
인터넷 및 전자상거래가 다양한 유형의 공격 벡터와 보안 문제에 집중하는 것과 마찬가지로 임베디드 시스템도 새로운 보안 시나리오에 중점을 둘 것이다. 이는 디바이스가 나날이 스마트해지고 상호작용을 하기 때문이다. 커넥티비티와 더불어 증대된 프로세싱 파워로 인해 이러한 임베디드 시스템은 매력적인 공격 대상이 된다. ARM의 트러스트존 아키텍처는 전체론적인 방식(holistic manner)으로 임베디드 시스템의 보안 문제를 다루는 훌륭한 비용 효율적인 솔루션이다. TI 디바이스의 키스톤 Ⅱ 제품군은 다양한 애플리케이션에 고성능을 제공할 뿐만 아니라 많은 보안 확장과 보안 기능을 제공해 안전한 솔루션을 구축하고 배치할 수 있다. ES
<저작권자(c)스마트앤컴퍼니. 무단전재-재배포금지>