.NET의 암호화, 디지털 서명 및 해시 알고리즘 개요

이 문서에서는 ClickOnce 매니페스트를 포함하여 .NET에서 지원하는 암호화 방법 및 사례를 간략하게 설명합니다.

암호화 소개

인터넷과 같은 공용 네트워크에서는 엔터티 간의 보안 통신 수단을 제공하지 않습니다. 이러한 네트워크를 통한 통신은 권한이 없는 제3자가 읽거나 심지어는 수정하기도 쉽습니다. 암호화는 데이터를 볼 수 없도록 보호하며 데이터가 수정되었는지 감지하는 방법을 제공하며 기타 보안상 위험한 채널을 통한 안전한 통신 수단 제공을 지원합니다. 예를 들어 데이터를 암호화된 상태로 전송하고 나중에 의도된 당사자가 해독하는 암호화 알고리즘을 사용하여 데이터를 암호화할 수 있습니다. 제3자가 암호화된 데이터를 가로채는 경우 해독하기 어렵습니다.

.NET에서는 System.Security.Cryptography 네임스페이스의 클래스가 암호화에 대한 많은 세부 정보를 관리합니다. 일부는 운영 체제 구현을 위한 래퍼이고 다른 일부는 순수하게 관리되는 구현입니다. 이러한 클래스를 사용하기 위해 암호화 전문가가 될 필요는 없습니다. 암호화 알고리즘 클래스 중 하나의 새 인스턴스를 만들 경우 키가 사용 편의를 위해 자동으로 생성되며, 기본 속성은 가능한 한 안전합니다.

암호화 기본

암호화가 사용되는 일반적인 상황에서 두 당사자(Alice와 Bob)는 보안상 위험한 채널을 통해 통신하고 있습니다. Alice와 Bob은 통신을 수신할 수도 있는 다른 사용자가 계속해서 둘 간의 통신을 이해할 수 없도록 하려고 합니다. 게다가 Alice와 Bob은 원격 위치에 있으므로 Alice는 Bob으로부터 받은 정보가 전송 중 다른 사용자에 의해 수정되지 않았는지 확인해야 합니다. 또한 그녀는 정보가 Bob을 가장하는 사람이 아니라 실제로 Bob에서 온 것임을 확인해야 합니다.

암호화는 다음과 같은 목표를 달성하기 위해 사용됩니다.

  • 기밀성: 사용자의 ID 또는 데이터를 읽지 못하도록 보호 지원

  • 데이터 무결성: 데이터를 변경하지 못하도록 보호 지원

  • 인증: 데이터가 특정 당사자로부터 온 것임을 보장

  • 부인 방지: 특정 당사자가 메시지 보낸 사실을 부인하지 못하도록 방지

이러한 목표를 달성하기 위해 암호화 기본이라고 알려진 알고리즘과 방법을 결합하여 암호화 체계를 만들 수 있습니다. 다음 표는 암호화 기본 및 해당 기능 목록을 보여 줍니다.

암호화 기본 사용할 용어
비밀 키 암호화(대칭 암호화) 데이터에서 변환을 수행하여 제3자가 읽지 못하게 합니다. 이 유형의 암호화는 공유된 하나의 비밀 키를 사용하여 데이터를 암호화하고 해독합니다.
공개 키 암호화(비대칭 암호화) 데이터에서 변환을 수행하여 제3자가 읽지 못하게 합니다. 이 유형의 암호화는 퍼블릭/프라이빗 키 쌍을 사용하여 데이터를 암호화하고 해독합니다.
암호화 서명 특정 당사자에 고유한 디지털 서명을 만들어 데이터가 해당 당사자로부터 온 것임을 확인할 수 있도록 지원합니다. 또한 이 프로세스는 해시 함수도 사용합니다.
암호화 해시 데이터를 임의 길이에서 고정 길이의 바이트 시퀀스로 매핑합니다. 해시는 통계적으로 고유합니다. 서로 다른 2바이트 시퀀스는 같은 값으로 해시하지 않습니다.

비밀 키 암호화

