.NET Core 의 데이터 보호 구성 요 소 를 자세히 설명 합 니 다.

9801 단어 .NETCore
배경 설명
OWASP(오픈 웹 애플 리 케 이 션 보안 프로젝트)가 2013 년 에 발표 한 보고서 에서 안전 하지 않 은 직접 대상 참조(Insecure Direct Object Reference)를 10 대 웹 애플 리 케 이 션 리 스 크 중 하나 로 표시 하고 그 표현 형식 은 대상 의 참조(예 를 들 어 데이터베이스 메 인 키)가 각종 악의 적 인 공격 에 의 해 이용 되 기 때문에 Api 가 되 돌아 오 는 각종 메 인 키 외부 키 ID 에 대해암호 화가 필요 합 니 다.
.NET Core 의 데이터 보호 구성 요소
.NET Core 에는 IDataProtection Provider 인터페이스 와 IDataProtector 인터페이스 가 내장 되 어 있다.그 중에서 IDataProtection Provider 는 보호 구성 요 소 를 만 드 는 인터페이스 이 고 IDataProtector 는 데이터 보호 인터페이스 입 니 다.개발 자 는 이 두 개의 인 터 페 이 스 를 실현 하여 데이터 보호 구성 요 소 를 만 들 수 있다.
내 장 된 데이터 보호 구성 요소
.NET Core 에 서 는 기본적으로 데이터 보호 구성 요 소 를 제공 합 니 다.다음은 이 기본 구성 요 소 를 사용 하여 데 이 터 를 보호 하려 고 합 니 다.
예:현재 우 리 는 Movie 류 가 있 습 니 다.코드 는 다음 과 같 습 니 다.Movie 대상 을 가 져 올 때 Id 필드 는 암호 화 되 기 를 바 랍 니 다.

public class Movie
 {
  public Movie(int id, string title)
  {
   Id = id;
   Title = title;
  }

  public int Id { get; set; }
  public string Title { get; set; }
 }
우선 Startup.cs 에서 Configure Service 방법 에서 기본 데이터 보호 구성 요 소 를 설정 해 야 합 니 다.

public void ConfigureServices(IServiceCollection services)
 {
  services.AddMvc();
  services.AddDataProtection();
 }
이 코드 는.NET Core 의 기본 데이터 보호 기 를 사용 합 니 다.
그 다음 에 우 리 는 Movies Controller 를 만 들 고 구조 함수 에 IDataProtection Provider 대상 을 주입 한 다음 에 이 Provider 대상 을 사용 하여 IDataProtector 인 터 페 이 스 를 실현 하 는 데이터 보호 기 대상 을 만 듭 니 다.

[Route("movies")]
 public class MoviesController : Controller
 {
  private readonly IDataProtector protector;
 
  public MoviesController(IDataProtectionProvider provider)
  {
   this.protector = provider.CreateProtector("protect_my_query_string");
  }
 }
TIPS:Provider 를 사용 하여 Protector 를 만 들 때"protect"인자 가 들 어 왔 습 니 다.my_query_string",이 매개 변 수 는 이 보호 기의 용 도 를 표시 합 니 다.이 보호 기의 이름 으로 도 사용 할 수 있 습 니 다.
메모:서로 다른 용도 의 보호 기 는 상대방 의 암호 화 문자열 을 복호화 할 수 없습니다.보호 기 A 를 사용 하여 보호 기 B 에서 생 성 된 문자열 을 복호화 하면 다음 과 같은 이상 이 발생 합 니 다.Cryptographic Exception:The payload was invalid.
그리고 MovieController 에 Api 2 개 를 추가 합 니 다.하 나 는 모든 Movies 대상 을 가 져 오 는 것 이 고 하 나 는 지정 한 Movie 대상 을 가 져 오 는 것 입 니 다.

[HttpGet]
 public IActionResult Get()
 {
  var model = GetMovies();
  
  var outputModel = model.Select(item => new
  {
   Id = this.protector.Protect(item.Id.ToString()),
   item.Title,
   item.ReleaseYear,
   item.Summary
  });

  return Ok(outputModel);
 }

 [HttpGet("{id}")]
 public IActionResult Get(string id)
 {
  var orignalId = int.Parse(this.protector.Unprotect(id));

  var model = GetMovies(); 
  
  var outputModel = model.Where(item => item.Id == orignalId);

  return Ok(outputModel);
 }
