다음을 통해 공유


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

이 문서에서는 ClickOnce 매니페스트를 포함하여 .NET에서 지원하는 암호화 방법 및 사례에 대한 개요를 제공합니다.

암호화 소개

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

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

암호화 기본 형식

암호화가 사용되는 일반적인 상황에서는 두 당사자(Alice와 Bob)가 안전하지 않은 채널을 통해 통신합니다. Alice와 Bob은 귀기울일 수 있는 사람이 통신을 이해할 수 없도록 하고 싶어합니다. 또한 Alice와 Bob은 원격 위치에 있으므로 Alice는 전송 중에 Bob에게서 받은 정보가 수정되지 않았는지 확인해야 합니다. 또한, 그녀는 정보가 실제로 Bob을 가장하는 사람이 아니라 Bob에서 유래했는지 확인해야 합니다.

암호화는 다음 목표를 달성하는 데 사용됩니다.

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

  • 데이터 무결성: 데이터가 변경되지 않도록 보호합니다.

  • 인증: 데이터가 특정 당사자로부터 시작되는지 확인합니다.

  • 부인할 수 없음: 특정 당사자가 메시지를 보낸 것을 부인하지 못하도록 합니다.

이러한 목표를 달성하기 위해 암호화 기본 형식이라고 하는 알고리즘과 사례의 조합을 사용하여 암호화 체계를 만들 수 있습니다. 다음 표에서는 암호화 기본 형식 및 해당 용도를 나열합니다.

암호화 기본 형식 사용하세요
비밀 키 암호화(대칭 암호화) 타사에서 데이터를 읽지 못하도록 데이터에 대한 변환을 수행합니다. 이 유형의 암호화는 단일 공유 비밀 키를 사용하여 데이터를 암호화하고 암호를 해독합니다.
공개 키 암호화(비대칭 암호화) 타사에서 데이터를 읽지 못하도록 데이터에 대한 변환을 수행합니다. 이 유형의 암호화는 퍼블릭/프라이빗 키 쌍을 사용하여 데이터를 암호화하고 암호를 해독합니다.
암호화 서명 해당 당사자에 고유한 디지털 서명을 만들어 데이터가 특정 당사자에서 발생하는지 확인하는 데 도움이 됩니다. 이 프로세스에서는 해시 함수도 사용합니다.
암호화 해시 모든 길이에서 고정 길이 바이트 시퀀스로 데이터를 매핑합니다. 해시는 통계적으로 고유합니다. 다른 2바이트 시퀀스는 동일한 값으로 해시되지 않습니다.

Secret-Key 암호화

비밀 키 암호화 알고리즘은 단일 비밀 키를 사용하여 데이터를 암호화하고 암호를 해독합니다. 권한 없는 자가 키에 접근하지 못하도록 반드시 보호해야 합니다. 키를 소지한 측은 귀하의 데이터를 해독하거나 자신의 데이터를 암호화하여 귀하로부터 발생한 것으로 주장할 수 있습니다.

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

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

블록 암호화의 한 가지 간단한 형태를 ECB(전자 코드북) 모드라고 합니다. ECB 모드는 초기화 벡터를 사용하여 첫 번째 일반 텍스트 블록을 초기화하지 않으므로 안전한 것으로 간주되지 않습니다. 지정된 비밀 키 k의 경우 초기화 벡터를 사용하지 않는 간단한 블록 암호화는 동일한 일반 텍스트 입력 블록을 암호화 텍스트의 동일한 출력 블록으로 암호화합니다. 따라서 입력 일반 텍스트 스트림에 중복 블록이 있는 경우 출력 암호 텍스트 스트림에 중복 블록이 있습니다. 이러한 중복 출력 블록은 사용되었을 수 있는 알고리즘과 가능한 공격 모드를 사용하는 약한 암호화에 대해 권한이 없는 사용자에게 경고합니다. 따라서 ECB 암호화 모드는 분석 및 궁극적으로 주요 검색에 매우 취약합니다.

기본 클래스 라이브러리에서 제공되는 블록 암호 클래스는 CBC(암호 블록 체인)라는 기본 체인 모드를 사용하지만 원하는 경우 이 기본값을 변경할 수 있습니다.

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