비밀 키 암호화 알고리즘은 하나의 비밀 키를 사용하여 데이터를 암호화하고 해독합니다. 키를 가진 사람은 누구나 키를 사용하여 데이터를 해독하거나 자신의 데이터를 암호화한 다음 출처를 가장할 수 있으므로 권한이 없는 다른 사용자가 키에 액세스할 수 없도록 보호해야 합니다.

또한 비밀 키 암호화는 동일한 키가 암호화 및 해독에 사용되므로 대칭 암호화라고도 합니다. 비밀 키 암호화 알고리즘은 공개 키 알고리즘과 비교하여 매우 빠르며, 대규모 데이터 스트림에 대해 암호화 변환을 수행하는 데 매우 적합합니다. RSA와 같은 비대칭 암호화 알고리즘은 암호화할 수 있는 데이터 양에 있어 수학적으로 제한됩니다. 일반적으로 대칭 암호화 알고리즘에는 이러한 문제가 없습니다.

블록 암호라고 하는 비밀 키 알고리즘의 유형은 한 번에 한 데이터 블록을 암호화하는 데 사용합니다. DES(데이터 암호화 표준), TripleDES 및 AES(Advanced Encryption Standard)와 같은 블록 암호는 n 바이트의 입력 블록을 암호화된 바이트의 출력 블록으로 암호화하여 변환합니다. 바이트 시퀀스를 암호화하거나 해독하려는 경우 작업을 블록 단위로 수행해야 합니다. n 이 작기(DES 및 TripleDES의 경우 8바이트, AES의 경우 16바이트[기본값], 24바이트 또는 32바이트) 때문에 n 보다 큰 데이터 값은 한 번에 한 블록씩 암호화되어야 합니다. n 보다 작은 데이터 값은 처리하려면 n 으로 확장해야 합니다.

블록 암호의 한 가지 간단한 형태는 ECB(Electronic CodeBook) 모드라고 합니다. ECB 모드는 첫 번째 일반 텍스트 블록을 초기화하는 데 초기화 벡터를 사용하지 않으므로 안전하지 않은 것으로 간주됩니다. 비밀 키 k가 주어진 경우 초기화 벡터를 사용하지 않는 단순 블록 암호는 일반 텍스트의 동일한 입력 블록을 암호 텍스트의 동일한 출력 블록으로 암호화합니다. 따라서 입력 일반 텍스트 스트림에 중복된 블록이 있는 경우 출력 암호 텍스트 스트림에도 중복된 블록이 생성됩니다. 이러한 중복 출력 블록을 통해 권한이 없는 사용자가 취약한 암호화 알고리즘이 사용되었다는 사실과 가능한 공격 방식을 알게 됩니다. 따라서 ECB 암호화 모드는 분석에 매우 취약하므로 키가 노출될 수 있습니다.

기본 클래스 라이브러리에 제공되는 블록 암호 클래스에서는 CBC(Cipher Block Chaining)라는 기본 체인 모드를 사용하며, 필요에 따라 이 기본 모드를 변경할 수 있습니다.

CBC 암호화에서는 IV(Initialization Vector)를 사용하여 일반 텍스트의 첫 번째 블록을 암호화함으로써 ECB 암호화와 관련된 문제를 해결합니다. 일반 텍스트의 각 후속 블록은 암호화되기 전에 이전 암호 텍스트 블록과 배타적 비트 OR(XOR) 연산을 수행합니다. 따라서 각 암호 텍스트 블록은 이전 모든 블록에 종속됩니다. 이 시스템을 사용하는 경우 권한이 없는 사용자에게 알려질 수 있는 일반적인 메시지 헤더를 사용해서는 키를 리버스 엔지니어링할 수 없습니다.

CBC 암호화로 암호화된 데이터를 손상시킬 수 있는 한 가지 방법은 가능한 모든 키에 대해 철저한 검색을 수행하는 것입니다. 암호화 수행에 사용된 키의 크기에 따라 가장 빠른 컴퓨터를 사용해도 이러한 철저한 검색에는 많은 시간이 걸리므로 이 방법은 실제로 불가능합니다. 키 크기가 클수록 해독이 더 어려워집니다. 이론적으로 암호화를 통해 악의적 사용자가 암호화된 데이터를 검색할 수 없도록 할 수는 있지만, 그러면 비용이 증가합니다. 며칠 동안만 유용한 데이터를 검색하기 위해 3개월에 걸쳐 철저한 검색을 수행한다면 철저한 검색 방법은 실용적이지 않습니다.