코드 해석
  • Movie 목록 을 가 져 오 는 api 에서 우 리 는 IDataProtector 인터페이스의 Protect 방법 으로 Id 필드 를 암호 화 했다
  • 단일 Movie 대상 을 가 져 오 는 api 에서 우 리 는 IDataProtector 인터페이스의 Unprotect 방법 으로 Id 필드 를 복호화 해 야 합 니 다
  • 최종 효과
    우선/api/movies 를 호출 합 니 다.결 과 는 다음 과 같 습 니 다.id 필드 는 정확하게 암호 화 되 었 습 니 다.
    
    [{
     "id": "CfDJ8D9KlbQBeipPoQwll5uLR6ygyO6avkgI2teCQGZQShNwsxC9ApDdsnyYd1K5IyNHjhZcRoGd6W31se3W6TWM8H9UdLEPn4fJpS5uKkqUa0PMV6a0ZZHBQSnlGoisSnj29g",
     "title": "     "
    }, {
     "id": "CfDJ8D9KlbQBeipPoQwll5uLR6wkMUYyzflIzy3CwoMhcaO-np2WOy4czIL3WZd2FWi7Tsy119tDeFq7yAeye4o2W-KmbffpGXnTDZzNv2QbCrAm7-AyEN35g3pkfAYHa3X7aQ",
     "title": "   "
    }, {
     "id": "CfDJ8D9KlbQBeipPoQwll5uLR6x2AXM6ulCwts2-uQSfzIU8UquTz-OAZIl-49D5-CYYl5H4mfZH8VihhCBJ60MMrZOlZla9qvb8EIP6GYRkEap4nhktbzGxW0Qu5r3edm6_Kg",
     "title": "   "
    }, {
     "id": "CfDJ8D9KlbQBeipPoQwll5uLR6zDZeLtPIVlkRLCd_V6Mr2kTzWsCkfYgmS0-cqhFAOu4dUWGtx6d402_eKnObAOFUClEDdF4mrUeDQawE71DDa805umhbAvX2712i7UgYO5MA",
     "title": "   "
    }]
    그리고 우 리 는 api 를 계속 호출 하여 아 이언 맨 의 영화 정 보 를 조회 합 니 다.
    
    /api/movies/CfDJ8D9KlbQBeipPoQwll5uLR6zDZeLtPIVlkRLCd_V6Mr2kTzWsCkfYgmS0-cqhFAOu4dUWGtx6d402_eKnObAOFUClEDdF4mrUeDQawE71DDa805umhbAvX2712i7UgYO5MA
    결과 도 정확히 돌 아 왔 다.
    
    [{"id":4,"title":"   "}]
    만 료 된 데이터 보호 기(Limited Lifetime)
    .NET Core 는 기본적으로 만 료 된 시간 을 가 진 데이터 보호 기 를 제공 합 니 다.이런 데이터 보호 기 는 많은 장면 을 사용 합 니 다.가장 자주 사용 하 는 장면 은 암 호 를 리 셋 하 는 Token 에 실효 시간 을 설정 하 는 것 입 니 다.그러면 시간 이 초과 되면 Token 은 복호화 에 성공 하지 못 하고 암호 리 셋 작업 이 시간 을 초과 했다 고 인정 할 수 있 습 니 다.
    .NET Core 에 서 는 IDataProtector 인터페이스의 ToTime Limited DataProtector 방법 으로 만 료 된 시간 이 있 는 데이터 보호 기 를 만 들 수 있 습 니 다.
    여기 서 우 리 는 기본 값 을 사용 합 니까?아니면 위의 예 를 들 어 코드 를 다음 과 같이 수정 합 니까?
    
    private readonly ITimeLimitedDataProtector protector;
    
     public MoviesController(IDataProtectionProvider provider)
     {
      this.protector = provider.CreateProtector("protect_my_query_string")
         .ToTimeLimitedDataProtector();
     }
    
     [HttpGet]
     public IActionResult Get()
     {
      var model = GetMovies(); // simulate call to repository
      
      var outputModel = model.Select(item => new
      {
       Id = this.protector.Protect(item.Id.ToString(), 
              TimeSpan.FromSeconds(10)),
       item.Title,
       item.ReleaseYear,
       item.Summary
      });
    
      return Ok(outputModel);
     }
    코드 해석
    4.567917.여기 서 우 리 는 ITimeLimited DataProtector 인터페이스 대상 protector 를 정 의 했 고 구조 함수 에서 ToTimeLimited DataProtector 방법 을 사용 하여 일반 데이터 보호 기 를 만 료 시간 이 있 는 데이터 보호 기로 전환 했다
  • Movie 목록 을 가 져 오 는 api 에서 저 희 는 Protect 방법 으로 Id 필드 를 암호 화 합 니 다.이전 과 달리 두 번 째 TimeSpan 파 라 메 터 를 추 가 했 습 니 다.이 파 라 메 터 는 현재 암호 화의 유효 시간 이 10 초 밖 에 되 지 않 음 을 나타 냅 니 다
  • 최종 효과
    현재 프로젝트 를 다시 실행 하 는 것 은 이전 과 마찬가지 로/api/movies 방법 으로 Movies 목록 을 가 져 오 는 것 입 니 다.결 과 는 다음 과 같 습 니 다.
    
    [{
     "id": "CfDJ8D9KlbQBeipPoQwll5uLR6yzbDbZ931toH32VC6Jqg8DWsrmiLrOxOFFViH4QWZne43jwSVzBjzJIfctYKZniZKNVbr50RRIZpW2fe9UtPajEzBhI-H32Effm-F0ColUaA",
     "title": "     "
    }, {
     "id": "CfDJ8D9KlbQBeipPoQwll5uLR6zDDVymvftZK9lKBIjEyuoNTzOEu0SC2-qfTy6quXir2S8f3A1r44f9Yz3Sd_cyLZUp-_4gfJAasMfE8_ngYLrJmdsjN9LZ0g4vox0WJLjiGA",
     "title": "   "
    }, {
     "id": "CfDJ8D9KlbQBeipPoQwll5uLR6zL-M2jzv2HCeTiHjevkXvI2216NERplp43TOjCXtj4S52ll68sLyQNtG2FhhWlsOmFGvYY5G4gm5SKfASMMgE1jBr20xc2b_djWdLhWLIxnA",
     "title": "   "
    }, {
     "id": "CfDJ8D9KlbQBeipPoQwll5uLR6wAoZKCHTG0lvgYS3If_0_eAD30a2YV8RjNagwLXUdCSKsO3kyS58hqDqAPHw_KHwNpd-hjDFl3hFPa8LOWHyk901oc6ZuSxwzxFlljaVreFA",
     "title": "   "
    }]
    10 초 를 기다 린 후에 우 리 는 api 를 계속 호출 하여 아 이언 맨 의 영화 정 보 를 조회 합 니 다.
    
    /api/movies/CfDJ8D9KlbQBeipPoQwll5uLR6wAoZKCHTG0lvgYS3If_0_eAD30a2YV8RjNagwLXUdCSKsO3kyS58hqDqAPHw_KHwNpd-hjDFl3hFPa8LOWHyk901oc6ZuSxwzxFlljaVreFA
    오류 정 보 를 되 돌려 주 었 습 니 다.Cryptographic Exception:The payload expired at 9/29/2018 11:25:05 AM+00:00.이것 은 현재 암호 화의 유효기간 이 지 났 기 때문에 정확하게 복호화 할 수 없다 는 것 을 설명 합 니 다.
    Tips:Action Filter 복호화 파 라미 터 를 사용 합 니 다.
    이전 코드 에서 우 리 는 하나의 Movie 를 가 져 오 는 방법 에서 Unproctected 방법 으로 id 속성 을 복호화 합 니 다.
    
    [HttpGet("{id}")]
     public IActionResult Get(string id)
     {
      var orignalId = int.Parse(this.protector.Unprotect(id));
    
      var model = GetMovies(); // simulate call to repository
      
      var outputModel = model.Where(item => item.Id == orignalId);
    
      return Ok(outputModel);
     }
    다음은 액 션 필터 로 이 코드 를 개선 하 겠 습 니 다.
    우선 DecryptReferenceFilter 를 만 듭 니 다.코드 는 다음 과 같 습 니 다.
    
    public class DecryptReferenceFilter : IActionFilter
     {
      private readonly IDataProtector protector;
    
      public DecryptReferenceFilter(IDataProtectionProvider provider)
      {
       this.protector = provider.CreateProtector("protect_my_query_string");
      }
    
      public void OnActionExecuting(ActionExecutingContext context)
      {
       object param = context.RouteData.Values["id"].ToString();
       var id = int.Parse(this.protector.Unprotect(param.ToString()));
       context.ActionArguments["id"] = id;
      }
    
      public void OnActionExecuted(ActionExecutedContext context)
      {
    
      }
     }
    
     public class DecryptReferenceAttribute : TypeFilterAttribute
     {
      public DecryptReferenceAttribute() :
       base(typeof(DecryptReferenceFilter))
      { }
     }
    코드 해석
    여기 DecryptReference Filter 는 IAction Filter 인 터 페 이 스 를 실 현 했 고 OnAction Executing 과 OnAction Executed 방법 을 실 현 했 습 니 다
  • DecryptReference Filter 클래스 에서 우 리 는 기본 데이터 보호 기 제공 기 를 주입 하고 구조 함수 에서 데이터 보호 기 를 초기 화 했다
  • OnAction Executing 에서 RouteData 에서 복호화 되 지 않 은 id 필드 를 가 져 온 다음 복호화 한 후에 복호화 되 지 않 은 id 필드 를 교체 하면 ModelBinder 는 복호화 된 문자열 로 모델 을 연결 합 니 다
  • 최종 수정
    마지막 으로 하나의 Movie 를 가 져 오 는 api 를 수정 합 니 다.코드 는 다음 과 같 습 니 다.
    
    [HttpGet("{id}")]
     [DecryptReference]
     public IActionResult Get(int id)
     {
      var model = GetMovies();
    
      var outputModel = model.Where(item => item.Id == id);
    
      return Ok(outputModel);
     }
    하나의 Movie 를 가 져 오 는 방법 에 DecryptReference 기능 을 추 가 했 습 니 다.
    코드 를 실행 한 후 코드 는 이전의 효과 와 같다.
    원본 주소:http://xiazai.jb51.net/201809/yuanma/id_protector_jb51.rar

    좋은 웹페이지 즐겨찾기