CloudFront Signed URL

FGPRJS·2023년 1월 12일

다음 링크를 참조하여 Signed URL을 작성한다.

주의 사항

암호화 방식 관련

OpenSSL 3.0버전에서는 PKCS#8이 기준이다.

OpenSSL 3.0 버전에서 다음과 같은 명령어는 PKCS#8 Key를 만든다.

openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout -out public.key

하지만, .NET CloudFront 라이브러리에서 사용하는 CloudFront 라이브러리는 PKCS#1 키를 요구한다.
PKCS#1 키가 아닌 경우, 다음과 같은 오류를 발생시킨다.

Amazon.Runtime.AmazonClientException: Invalid RSA Private Key
 ---> System.Exception: Unknown primitive tag
   at ThirdParty.BouncyCastle.Asn1.Asn1InputStream.CreatePrimitiveDerObject(Int32 tagNo, Byte[] bytes)

다음과 같은 명령여를 통해 PKCS#1 Key를 만들어야 한다.

openssl genrsa -out private.key -traditional 2048
openssl rsa -in private.key -pubout -out public.key -traditional
  • Signed Url은 1개의 파일만 대상으로 할 수 있다.
  • 여러개의 파일, 혹은 폴더 하위를 대상으로 하려면 Cookie를 사용해야 한다.
    • 특히, 여러개의 파일을 대상으로 하려면 Custom Policy를 사용해야 한다.
    • Signed Cookie를 요청하면, 어떤 내용(Cookie-Policy, Cookie-Key-Pair-Id 등)이 들어있는 객체를 받을 수 있는데, 발송할 CloudFront의 Request에 Cookie를 넣어서 발송해야 한다.

C#의 경우, 작동하는 코드의 일부 예시

var signedCookie = AmazonCloudFrontCookieSigner.GetCookiesForCustomPolicy(
	@"{CloudFront distribution URL}/*(If using wildcard, should use Custom Policy)",
    new StreamReader(@"PKCS#1 Private Key file.(PEM)"),
    "Key-Pair-Id",
    DateTime.Now.AddHours(1),
    DateTime.Now.AddHours(-1),
    "0.0.0.0/0"
    );

var newClientHandler = new HttpClientHandler();

var cookieDomain = "{CloudFront distribution URL}";

newClientHandler.CookieContainer.Add(
  new Cookie(signedCookie.Policy.Key, signedCookie.Policy.Value)
  {
  	 Domain = cookieDomain
  });

newClientHandler.CookieContainer.Add(
  new Cookie(signedCookie.KeyPairId.Key, signedCookie.KeyPairId.Value)
  {
  	 Domain = cookieDomain
  });
newClientHandler.CookieContainer.Add(
  new Cookie(signedCookie.Signature.Key, signedCookie.Signature.Value)
  {
  	 Domain = cookieDomain
  });

var newClient = new HttpClient(newClientHandler);

var result = await newClient.GetAsync(@"{CloudFront distribution URL + File path}");

Console.WriteLine(result.StatusCode);

var resultString = await result.Content.ReadAsStringAsync();
profile
FGPRJS

0개의 댓글