비밀 키 암호화의 단점은 두 당사자가 키 및 IV에 대해 동의하고 해당 값을 통신했다고 추정하는 것입니다. IV는 비밀로 간주되지 않으며 메시지와 함께 일반 텍스트로 전송할 수 있습니다. 그러나 키는 권한이 없는 사용자에게 비밀로 유지되어야 합니다. 이러한 문제 때문에 비밀 키 암호화는 키와 IV의 값을 비밀리에 교환하는 공개 키 암호화와 함께 사용되는 경우가 많습니다.

두 당사자인 Alice와 Bob이 안전하지 않은 채널을 통해 통신하려는 경우를 가정할 때 그들은 다음과 같은 방법으로 비밀 키 암호화를 사용할 수 있습니다. 즉, Alice와 Bob은 특정 키 및 IV와 함께 하나의 특정 알고리즘(예: AES)을 사용하기로 동의합니다. Alice는 메시지를 작성하고 해당 메시지를 보낼 네트워크 스트림(명명된 파이프 또는 네트워크 메일)을 만듭니다. 그런 다음 키와 IV를 사용하여 텍스트를 암호화하고 인트라넷을 통해 Bob에게 암호화된 메시지와 IV를 전송합니다. Bob은 암호화된 텍스트를 수신하고 IV와 미리 동의한 키를 사용하여 텍스트를 해독합니다. 전송이 차단되면 인터셉터는 키를 모르기 때문에 원본 메시지를 복구할 수 없습니다. 이 시나리오에서는 키만 비밀로 유지하면 됩니다. 실제 시나리오에서는 Alice 또는 Bob 중 한 사람이 비밀 키를 생성하고 공개 키(비대칭) 암호화를 사용하여 비밀(대칭) 키를 상대방에게 전송합니다. 공개 키 암호화에 대한 자세한 내용은 다음 섹션을 참조하세요.

.NET에서는 비밀 키 암호화 알고리즘을 구현하는 다음 클래스를 제공합니다.

  • Aes

  • HMACSHA256, HMACSHA384HMACSHA512. (이는 비밀 키와 결합된 암호화 해시 함수를 사용하여 계산된 메시지 인증 코드를 나타내기 때문에 기술적으로 비밀 키 알고리즘입니다. 이 문서 뒷부분에 나오는 해시 값을 참조하세요.)

공개 키 암호화

퍼블릭 키 암호화에서는 권한이 없는 사용자에게 비밀로 유지되어야 하는 프라이빗 키와 모든 사람에게 퍼블릭될 수 있는 퍼블릭 키를 사용합니다. 퍼블릭 키와 프라이빗 키는 수학적으로 연결되어 있습니다. 퍼블릭 키로 암호화된 데이터는 해당 프라이빗 키로만 해독할 수 있으며, 프라이빗 키로 서명된 데이터는 해당 퍼블릭 키로만 확인할 수 있습니다. 퍼블릭 키는 모든 사람이 사용할 수 있습니다. 퍼블릭 키는 프라이빗 키의 보유자에게 보낼 데이터를 암호화하는 데 사용됩니다. 공개 키 암호화 알고리즘은 데이터를 암호화하는 데 필요한 키와 해독하는 데 필요한 키가 서로 다르므로 비대칭 알고리즘이라고도 합니다. 기본적인 암호화 규칙은 키 재사용을 금지하며, 두 키가 모두 각 통신 세션에 고유해야 합니다. 그러나 실제로는, 일반적으로 비대칭 키가 수명이 깁니다.

두 당사자인 Alice와 Bob은 다음과 같이 퍼블릭 키 암호화를 사용할 수 있습니다. 즉, 먼저 Alice가 퍼블릭/프라이빗 키 쌍을 생성합니다. Bob은 Alice에게 암호화된 메시지를 보내려는 경우 Alice의 공개 키를 묻습니다. Alice는 안전하지 않은 네트워크를 통해 Bob에게 공개 키를 보내고 Bob은 이 키를 사용하여 메시지를 암호화합니다. Bob은 암호화된 메시지를 Alice에게 보내고 Alice는 자신의 프라이빗 키를 사용하여 메시지를 해독합니다. Bob이 공용 네트워크와 같은 안전하지 않은 채널을 통해 Alice의 키를 받은 경우 Bob은 메시지 가로채기(man-in-the-middle) 공격에 노출될 수 있습니다. 따라서 Bob은 자신이 공개 키의 정확한 복사본을 가졌는지 Alice에게 확인해야 합니다.

