[ASP.NET Core] Secret Manager를 통한 중요정보 보호

2016. 12. 20. 18:09WEB

이 내용은 https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets을 바탕으로 작성되었습니다. 모든 저작권은 원저자에게 있으며 요청이 있을 경우 언제든지 게시가 중단될 수 있습니다. 본 문서에는 오역이 포함되어 있을 수 있으며 번역된 내용에 대해서는 어떠한 일체의 보장을 하지 않습니다.

이 문서는 SecretManager 도구를 통해 코드에서 민감한 정보를 분리하는 방법에 대해 안내드립니다. 소프트웨어 개발 시 고려해야할 중요한 부분 중 하나는 절대 비밀번호나 민감한 정보를 소스코드에 저장해서는 안된다는 것이며, 제품이 릴리즈된 이후에 사용하게 될 정보들을 개발이나 테스트 단계에서 사용해서는 안됩니다. 대신에 운영체제의 환경변수 혹은 Secreet Manager 도구로부터 이러한 정보를 불러오도록 Configuration을 설정해야 합니다. Secret Manager 도구는 민감한 정보들이 Source Control System으로 체크인되지 않도록 도와줍니다. Secret Manager 도구를 사용하여 저장된 정보들은 Configuration을 통해 로드하실 수 있습니다.

환경변수 (Environment variables)

민감한 정보를 소스코드나 로컬설정파일에 저장하지 않고 환경변수에 저장할 수 있습니다. ASP.NET Core 어플리케이션에서 AddEnvironmentVariables 메서드를 호출함으로서 Configuration System이 환경변수에서 값을 읽을 수 있도록 설정할 수 있습니다. 이를 통해 민감한 정보들을 환경변수에 저장하고 환경변수에서 읽어올 수 있습니다.

예를들어 ASP.NET Core Wep App 프로젝트를 Individual User Account 유형으로 생성하면 프로젝트는DefaultConnectionString을 appSettings.json파일에 DefaultConnection이라는 key로 저장하게 됩니다. DefaultConnectionString은 LocalDB을 사용하기 위한 설정정보 입니다. LocalDB는 UserMode에서 동작하며 비밀번호를 요구하지 않습니다. 만약 개발된 Web App을 테스트하거나 릴리즈 하기 위해 배포를 하게 된다면 DB접속을 위한 민감한 인증정보를 설정해야 합니다. 이러한 경우 DefaultConnection 값을 환경변수에서 읽어오도록 설정한 후 DB인증정보를 테스트 서버나 릴리즈서버의 환경변수에 저장해두면 Web App은 운영체제의 환경변수에서 DefaultConnection 값을 읽어들이게 될 것입니다.

주의
환경변수는 운영체제에서 관리하며, 암호화되지 않은 순수한 텍스트로 저장되게 됩니다. 만약 운영체제나 프로세스가 보안에 취약하다면 환경변수는 공격자에 의해 탈취될 수 있습니다. 따라서 환경변수 정보의 유출을 막기 위해 추가적인 보안수단이 필요합니다.

Secret Manager

Secret Manager 도구는 개발과 관련된 민감한 정보들이 프로젝트의 외부에 저장할 수 있도록 좀더 일반적인 장치를 제공합니다. Secret Manager 도구는 프로젝트 도구로서 .NET Core 개발 중에 민감한 정보들을 저장하는데 사용될 수 있습니다. Secret Manager 도구와 함께 앱과 관련된 민감한 정보를 특정한 프로젝트와 연관시킬 수 있으며, 이러한 정보를 여러 프로젝트에 공유할 수 있습니다.

주의
Secret Manager 도구는 저장된 정보를 암호화하지 않기 때문에 Secret Manager를 신뢰할 수 있는 저장소로 간주해서는 안됩니다. Secret Manager도구는 개발 환경으로만 한정해야 합니다. Key와 Value는 사용자 프로파일 디렉터리의 JSON 설정파일에 저장되기 때문입니다.

Secret Manager 도구 설치

  • project.json 파일을 열고 tools 섹션에 Microsoft.Extensions.SecretManager.Tools를 추가해주세요. 그리고 donet restore를 실행해주세요.
  • 아래 명령어를 실행하여 Secret Manager 도구를 테스트 해보세요.
    dotnet user-secrets -h

Secret Manager 도구는 Usage, Options, Command Help 정보를 출력할 것입니다.

Secret Manager 도구는 사용자 프로파일에 저장된 설정정보 위에서 동작합니다. User Secret를 사용하기 위해 프로젝트는 반드시 userSecretsId값을 project.json파일에 정의해야 합니다. userSecretsId 값은 임의로 지정하실 수 있지만 일반적으로 프로젝트마다 고유한 값을 사용합니다.

  • userSecretsId를 프로젝트의 project.json 파일에 추가해주세요
    {
       "userSecretsId": "aspnet-WebApp1-c23d27a4-eb88-4b18-9b77-2a93f3b15119",
       "dependencies": {
  • Secret Manager 도구를 사용하여 값을 저장해주세요. 예를들어 프로젝트 디렉토리의 Command Window에서 다음 명령어를 입력하세요.
    dotnet user-secrets set 시크릿이름 시크릿값

다른 디렉터리에서 Secret Manager 도구를 사용할 수 있지만 반드시 --project 옵션을 사용하여 해당 프로젝트의 project.json 파일 경로를 제공해야 합니다.

dotnet user-secrets set 시크릿이름 시크릿값 --project c:\projects\AspNetCoreWebApp\src\webapp

Secret Manager 도구를 사용하여 저장된 내역을 출력하거나, 삭제하거나, 초기화 하실 수도 있습니다.

저장된 시크릿정보를 Configuration을 통해 접근하기

위에서 Secret Manager 도구를 사용하여 저장한 시크릿이름, 시크릿값을 Configuration을 통해 조회할 수 있습니다. 먼저 Microsoft.Extensions.Configuration.UserSecrets를 project.json의 dependency 섹션에 추가하고 dotnet restore 명령을 실행해주세요.

 "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc2-final",

프로젝트의 Startup 메서드에 UserSecrets 설정 코드를 추가해주세요.

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

    if (env.IsDevelopment())
    {
        builder.AddUserSecrets();
    }

    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

이제 Configuration을 통해 저장된 시크릿에 접근하실 수 있습니다.

string testConfig = Configuration["시크릿이름"];

Secret Manager 도구는 어떻게 동작하는가

Secret Manager 도구는 값의 저장위치와 방법에 대한 상세 구현을 추상화합니다. 따라서 구현에 대해 몰라도 Secret Manager 도구를 사용하실 수 있습니다. 현재 버전에서 값은 JSON파일로 유저 프로파일 폴더에 저장됩니다.

  • Windows: %APPDATA%\microsoft\UserSecrets\<userSecretsId>\secrets.json
  • Linux: ~/.microsoft/usersecrets/<userSecretsId>/secrets.json
  • Mac: ~/.microsoft/usersecrets/<userSecretsId>/secrets.json

userSecretsId 값은 project.json에 정의한 값을 사용 합니다.

Secret Manager도구를 통해 저장된 값의 구조나 위치에 대한 추가적인 코드를 작성하지 않는 것이 좋습니다. 이러한 상세한 구조에 대해서는 추후 변경될 수 있기 때문입니다. 예를들어 현재는 값을 암호화하지 않지만 언젠가는 값을 암호화 할 수 있기 때문입니다.