다음을 통해 공유


.NET 암호화 모델

.NET은 다양한 표준 암호화 알고리즘의 구현을 제공합니다.

개체 상속

.NET 암호화 시스템은 파생 클래스 상속의 확장 가능한 패턴을 구현합니다. 계층 구조는 다음과 같습니다.

이 파생 클래스 패턴을 사용하면 새 알고리즘을 추가하거나 기존 알고리즘의 새 구현을 추가할 수 있습니다. 예를 들어 새로운 공용 키 알고리즘을 만들려면 AsymmetricAlgorithm 클래스에서 상속합니다. 특정 알고리즘의 새 구현을 만들려면 해당 알고리즘의 비추상 파생 클래스를 만듭니다.

앞으로는 이 상속 모델이 AesGcm 또는 Shake128과 같은 새로운 유형의 기본 요소에 사용되지 않습니다. 이러한 알고리즘은 sealed입니다. 이러한 형식에 대한 확장성 패턴이나 추상화가 필요한 경우 추상화 구현은 개발자의 책임입니다.

원샷 API

.NET 5부터 해싱 및 HMAC를 위해 더 간단한 API가 도입되었습니다. 유연성은 약간 떨어지지만 이러한 원샷 API는 다음과 같습니다.

  • 사용하기가 더 쉽고 오용 가능성도 적음
  • 할당을 줄이거나 할당이 없음
  • 스레드로부터 안전
  • 플랫폼에 가장 적합한 구현 사용

해싱 및 HMAC 기본 요소는 SHA256.HashData와 같은 형식의 정적 HashData 메서드를 통해 일회성 API를 노출합니다. 정적 API는 기본 제공된 확장성 메커니즘을 제공하지 않습니다. 자체 알고리즘을 구현하는 경우 알고리즘의 유사한 정적 API도 제공하는 것이 좋습니다.

RandomNumberGenerator 클래스는 또한 암호화 임의 데이터로 버퍼를 만들거나 채우기 위한 정적 메서드를 제공합니다. 이러한 방법은 항상 시스템의 CSPRNG(암호화 보안 의사 난수 생성기)를 사용합니다.

.NET에서 알고리즘이 구현되는 방법

알고리즘에 사용할 수 있는 다양한 구현의 예로 대칭 알고리즘을 고려해 보세요. 모든 대칭 알고리즘의 기본은 SymmetricAlgorithm이며, 이는 Aes, TripleDES 및 더 이상 권장되지 않는 기타 알고리즘에 의해 상속됩니다.

AesAesCryptoServiceProvider, AesCngAesManaged에 상속됩니다.

Windows의 .NET Framework에서:

  • AesCryptoServiceProvider와 같은 *CryptoServiceProvider 알고리즘 클래스는 알고리즘의 Windows CAPI(Windows Cryptography API) 구현을 둘러싼 래퍼입니다.
  • ECDiffieHellmanCng와 같은 *Cng 알고리즘 클래스는 Windows CNG(Cryptography Next Generation) 구현에 대한 래퍼입니다.
  • AesManaged와 같은 *Managed 클래스는 전적으로 관리 코드로 작성되었습니다. *Managed 구현은 FIPS(Federal Information Processing Standard)의 인증을 받지 않았으며 *CryptoServiceProvider*Cng 래퍼 클래스보다 느릴 수 있습니다.

.NET Core 및 .NET 5 이상 버전에서 모든 구현 클래스(*CryptoServiceProvider, *Managed*Cng)는 OS(운영 체제) 알고리즘에 대한 래퍼입니다. OS 알고리즘이 FIPS 인증을 받은 경우 .NET은 FIPS 인증 알고리즘을 사용합니다. 자세한 내용은 플랫폼 간 암호화를 참조하세요.

대부분의 경우 AesCryptoServiceProvider와 같은 알고리즘 구현 클래스를 직접 참조할 필요는 없습니다. 일반적으로 필요한 메서드와 속성은 Aes와 같은 기본 알고리즘 클래스에 있습니다. 기본 알고리즘 클래스에 팩터리 메서드를 사용하여 기본 구현 클래스의 인스턴스를 만들고 기본 알고리즘 클래스를 참조하세요. 예를 들어, 다음 예에서 강조 표시된 코드 줄을 참조하세요.

using System.Security.Cryptography;

try
{
    using (FileStream fileStream = new("TestData.txt", FileMode.OpenOrCreate))
    {
        using (Aes aes = Aes.Create())
        {
            byte[] key =
            {
                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
            };
            aes.Key = key;

            byte[] iv = aes.IV;
            fileStream.Write(iv, 0, iv.Length);

            using (CryptoStream cryptoStream = new(
                fileStream,
                aes.CreateEncryptor(),
                CryptoStreamMode.Write))
            {
                // By default, the StreamWriter uses UTF-8 encoding.
                // To change the text encoding, pass the desired encoding as the second parameter.
                // For example, new StreamWriter(cryptoStream, Encoding.Unicode).
                using (StreamWriter encryptWriter = new(cryptoStream))
                {
                    encryptWriter.WriteLine("Hello World!");
                }
            }
        }
    }

    Console.WriteLine("The file was encrypted.");
}
catch (Exception ex)
{
    Console.WriteLine($"The encryption failed. {ex}");
}
Imports System
Imports System.IO
Imports System.Security.Cryptography

Module Module1
    Sub Main()
        Try
            ' Create a file stream
            Using fileStream As New FileStream("TestData.txt", FileMode.OpenOrCreate)

                ' Create a new instance of the default Aes implementation class  
                ' and configure encryption key.
                Using aes As Aes = Aes.Create()
                    'Encryption key used to encrypt the stream.
                    'The same value must be used to encrypt and decrypt the stream.
                    Dim key As Byte() = {
                        &H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8,
                        &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16
                    }

                    aes.Key = key

                    ' Stores IV at the beginning of the file.
                    ' This information will be used for decryption.
                    Dim iv As Byte() = aes.IV
                    fileStream.Write(iv, 0, iv.Length)

                    ' Create a CryptoStream, pass it the FileStream, and encrypt
                    ' it with the Aes class.
                    Using cryptoStream As New CryptoStream(fileStream, aes.CreateEncryptor(), CryptoStreamMode.Write)

                        ' By default, the StreamWriter uses UTF-8 encoding.
                        ' To change the text encoding, pass the desired encoding as the second parameter.
                        ' For example, New StreamWriter(cryptoStream, Encoding.Unicode).
                        Using sWriter As New StreamWriter(cryptoStream)

                            'Write to the stream.
                            sWriter.WriteLine("Hello World!")
                        End Using
                    End Using
                End Using
            End Using

            'Inform the user that the message was written  
            'to the stream.  
            Console.WriteLine("The text was encrypted.")
        Catch
            'Inform the user that an exception was raised.  
            Console.WriteLine("The encryption failed.")
            Throw
        End Try
    End Sub
End Module

알고리즘 선택

데이터 무결성, 데이터 프라이버시 또는 키 생성과 같은 다양한 이유로 알고리즘을 선택할 수 있습니다. 대칭 및 해시 알고리즘은 무결성(변경 차단) 또는 프라이버시(보기 차단)를 위해 데이터를 보호하는 데 사용됩니다. 해시 알고리즘은 주로 데이터 무결성을 위해 사용됩니다.

애플리케이션에서 권장하는 알고리즘 목록은 다음과 같습니다.

참고 항목