Alice의 공개 키를 전송하는 동안 권한이 없는 제3자가 키를 가로챌 수 있습니다. 또한 동일한 제3자가 Bob으로부터 암호화된 메시지를 가로챌 수도 있습니다. 그러나 제3자는 공개 키를 사용하여 메시지를 해독할 수 없습니다. 전송되지 않은 Alice의 프라이빗 키를 사용해서만 메시지를 해독할 수 있습니다. Alice는 Bob에게 보내는 회신 메시지를 암호화하는 데 자신의 프라이빗 키를 사용하지 않습니다. 퍼블릭 키를 가진 사람이 해당 메시지를 해독할 수 있기 때문입니다. Alice가 Bob에게 메시지를 다시 보내려는 경우 Bob에게 그의 공개 키를 묻고 해당 공개 키를 사용하여 메시지를 암호화합니다. 그러면 Bob은 자신의 연결된 프라이빗 키를 사용하여 메시지를 해독합니다.

이 시나리오에서 Alice와 Bob은 공개 키(비대칭) 암호화를 사용하여 비밀(대칭) 키를 전송하고 나머지 세션에 비밀 키 암호화를 사용합니다.

다음은 공개 키와 비밀 키 암호화 알고리즘을 비교한 목록입니다.

  • 공개 키 암호화 알고리즘에서는 고정 버퍼 크기를 사용하는 반면 비밀 키 암호화 알고리즘에서는 가변 길이 버퍼를 사용합니다.

  • 공개 키 알고리즘에서는 적은 양의 데이터만 암호화할 수 있으므로 비밀 키 알고리즘과 같이 데이터를 스트림으로 결합하는 데 사용할 수는 없습니다. 따라서 비대칭 작업에서는 대칭 작업에서와 동일한 스트리밍 모델을 사용하지 않습니다.

  • 공개 키 암호화는 비밀 키 암호화보다 키 공간(키에 사용할 수 있는 값의 범위)이 훨씬 큽니다. 따라서 공개 키 암호화는 가능한 모든 키를 시도하는 철저한 공격에 덜 취약합니다.

  • 보낸 사람의 ID를 확인할 방법이 몇 가지 있다면 공개 키는 보호할 필요가 없으므로 손쉽게 배포할 수 있습니다.

  • 디지털 서명을 생성하는 데 일부 공개 키 알고리즘(예: RSA 및 DSA 단, Diffie-Hellman 제외)을 사용하면 데이터를 보낸 사람의 ID를 확인할 수 있습니다.

  • 공개 키 알고리즘은 비밀 키 알고리즘과 비교하면 매우 느리므로 대규모 데이터를 암호화할 때는 적합하지 않습니다. 공개 키 알고리즘은 매우 적은 양의 데이터를 전송하는 데만 유용합니다. 일반적으로 공개 키 암호화는 비밀 키 알고리즘에서 사용하는 키 및 IV를 암호화하는 데 사용합니다. 키 및 IV가 전송되면 비밀 키 암호화가 나머지 세션에서 사용됩니다.

.NET은 공용 키 알고리즘을 구현하는 다음 클래스를 제공합니다.

RSA는 암호화와 서명을 모두 허용하지만 DSA는 서명에만 사용할 수 있습니다. DSA는 RSA만큼 안전하지 않으므로 RSA를 권장합니다. Diffie-Hellman은 키 생성에만 사용할 수 있습니다. 일반적으로 퍼블릭 키 알고리즘은 비밀 키 알고리즘보다 용도가 제한됩니다.

디지털 서명

공개 키 알고리즘은 디지털 서명을 만드는 데도 사용할 수 있습니다. 디지털 서명은 보낸 사람의 공개 키를 신뢰하는 경우 보낸 사람의 ID를 인증하고, 데이터 무결성 보호를 지원합니다. Alice의 데이터를 받는 사람은 Alice가 생성한 공개 키를 사용하여 해당 디지털 서명을 Alice의 데이터 및 공개 키와 비교함으로써 Alice가 해당 데이터를 보냈는지 확인할 수 있습니다.