CBC 암호화로 암호화된 데이터를 손상시키는 한 가지 방법은 가능한 모든 키를 철저히 검색하는 것입니다. 암호화를 수행하는 데 사용되는 키의 크기에 따라 이러한 종류의 검색은 가장 빠른 컴퓨터를 사용하는 데 시간이 많이 걸리므로 사용할 수 없습니다. 키 크기가 클수록 해독하기가 더 어렵습니다. 암호화로 인해 악의적 사용자가 암호화된 데이터를 검색하는 것이 이론적으로 불가능해지지는 않지만 이 작업을 수행하는 데 드는 비용이 발생합니다. 며칠 동안만 의미 있는 데이터를 검색하기 위해 철저한 검색을 수행하는 데 3개월이 걸리는 경우 전체 검색 방법은 실용적이지 않습니다.

비밀 키 암호화의 단점은 두 당사자가 키와 IV에 합의하고 값을 전달했다고 가정한다는 것입니다. IV는 비밀로 간주되지 않으며 메시지와 함께 일반 텍스트로 전송될 수 있습니다. 그러나 권한이 없는 사용자로부터 키를 비밀로 유지해야 합니다. 이러한 문제로 인해 비밀 키 암호화는 종종 공개 키 암호화와 함께 사용하여 키 및 IV의 값을 비공개로 전달합니다.

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

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

  • Aes

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

Public-Key 암호화

공개 키 암호화는 권한이 없는 사용자로부터 비밀로 유지해야 하는 프라이빗 키와 누구나 공개할 수 있는 공개 키를 사용합니다. 공개 키와 프라이빗 키는 수학적으로 연결됩니다. 공개 키로 암호화된 데이터는 프라이빗 키로만 암호 해독할 수 있으며, 프라이빗 키로 서명된 데이터는 공개 키로만 확인할 수 있습니다. 공개 키는 누구나 사용할 수 있습니다. 프라이빗 키의 키 관리자에게 전송할 데이터를 암호화하는 데 사용됩니다. 공개 키 암호화 알고리즘을 비대칭 알고리즘이라고도 합니다. 한 키는 데이터를 암호화하는 데 필요하고 다른 키는 데이터 암호 해독에 필요하기 때문입니다. 기본 암호화 규칙은 키 재사용을 금지하며 두 키는 각 통신 세션에 대해 고유해야 합니다. 그러나 실제로 비대칭 키는 일반적으로 수명은 깁니다.

두 당사자(Alice 및 Bob)는 다음과 같이 공개 키 암호화를 사용할 수 있습니다. 첫째, Alice는 공개/프라이빗 키 쌍을 생성합니다. Bob이 Alice에게 암호화된 메시지를 보내려고 하면 공개 키를 요청합니다. Alice는 비보안 네트워크를 통해 Bob에게 공개 키를 보내고 Bob은 이 키를 사용하여 메시지를 암호화합니다. Bob은 암호화된 메시지를 Alice에게 보내고 프라이빗 키를 사용하여 암호를 해독합니다. Bob이 공개 네트워크와 같은 안전하지 않은 채널을 통해 Alice의 키를 받은 경우 Bob은 중간에서 맨인 더 미들 공격에 노출됩니다. 따라서 Bob은 Alice에게 공개 키의 올바른 복사본이 있는지 확인해야 합니다.

Alice의 공개 키를 전송하는 동안 권한이 없는 에이전트가 키를 가로챌 수 있습니다. 또한 동일한 에이전트가 Bob의 암호화된 메시지를 가로챌 수 있습니다. 그러나 에이전트는 공개 키를 사용하여 메시지의 암호를 해독할 수 없습니다. 메시지는 전송되지 않은 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는 먼저 메시지에 해시 알고리즘을 적용하여 메시지 다이제스트를 만듭니다. 메시지 다이제스트는 데이터의 간결하고 고유한 표현입니다. 그런 다음 Alice는 개인 키를 사용하여 메시지 다이제스트를 암호화하여 개인 서명을 만듭니다. 메시지와 서명을 받으면 Bob은 Alice의 공개 키를 사용하여 서명의 암호를 해독하여 메시지 다이제스트를 복구하고 Alice가 사용한 것과 동일한 해시 알고리즘을 사용하여 메시지를 해시합니다. Bob이 계산하는 메시지 다이제스트가 Alice로부터 받은 메시지 다이제스트와 정확히 일치하는 경우 Bob은 메시지가 프라이빗 키의 소유자로부터 제공되었으며 데이터가 수정되지 않았다는 것을 보장합니다. Bob이 Alice가 프라이빗 키의 소유자라고 신뢰하는 경우 메시지가 Alice에게서 왔다는 것을 알고 있습니다.

