기본 콘텐츠로 건너뛰기

[.NET] Configuration 암/복호화

.NET 2.0 이상부터는 ConfigurationSettings 가 아닌 ConfigurationManager 를 사용하게 된다. 그럼 ConfigurationManager의 특징들에 대해 정리해 놓도록 하자.

  • AppSettings, ConnectionStrings 속성을 제공하기 때문에 바로 접근이 가능하다.
  • 다른 섹션을 액세스하기 위해 GetSection 메서드를 사용하고, 다른 컴퓨터에 대한 모든 수준의 설정을 로컬 및 원격으로 읽고 쓰기가 가능하다.
  • 설정에 대해서 다양한 작업을 지원한다. (SectionInformation, PropertyInformation, PropertyInformationCollection, ElementInformation, ContextInformation, ConfigurationSectionGroup, ConfigurationSectionGroupCollection, ...)
  • RefreshSection 메서드를 이용해서 특정 Section 정보를 다시 읽을 수 있으며, Configuration 파일의 내용을 갱신할 수도 있다. (단, 주의할 부분은 Configuration 정보들이 읽기 전용이므로 Add 등의 작업은 불가능하며, 수정되는 경우도 machine.config 가 대상이 될 수 있으므로 특정한 파일을 처리하여야 하는 경우는 OpenExeConfiguration, OpenMachineConfigufation, OpenMappedExeConfiguration, OpenMappedMachineConfiguration, ... 등의 메서드를 이용해서 Configuration을 구성하고 처리하여야 한다)
위의 수정(저장) 기능은 다음과 같이 처리가 가능하다.

...
string connStr = "server=(local);database=northwind;Integrated Security=SSPI;";

// open configuration file
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

// add ConnectionString
config.ConnectionStrings.ConnectionStrings.Add(new ConnectionStringSettings("connStr", connStr));

// save
config.Save(ConfigurationSaveMode.Modified);

// force a reaload of the changed section
ConfigurationManager.RefreshSection("connectionStrings");

이제 암/복호화에 대해서 알아보도록 하자.

설정 파일은 단순한 XML 파일이기 때문에 DB 연결 문자열의 경우는 별도의 처리를 하지 않는 한 그대로 노출이 된다. 웹 어플리케이션의 경우는 설정 파일이 서버에 존재하기 때문에 노출될 경우가 없지만 (내부적인 개발자등은 제외) 일반 데스크탑 어플리케이션의 경우는 문제가 될 수 있다.

따라서 암/복호화가 필요하다. 다행이 System.Configuration 어셈블리에 이를 위한 메서드가 존재한다. 이런 기능을 제공하는 SectionInformation 클래스에 대해서 알아보도록 하자.
  • ProtectSection - 암호화
  • UnprotectSection - 복호화
[ 암호화 : ProtectSection ]

Section을 암호화하는 것으로 다음과 같은 형식으로 사용한다.

public void ProtectSection(string protectionProvider)

기본적으로 제공하는 Protection Provider는 다음과 같다.
  • DpapiProtectedConfigurationProvider - Windows 에서 기본 제공되는 암호화 서비스를 사용하며, PC 별 보호기능이나 사용자 계정별 보호기능을 사용하도록 구성할 수 있다. PC별 보호기능은 익명 서비스에는 유용하지만 보안 수준이 낮고, 사용자 계정별 보호기능은 특정 사용자 ID로 실행되는 서비스에 사용할 수 있다.
  • RsaProtectedConfigurationProvider - 구성파일에 민감한 정보를 암호화할 수 있으므로 무단으로 액세스하는 것을 방지할 수 있다.
암호화 처리는 다음과 같이 처리하면 된다.
// open configuration file
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

// get specific section
ConfigurationSection section = config.ConnectionStrings;

// 암호화
if (section != null) {
if (!section.SectionInformation.IsProtected && !section.ElementInformation.IsLocked) {
section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
section.SectionInformation.ForeceSave = true;
config.Save(ConfigurationSaveMode.Full);
}
}

위의 코드에서 ProtectSection 메서드가 실제 암호화를 처리하는 부분인데 주의할 점은 실제 Provider는 "DpapiProtectedConfigurationProvider" 지만 파라미터로 지정할 때는 "DataProtectionConfigurationProvider" 로 지정하여야 한다.  이 처리 과정을 거치고 나면 아래의 그림과 같이 Section 전체가 암호화된 코드로 나타나게 된다.


문제는 "DpapiProtectedConfigurationProvider" 를 "RsaProtectedConfigurationProvider" 로 변경하면 발생하는데 아래의 그림과 같이 오류가 발생하게 된다.


이런 오류가 발생하는 이유는 XP 이상부터 존재하는 UAC (User Account Control) 때문이다. 처리 과정 중에 권한 상승이 필요한데, 권한이 없어서 발생하는 것이다. 권한을 제대로 상승 (관리자 권한으로 실행)을 하고 처리를 수행한 결과는 아래의 그림과 같다.


위에서 보았던 암호화의 결과와는 다른 것을 볼 수 있다. Section 전체가 암호화된 것은 맞지만 내용이 Rsa Key 등의 관리적인 부분이 세분화되어 있는 것을 확인할 수 있다.

어떤 것을 선택할지는 알아서...

[ 복호화 : UnProtectSection ]

암호화된 것을 읽기 위해서는 아래의 코드와 같이 처리를 해 주어야 한다.
// open configuration file
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

// get specific section
ConfigurationSection section = config.ConnectionStrings;

// 복호화
if (section != null) {
if (section.SectionInformation.IsProtected) {
section.SectionInformation.UnprotectedSection();
section.SectionInformation.ForceDeclaration(true);
section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
}
}

위의 코드로 처리를 하면 아래의 그림과 같이 처리된 것을 확인할 수 있다.


이미 암호화된 정보를 통해서 어떤 Provider가 사용되었는지를 알 수 있기 때문에 별도의 Provider 설정은 필요가 없다.

복호화할 때 잊지 말아야 할 부분은 RsaProtectedConfigurationProvider를 사용한 경우는 RSA 방식에 맞춰야 하기 때문에 개인키가 없다면 당연히 복구 자체가 불가능하다.

그외 더 많은 정보가 필요하면 여기를 확인해 보면 된다.

댓글