공개 키 암호화를 사용하여 메시지에 디지털 서명을 추가하기 위해 Alice는 먼저 메시지에 해시 알고리즘을 적용하여 메시지 다이제스트를 만듭니다. 이 메시지 다이제스트는 데이터의 압축된 고유 표현입니다. 그런 다음 Alice는 자신의 프라이빗 키를 사용하여 메시지 다이제스트를 암호화하고 자신의 개인 서명을 만듭니다. Bob은 메시지와 서명을 받으면 Alice의 공개 키를 사용하여 서명을 해독하고 메시지 다이제스트를 복구하고 Alice가 사용한 것과 동일한 해시 알고리즘을 사용하여 메시지를 해시합니다. Bob이 계산한 메시지 다이제스트가 Alice로부터 받은 메시지 다이제스트와 정확히 일치하면 Bob은 해당 메시지가 프라이빗 키의 소유자로부터 왔으며 데이터가 수정되지 않았음을 확인할 수 있습니다. Bob이 프라이빗 키의 소유자가 Alice임을 신뢰하는 경우 해당 메시지를 Alice가 보냈음을 알게 됩니다.

참고 항목

보낸 사람의 공개 키는 공개된 정보이고 일반적으로 디지털 서명 형식에 포함되므로 누구나 서명을 확인할 수 있습니다. 이 방법이 메시지의 기밀성을 유지하지는 않으므로 메시지의 기밀을 위해서는 메시지에 대한 암호화도 수행해야 합니다.

.NET에서는 디지털 서명 알고리즘을 구현하는 다음 클래스를 제공합니다.

해시 값

해시 알고리즘은 임의 길이의 이진 값을 해시 값으로 알려진 고정된 길이의 더욱 작은 이진 값에 매핑합니다. 해시 값은 데이터 부분을 숫자로 나타낸 값입니다. 일반 텍스트 단락을 해시하고 단락의 한 문자만 변경해도 그다음 해시는 다른 값을 생성합니다. 해시가 강력하게 암호화되면 해당 값이 크게 변경됩니다. 예를 들어 메시지 중 1비트만 변경되어도 강력한 해시 함수는 50%까지 다른 출력을 생성할 수 있습니다. 여러 입력 값이 동일한 출력 값으로 해시될 수 있습니다. 그러나 동일한 값으로 해시되는 두 개의 고유한 입력을 찾는 것은 계산상 불가능합니다.

두 당사자, Alice와 Bob은 해시 함수를 사용하여 메시지 무결성을 보장할 수 있습니다. 이를 위해 메시지에 서명할 해시 알고리즘을 선택합니다. Alice는 메시지를 작성한 후 선택한 알고리즘을 사용하여 해당 메시지의 해시를 만듭니다. 그런 다음 아래 방법 중 하나를 따릅니다.

  • Alice는 일반 텍스트 메시지와 해시된 메시지(디지털 서명)를 Bob에게 보냅니다. Bob은 메시지를 받아 해시하고 자신의 해시 값과 Alice로부터 받은 해시 값을 비교합니다. 해시 값이 동일하면 메시지가 변경되지 않은 것입니다. 값이 동일하지 않으면 Alice가 메시지를 작성한 후 해당 메시지가 변경된 것입니다.

    하지만 이 방법이 보낸 사람의 신뢰성을 보장하지는 않습니다. 다른 사람이 Alice를 가장하여 Bob에게 메시지를 보낼 수도 있습니다. Alice와 Bob이 동일한 해시 알고리즘을 사용하여 메시지에 서명할 수 있는데 이때 Bob은 메시지와 해당 서명이 일치한다는 사실만 확인하면 됩니다. 이는 메시지 가로채기(man-in-the-middle) 공격의 한 가지 형태입니다. 자세한 내용은 CNG(Cryptography Next Generation) 보안 통신 예를 참조하세요.

  • Alice가 비보안 공용 채널을 통해 Bob에게 일반 텍스트 메시지를 보냅니다. 그리고 보안 개인 채널을 통해 Bob에게 해시된 메시지를 보냅니다. Bob은 일반 텍스트 메시지를 받아 해시하고, 이 해시를 개인 채널로 교환된 해시와 비교합니다. 해시가 일치하면 Bob은 다음 두 가지 사실을 알게 됩니다.

    • 메시지가 변경되지 않았습니다.

    • 메시지를 보낸 사람(Alice)이 인증되었습니다.

    이 시스템이 작동되려면 Alice가 Bob을 제외한 모든 사람에게 원본 해시 값을 숨겨야 합니다.

  • Alice가 비보안 공용 채널을 통해 Bob에게 일반 텍스트 메시지를 보내고 공개적으로 볼 수 있는 자신의 웹 사이트에 해시된 메시지를 게시합니다.

    이 방법을 사용하면 아무도 해시 값을 수정할 수 없으므로 메시지 변조를 방지할 수 있습니다. 메시지와 해당 해시를 아무나 읽을 수 있지만, 해시 값은 Alice만 변경할 수 있습니다. Alice를 가장하려는 공격자는 Alice의 웹 사이트에 액세스할 수 있어야 합니다.