비고

보낸 사람의 공개 키는 일반적인 지식이며 일반적으로 디지털 서명 형식에 포함되기 때문에 누구나 서명을 확인할 수 있습니다. 이 메서드는 메시지의 비밀을 유지하지 않습니다. 메시지가 비밀이 되려면 암호화해야 합니다.

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

해시 값

해시 알고리즘은 임의의 길이의 이진 값을 해시 값이라고 하는 고정 길이의 더 작은 이진 값에 매핑합니다. 해시 값은 데이터 조각의 숫자 표현입니다. 일반 텍스트의 단락을 해시하고 단락의 한 글자만 변경하면 후속 해시가 다른 값을 생성합니다. 해시가 암호화적으로 강한 경우 해당 값이 크게 변경됩니다. 예를 들어 메시지의 단일 비트가 변경된 경우 강력한 해시 함수는 50% 차이의 출력을 생성할 수 있습니다. 많은 입력 값이 동일한 출력 값으로 해시할 수 있습니다. 하지만 두 개의 서로 다른 입력이 동일한 값에 해시되는 경우를 계산적으로 찾는 것은 불가능합니다.

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

  • Alice는 일반 텍스트 메시지와 해시된 메시지(디지털 서명)를 Bob에게 보냅니다. Bob은 메시지를 수신하고 해시하고 해시 값을 Alice로부터 받은 해시 값과 비교합니다. 해시 값이 같으면 메시지가 변경되지 않았습니다. 값이 동일하지 않으면 Alice가 메시지를 쓴 후 메시지가 변경되었습니다.

    아쉽게도 이 메서드는 보낸 사람의 신뢰성을 설정하지 않습니다. 누구나 Alice를 가장하고 Bob에게 메시지를 보낼 수 있습니다. 동일한 해시 알고리즘을 사용하여 메시지에 서명할 수 있으며, Bob이 확인할 수 있는 것은 메시지가 해당 서명과 일치한다는 것입니다. 이것은 중간자 공격의 한 형태입니다. 자세한 내용은 CNG(Cryptography Next Generation) 보안 통신 예제를 참조하세요.

  • Alice는 안전하지 않은 공용 채널을 통해 일반 텍스트 메시지를 Bob에게 보냅니다. 그녀는 보안 개인 채널을 통해 Bob에게 해시 메시지를 보냅니다. Bob은 일반 텍스트 메시지를 수신하고 해시한 다음 해시를 비공개로 교환된 해시와 비교합니다. 해시가 일치하면 Bob은 다음 두 가지를 알고 있습니다.

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

    • 메시지의 보낸 사람(Alice)이 인증됩니다.

    이 시스템이 작동하려면 Alice가 Bob을 제외한 모든 당사자로부터 원래 해시 값을 숨겨야 합니다.

  • Alice는 안전하지 않은 공개 채널을 통해 일반 텍스트 메시지를 Bob에게 보내고 공개적으로 볼 수 있는 웹 사이트에 해시된 메시지를 배치합니다.

    이 메서드는 누군가가 해시 값을 수정하지 못하도록 하여 메시지 변조를 방지합니다. 메시지와 해당 해시는 누구나 읽을 수 있지만 해시 값은 Alice만 변경할 수 있습니다. Alice를 가장하려는 공격자는 Alice의 웹 사이트에 액세스해야 합니다.

이전 메서드 중 어느 것도 Alice의 메시지를 일반 텍스트로 전송하기 때문에 다른 사람이 Alice의 메시지를 읽는 것을 방지하지 않습니다. 전체 보안에는 일반적으로 디지털 서명(메시지 서명) 및 암호화가 필요합니다.

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

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

난수 생성

난수 생성은 많은 암호화 작업에 필수적입니다. 예를 들어 암호화 키를 재현할 수 없도록 가능한 한 임의 키여야 합니다. 암호화 난수 생성기는 절반보다 더 나은 확률로 예측할 수 없는 출력을 생성해야 합니다. 따라서 다음 출력 비트를 예측하는 방법은 임의 추측보다 더 잘 수행해서는 안 됩니다. .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 는 자주 사용되는 키 속성을 유지 관리합니다.

참고하십시오