주요 내용
- 스캔은 JAR 파일에 무엇이 들어 있는지 알려줄 뿐, 프로젝트에서 공개한 소스 코드와 일치하는지 여부는 알려주지 않습니다.
- 유효한 좌표 하에서 조작된 빌드는 서명이나 권고 데이터베이스로는 메울 수 없는 빈틈입니다.
- Maven은 성숙하고 재현 가능한 빌드 도구를 갖추고 있어, Java가 독립적인 재빌드 검증을 수행하기에 매우 적합합니다.
- SecureChain은 빌드 프로세스가 이미 연결되어 있는 Nexus 또는 Artifactory 프록시의 상류에 위치합니다.
Sonatype Repository Firewall(구 Nexus Firewall)은 빌드에 도달하기 전에 수많은 위협을 차단합니다. 프록시에서 적용하는 정책에 따라, 알려진 취약점, 정책 위반 사항, 그리고 인텔리전스 및 머신러닝 시스템이 악성 또는 의심스러운 것으로 식별한 구성 요소를 차단할 수 있습니다. 하지만 이러한 조치만으로는 방금 검사한 JAR 파일이 실제로 프로젝트에서 공개한 소스 코드를 기반으로 빌드된 것인지 여부를 확인할 수 없습니다. 이러한 한계 때문에 보안 팀은 유효한 좌표 하에 변조된 아티팩트를 발견하게 되면 Sonatype Nexus Firewall의 대안을 찾기 시작하는데, 이는 스캔 기능만으로는 해결할 수 없는 문제입니다.
이 가이드에서는 바이너리 스캐닝으로 검증할 수 있는 사항과 검증할 수 없는 사항, Sonatype Firewall과 JFrog Xray가 이 문제와 관련해 어떤 위치에 있는지, 그리고 SecureChain이 기존 Nexus 또는 Artifactory 설정을 건드리지 않고 소스 코드부터 Java 패키지를 재구축하는 방법을 단계별로 설명합니다.
바이너리 스캐닝이 답할 수 있는 것과 답할 수 없는 것
대부분의 평가에서는 세 가지 별개의 질문이 하나의 질문으로 취급되는데, 이를 분리해 보면 나머지 비교 과정은 간단해집니다.
| 질문 | 답변자: | Maven의 현재 상태 |
|---|---|---|
| 이 유물은 손상 없이 도착했나요? | 체크섬 | 네, Maven은 기본적으로 이 항목들을 확인합니다. |
| 이 유물을 누가 출판했나요? | PGP 서명 | 게시 시 필수 사항이며, 일반적인 해결 과정 중에는 검증되지 않음 |
| 이 유물은 그 출처와 일치합니까? | 재구축 비교 | 누군가가 재구축을 실행하는 경우에만 |
Maven Central은 PGP 서명이 없는 릴리스를 허용하지 않습니다. 하지만 Maven은 일반적인 의존성 해결 과정에서 이러한 서명을 검증하지는 않습니다. Maven은 전송 무결성을 확인하기 위해 체크섬을 검사하며, 체크섬 불일치가 실제로 빌드 실패로 이어지는지는 리포지토리의 checksumPolicy 설정이며, 기본값은 warn ~보다는 fail.
올바르게 서명된 악성 아티팩트와 올바르게 서명된 정상적인 아티팩트는 기본 빌드와 똑같이 보입니다. 서명은 단지 올바른 키를 가진 사람이 이를 생성했음을 증명할 뿐, 해당 키가 사용자가 예상한 게시자의 것임을 증명하지는 않기 때문입니다.
우리는 잭슨 닮은꼴 사건을 분석한 글에서 이 취약점의 작동 원리를 더 심도 있게 다뤘으며, 여기에는 공격자가 단순히 자신의 키를 제어하는 것만으로도 Maven의 서명 요구 사항을 어떻게 충족시킬 수 있는지도 포함되어 있습니다.
Gradle을 사용하면 이 부분을 더 직접적으로 제어할 수 있습니다.
./gradlew --write-verification-metadata sha256,pgp help
이 명령어는 검증 메타데이터를 생성하며, 이를 검토한 후 신뢰할 수 있는 기준선으로 확정하면, 이후 빌드 과정에서 이 기준선과 일치하지 않는 항목이 있을 경우 빌드가 실패하게 됩니다. 검토 단계가 중요합니다. Gradle은 해당 시점에 리포지토리에서 제공하는 내용을 바탕으로 낙관적으로 부트스트랩을 수행하기 때문에, 생성된 파일은 해당 내용이 과거에 신뢰할 수 있었음을 입증하기보다는 단순히 현재 보유하고 있는 내용을 기록할 뿐입니다. 이러한 방식으로 사용될 때, 이는 강력한 기본 제어 수단이 됩니다.
서명 검증과 빌드 검증은 서로 다른 검증 절차입니다. 해킹당한 게시자 계정은 해당 계정의 소스 저장소에 존재하지 않는 코드가 포함된, 올바르게 서명된 JAR 파일을 생성합니다. 서명을 검증하면 해당 아티팩트가 해당 계정에서 생성된 것임을 확인할 수 있을 뿐입니다. 이는 해당 계정의 빌드가 주장하는 소스 코드와 일치하는지 여부에 대해서는 아무것도 알려주지 않습니다.
변조된 유물 클래스
게시 권한을 가진 공격자는 프로젝트를 빌드하고, 컴파일된 출력물에 변경 사항을 삽입하거나 수정된 작업 트리에서 빌드한 후 정상적으로 게시할 수 있습니다. 체크섬은 수신된 파일이 제공되는 파일과 일치하는지 확인하는 데 그치기 때문에 일관성을 유지합니다. 공격자가 해당 계정에 연결된 서명 키를 제어하고 있다면 서명도 유효한 상태로 유지될 수 있습니다. 게시된 JAR 파일에는 일치하는 커밋이 필요하지 않기 때문에 GitHub의 소스 저장소는 변경되지 않은 상태로 남아 있습니다.
해당 JAR에 대한 취약점 또는 시그니처 기반 스캔 결과는 아무 문제가 없는 것으로 나올 가능성이 높습니다. 아직 아무도 해당 패키지가 침해되었다고 식별하지 않았기 때문에 관련 권고 사항이 존재하지 않기 때문입니다. 행동 분석은 실질적인 두 번째 방어 단계로, 자체적으로 의심스러운 코드를 식별할 수 있지만, 분석 범위는 생태계에 따라 크게 다릅니다. JFrog은 npm과 PyPI에 대해 지속적으로 실행되는 자동화된 악성 패키지 스캐너를 문서화하고 있는 반면, Maven의 경우 잘 알려진 악성 패키지에 대해서만 분석 범위를 명시하고 있습니다. 어느 쪽이든, 두 접근 방식 모두 게시된 JAR 파일이 해당 프로젝트의 소스 코드와 일치하는지 여부를 확인하지는 못합니다.
그것은 ~와는 다른 공격입니다. 2025년 12월 메이븐 센트럴을 휩쓴 잭슨 닮은꼴, 이는 네임스페이스 사칭을 사용했으며, 이는 groupId 실제 라이브러리에서 접두사 하나만 다를 뿐입니다. 네임스페이스 제어 기능이 구성되어 있다면, 좌표 자체가 잘못되었기 때문에 정책으로 이러한 문제를 감지할 수 있습니다. 그러나 네임스페이스 정책은 좌표나 유효한 서명만으로는 출처 불일치를 파악할 수 없기 때문에, 그 외에는 유효한 좌표를 사용한 변조 행위는 식별할 수 없습니다.
| 공격 | 좌표 | 스캔을 통해 확인할 수 있는 사항 |
|---|---|---|
| 네임스페이스 사칭 | 아니요, 닮은꼴 그룹입니다 | 네, 네임스페이스 정책이 적용되는 곳에서는 |
| 알려진 취약한 종속성 | 맞습니다 | 네, 자문 매칭을 통해 |
| 유효한 좌표 하에서 변조된 빌드 | 맞습니다 | 가끔 표시되기도 하지만, 출처 불일치로 표시된 적은 한 번도 없다 |
이 글은 유효한 좌표 하에서 조작된 빌드에 대해 다루고 있습니다. 이는 자바 개발 환경이 우려해야 할 유일한 공격 방식은 아니지만, 일반적인 바이너리 스캔만으로는 해결할 수 없는 문제이기 때문에, 기존 도구에 대한 기능 요청이 아닌 별도의 대응 방안이 필요합니다.
Sonatype Repository Firewall과 JFrog Xray가 실제로 확인하는 사항
Sonatype 리포지토리 방화벽은 구성 요소가 리포지토리에 유입되는 시점에서 이를 검사합니다. 이 제품의 ‘릴리스 무결성(Release Integrity)’ 기능은 새로운 릴리스에 대해 머신 러닝을 적용하여 비정상적인 릴리스 행동을 감지하고, 의심스러운 항목을 Sonatype 연구팀으로 전달합니다. 이때 원래의 리포지토리 방화벽은 해당 검토를 통해 문제가 없음이 확인될 때까지 감지된 구성 요소를 격리 상태로 유지합니다. 이는 실질적이고 유용한 통제 수단이며, 아티팩트가 소스와 일치하는지 확인하는 작업과는 별개의 운영 방식입니다.
Sonatype는 이 서비스를 두 가지 등급으로 판매합니다. 전체 리포지토리 방화벽(Repository Firewall)은 리포지토리 관리자와 통합되어 Nexus Repository와 지원되는 JFrog Artifactory 배포 환경을 모두 포괄하며, 다양한 패키지 형식에 대한 격리 및 네임스페이스 혼동 방지 기능을 포함합니다. Firewall Pro는 npm, Maven, PyPI 및 NuGet을 지원하는 보다 간소화된 SaaS 프록시 서비스로, 구성 요소를 격리 상태에 두지 않고 즉시 허용하거나 차단합니다. 두 등급의 공식 자료 모두 재빌드나 소스 비교 단계에 대해 설명하고 있지 않은데, 바로 이 점이 여기서 중요한 차이점입니다.
JFrog Xray는 아티팩트를 색인화하고 이를 취약점 및 악성 패키지 인텔리전스와 연계하며, 악성 패키지 시스템은 자동 스캔과 연구원의 검증을 결합하여 악성도를 점수로 산출합니다. 이와는 별도로, JFrog의 Evidence Service는 빌드가 어떻게 생성되었는지를 설명하는 서명된 증명서를 첨부할 수 있으며, 이는 진정한 의미의 공급망 출처 추적 기능입니다. 하지만 이는 여전히 독립적인 재빌드를 통한 검증이라기보다는 서명된 주장에 대한 신뢰에 불과합니다. 누군가는 증명서에 서명해야 하며, 증명서의 신뢰도는 이를 작성한 사람의 신뢰도에 달려 있습니다.
SecureChain for Java는 이 문제를 정반대의 접근 방식으로 해결합니다. 게시자의 바이너리를 스캔하는 대신 소스 코드를 검토한 후, 보안이 강화되고 격리된 환경에서 해당 소스 코드를 기반으로 자체 아티팩트를 컴파일하며, SLSA 레벨 3 출처 정보를 함께 제공합니다. 스캔해야 할 업스트림 바이너리가 존재하지 않습니다. Sonatype이나 JFrog가 검사했을 바이너리를 여러분의 빌드 과정이 전혀 건드리지 않기 때문입니다. 이것이 바로 현재 Maven 리포지토리 보안의 실질적인 핵심입니다. 대시보드에 어떤 벤더의 로고가 표시되는지가 아니라, 각 계층이 실제로 어떤 질문에 답하고 있는지가 중요합니다.
자바가 소스 코드부터 재구축하기에 적합한 이유
컴파일된 아티팩트는 이런 종류의 검증에 적합하지 않은 대상처럼 보입니다. 어쨌든 자바는 Maven 생태계 내에서 진정한 재현 가능한 빌드 구축을 위한 노력을 통해, 이를 처리 가능하게 만드는 인프라를 수년에 걸쳐 구축해 왔습니다.
설정하기 project.build.outputTimestamp 이 속성은 호환되는 플러그인이 생성된 아카이브에 고정된 타임스탬프를 기록할 수 있도록 하여, JAR에서 비결정성의 가장 큰 원인 중 하나를 제거합니다.
<properties>
<project.build.outputTimestamp>2026-01-15T00:00:00Z</project.build.outputTimestamp>
</properties>
이러한 설정이 완료되고 빌드 환경이 충분히 통제된다면, 동일한 소스 코드를 빌드해도 바이트 단위로 동일한 JAR 파일을 생성할 수 있습니다. Maven 4.0.0-beta-5부터는 별도의 속성 설정 없이도 재현 가능한 빌드 모드가 기본적으로 활성화되어 있지만, Maven 4는 아직 정식 출시되지 않았고 3.9.x 버전이 여전히 유지 관리되는 릴리스 라인이므로, Maven 3.x로 빌드하는 팀은 해당 속성을 명시적으로 설정해야 합니다.
mvn artifact:check-buildplan
mvn artifact:compare
첫 번째 명령어는 재현 가능한 출력이 문제없이 작동하기 위해 어떤 플러그인을 업그레이드해야 하는지 알려줍니다. 두 번째 명령어인 maven-artifact-plugin의 compare 목표는 바로 이 주장을 검증하며, 로컬 빌드를 참조 빌드(일반적으로 Maven Central에 게시된 빌드)와 비교합니다. 아파치는 동일한 환경에서의 비교만으로는 타사 환경에서의 재현성을 입증할 수 없다고 신중하게 지적합니다. 두 빌드 모두 동일한 환경 누출을 물려받을 수 있기 때문입니다. 진정한 검증은 다른 곳에서 다시 빌드하는 것을 의미합니다.
Reproducible Central은 Maven Central의 어떤 릴리스에 대해 독립적인 재빌드 시도가 있었는지 추적하며, 그 범위는 거의 전부를 아우르는 수준이라기보다는 실제로는 일부에 불과합니다. 2024년에 발표된 한 학술 연구에 따르면, Reproducible Central은 531개 프로젝트에 걸친 2,547건의 릴리스에 대한 재빌드 시도를 보고한 반면, 2023년 5월 스냅샷 기준 Maven Central에는 1,000만 건 이상의 릴리스와 479,000개의 고유 아티팩트 ID가 존재했습니다. 이러한 수치는 현재 레지스트리의 현황이 아닌 당시 스냅샷을 반영한 것이며, 당시 독립적으로 검증된 커버리지가 얼마나 부분적이었는지를 보여줍니다.
Go와 Rust는 의존성이 일반적으로 소스 형태로 배포되고 생태계 무결성 메커니즘에 의해 보호되기 때문에 바이너리 신뢰 문제를 어느 정도 완화합니다. 이는 공개된 패키지가 특정 업스트림 소스 리비전에 부합함을 증명하는 것과는 다릅니다. 자바의 Maven 생태계는 재현 가능한 바이너리 출력에 특히 상당한 투자를 해왔으며, 이는 컴파일된 확장 기능을 포함하는 파이썬 휠(wheel)이나 npm의 게시자가 빌드한 타르볼(tarball)이 현재 일반적으로 도달한 수준보다 한 발 앞서 있습니다.
'소스 코드로부터 재빌드하기'가 실제로 업스트림에 요구하는 사항
재빌드 비교를 수행하면 빌드 결과가 소스 코드와 일치하는지 여부에 대한 검증 가능한 증거를 확보할 수 있습니다. 프로젝트의 빌드 결과에 여전히 다양한 타임스탬프나 기타 비결정적 메타데이터가 포함되어 있는 경우, 기본 소스 코드가 전혀 변경되지 않았더라도 누가 실행하든 바이트 단위 비교는 실패하게 됩니다.
이러한 유물의 경우, 비교의 수준이 ‘증명’에서 ‘분석’으로 낮아집니다. 증거의 설득력은 필연적으로 약해지며 해석하는 데 더 많은 노력이 필요하므로, 이를 바탕으로 배포 범위를 설정하기 전에 이 점을 미리 알아두는 것이 좋습니다. 여전히 의미 있는 신호이긴 하지만, 바이트 단위로 정확히 일치하는 것은 아닙니다.
쉐이딩 처리되거나 위치가 변경된 종속성들은 이 문제를 더욱 복잡하게 만듭니다. 쉐이딩 플러그인은 패키지 이름과 인라인 종속성을 재작성하기 때문에, 구조적 비교가 실제로 어떤 대상을 살펴보는지까지 달라지게 됩니다. 이는 엔터프라이즈 자바 환경에서 꽤 자주 발생하는 문제이므로, 평가 과정에서 직접 이 점을 제기해 볼 가치가 있습니다.
Sonatype Nexus 방화벽의 대안이 있다고 해서 Nexus를 대체해야 한다는 뜻은 아닙니다
리포지토리 관리자의 프록시 리포지토리는 원격 URL을 가리킵니다. 해당 URL은 일반적으로 https://repo1.maven.org/maven2/입니다. 이 URL을 다른 곳으로 지정하는 것은 구성 항목일 뿐, 마이그레이션 프로젝트가 아닙니다.
| 레이어 | 그 전에는 | ~ 이후 |
|---|---|---|
| 빌드 도구 구성 | 리포지토리 관리자의 주요 사항 | 변경 없음 |
| 저장소 관리자 | Maven Central 프록시 | 프록시 SecureChain |
| pom.xml 및 settings.xml | 미러를 리포지토리 관리자에 설정 | 변경 없음 |
| 그룹 저장소 정렬 순서 | 설정된 대로 | 변경 없음 |
리포지토리 관리자가 빌드용 엔드포인트 역할을 계속 수행하는 한, 개발자 워크플로는 기존과 동일하게 유지되며 프로젝트 파일을 변경할 필요도 없습니다. 기존 그룹, 호스팅된 리포지토리 및 정리 정책은 그대로 유지됩니다. 리포지토리 관리자는 계속해서 캐싱, 가용성 관리 및 정책 적용을 수행합니다. 캐싱의 대상이 되는 업스트림은 공개 소스가 아닌, 선별되고 재빌드된 소스가 됩니다.
스왑 작업과 함께 두 가지를 수행하세요. 프록시에 네임스페이스 제외 규칙을 유지하세요. 내부 좌표가 업스트림에서 해결되는 것을 차단하는 것은 구성 변경에도 영향을 받지 않는 제어 수단이며, 어떤 업스트림으로 연결되어 있는지와는 무관하기 때문입니다. 그런 다음 미러 구성을 확인하세요. Maven은 종속성의 POM 내에 선언된 저장소를 우선적으로 따르기 때문에, 전이적 종속성으로 인해 사용자가 직접 선언하지 않았더라도 해결 세트에 저장소가 추가될 수 있습니다. A mirrorOf 규칙 집합은 오직 central 이러한 저장소는 차단되지 않으므로, 리포지토리 관리자를 통해 라우팅하려는 모든 외부 저장소가 포함되도록 설정되어 있는지 확인하십시오. 당사의 관련 기사에서 Maven의 settings.xml 누락 문제 이 문서에서는 바로 이 오류 유형을 더 자세히 다루고 있습니다. 프록시를 어디로 설정하든 상관없이 이 부분을 확인해 보시기 바랍니다. 이는 업스트림 변경으로 인해 발생하는 문제가 아니라, 기존 Maven 구성에 내재된 위험 요소이기 때문입니다.
어떤 구성이 적합할까요?
특히 아티팩트 변조 문제 때문에 Sonatype Nexus Firewall의 대체 솔루션을 검토하고 계신다면, 일반적인 기능 비교보다는 그 문제부터 직접적으로 다뤄보시기 바랍니다.
이미 Nexus나 Artifactory를 운영 중인 팀의 경우, 이번 조치가 프록시 URL 변경과 단일 그룹 리포지토리에 대한 시범 운영에 그치기 때문에 가장 수월하게 대응할 수 있습니다. 위협 모델에 조작된 아티팩트가 구체적으로 포함되지 않는다면, 기존의 스캔 기능만으로도 충분할 수 있으며, 네임스페이스 제외 규칙과 Gradle 검증 메타데이터는 다른 일반적인 공급망 공격 경로를 차단하는 데 도움이 되는 추가 비용 없이 적용할 수 있는 통제 수단입니다.
출처 증명이 필요한 규제 환경에서는 재빌드 비교 기능을 통해 최대의 효과를 얻을 수 있습니다. 이는 감사 가능한 증거를 생성하기 때문이며, 각 종속성에 대한 재현성 문제는 우선적으로 검토해야 할 사항입니다. 또한 Java 이외의 여러 생태계를 운영하고 있다면, 이를 단순한 개별 구매가 아닌 스택 수준의 결정으로 평가해야 합니다. Java에만 초점을 맞춘 통제 방식은 나머지 스택을 기존 상태 그대로 방치하게 되기 때문입니다.
결정하기 전에 SecureChain이 무엇을 재구축하는지 확인해 보세요
Nexus나 Artifactory 설정이 이미 캐싱, 가용성, 정책 관리를 잘 처리하고 있으며, 해당 파이프라인을 통해 흐르는 내용이 실제로 소스와 일치하는지 여부가 미해결 문제라면, SecureChain for Java는 사용자가 이미 운영 중인 리포지토리 관리 도구를 건드리지 않고도 바로 이 문제를 해결하기 위해 설계되었습니다. 동일한 레지스트리는 ‘무한 수명주기 지원(Endless Lifecycle Support)’을 통해 업스트림 유지보수가 종료된 후에도 의존성에 대한 취약점 수정 패치를 지속적으로 제공합니다.
견적 요청을 해 주시면, 귀사의 의존성 트리에서 단일 그룹 리포지토리를 대상으로 한 파일럿 프로젝트가 어떻게 진행될지 단계별로 안내해 드리겠습니다.
자주 묻는 질문
Sonatype Nexus Firewall의 대체 솔루션은 무엇인가요?
스캔 및 큐레이션 측면에서 Nexus Firewall(현재 Sonatype Repository Firewall로 명칭이 변경됨)과 경쟁하는 제품이 많습니다. 이 글에서 이 용어는 더 좁은 의미를 지닙니다. 즉, 게시된 아티팩트가 자신이 빌드되었다고 주장하는 소스와 일치하는지 여부와 같은 추가적인 신뢰 문제를 해결하는 접근 방식을 의미합니다. 스크리닝 및 재빌드 검증은 일반적으로 리포지토리 관리자를 대체하기보다는 리포지토리 관리자와 병행하여 실행됩니다. 리포지토리 관리자가 여전히 캐싱과 가용성을 처리하기 때문입니다.
바이너리 스캔으로 변조된 JAR 파일을 탐지할 수 있나요?
때로는 그렇습니다. 스캐너가 아티팩트의 내용을 검사하면, 행동 분석을 통해 해당 JAR 파일에 대한 보안 권고 사항이 전혀 없는 상태에서도 변조된 JAR 내부의 의심스러운 코드가 탐지될 수 있습니다. 그러나 스캐닝만으로는 아티팩트가 주장된 소스 코드와 다르다는 사실을 확인할 수 없으며, 이를 확인하려면 소스 코드와 아티팩트 간의 비교가 필요합니다.
자바에서 재현 가능한 빌드가 가능한가요?
네. Maven은 아카이브 메타데이터를 고정하는 빌드 출력 타임스탬프 속성을 지원하며, Maven 4.0.0-beta-5부터는 재현 가능한 빌드 모드가 기본적으로 활성화되어 있습니다. 빌드 환경이 충분히 통제된 상태라면, 동일한 소스 코드로 바이트 단위로 동일한 JAR 파일을 생성할 수 있습니다. Maven Central 전반에 걸친 지원 범위는 아직 부분적이므로, 재현 가능성은 프로젝트마다 다릅니다.
Maven은 기본적으로 PGP 서명을 검증하나요?
아닙니다. Maven Central은 게시자가 게시 시점에 서명을 제공하도록 요구하지만, Maven의 일반적인 종속성 해결 과정에서는 해당 서명이 아닌 체크섬을 검증합니다. 서명 검증을 위해서는 추가적인 도구나 플러그인이 필요합니다.
SecureChain을 사용하려면 Nexus나 Artifactory를 교체해야 하나요?
아닙니다. 리포지토리 관리자의 프록시는 구성 가능한 원격 URL을 가리키므로, SecureChain으로 전환하더라도 리포지토리 관리자 자체가 제거되는 것이 아니라 프록시 대상만 변경됩니다. 기존 리포지토리 관리자가 빌드용 엔드포인트로 계속 유지된다면, 개발자 설정, 프로젝트 파일 및 기존 그룹은 변경 없이 그대로 유지될 수 있습니다.
업스트림에서 재현할 수 없는 아티팩트는 어떻게 되나요?
빌드 결과 비결정적인 출력이 생성되면 바이트 단위 비교가 더 이상 불가능해지므로, 검증은 추가적인 분석에 의존하게 됩니다. 이러한 증거는 정확하고 재현 가능한 일치 결과보다는 설득력이 떨어지지만, 바이너리 파일만 스캔하는 것보다는 여전히 더 많은 정보를 제공합니다.