이러한 방법 중 어떠한 방법을 사용해도 일반 텍스트로 전송되는 Alice의 메시지를 다른 사람이 읽지 못하게 할 수는 없습니다. 일반적으로 완벽한 보안을 구현하려면 디지털 서명(메시지 서명)과 암호화가 필요합니다.

.NET에서는 해시 알고리즘을 구현하는 다음 클래스를 제공합니다.

.NET은 MD5SHA1도 제공합니다. 그러나 MD5 및 SHA-1 알고리즘은 안전하지 않은 것으로 확인되었으며 이제는 SHA-2가 대신 권장됩니다. SHA-2에는 SHA256, SHA384 및 SHA512가 포함됩니다.

난수 생성

난수 생성은 여러 암호화 작업에 필수적입니다. 예를 들어 암호화 키는 재현이 불가능하도록 가능한 한 무작위적이어야 합니다. 암호화 난수 생성기는 계산상 1/2 이상의 확률로 예측할 수 없는 출력을 생성해야 합니다. 따라서 어떠한 다음 출력 비트 예측 방법도 임의 추측보다 더 잘 예측할 수 없어야 합니다. .NET의 클래스는 난수 생성기를 사용하여 암호화 키를 생성합니다.

RandomNumberGenerator 클래스는 난수 생성기 알고리즘을 구현한 것입니다.

ClickOnce 매니페스트

다음과 같은 암호화 클래스를 통해 ClickOnce 기술로 배포된 애플리케이션의 매니페스트 서명에 대한 정보를 가져오고 확인할 수 있습니다.

또한 다음 클래스는 특정 서명 정보를 제공합니다.

CNG(Cryptography Next Generation) 클래스

CNG(Cryptography Next Generation) 클래스는 네이티브 CNG 함수 관련 관리 래퍼를 제공합니다. (CNG는 CryptoAPI를 대체합니다.) 이러한 클래스의 이름에는 "Cng"가 포함되어 있습니다. CNG 래퍼 클래스의 핵심은 CNG 키의 스토리지 및 사용을 추상화하는 CngKey 키 컨테이너 클래스입니다. 이 클래스를 통해 키 쌍 또는 공개 키를 안전하게 저장하고 간단한 문자열 이름을 사용하여 참조할 수 있습니다. 타원 곡선 기반 ECDsaCng 서명 클래스 및 ECDiffieHellmanCng 암호화 클래스는 CngKey 개체를 사용할 수 있습니다.

CngKey 클래스는 키 열기, 생성, 삭제, 내보내기 등의 다양한 추가 작업에 사용됩니다. 또한 네이티브 함수를 직접 호출할 때 사용할 기본 키 핸들에 대한 액세스를 제공합니다.

.NET에는 다음과 같은 다양한 지원 CNG 클래스도 포함되어 있습니다.

  • CngProvider는 키 스토리지 공급자를 유지 관리합니다.

  • CngAlgorithm 은 CNG 알고리즘을 유지 관리합니다.

  • CngProperty 는 자주 사용되는 키 속성을 유지 관리합니다.

참고 항목