Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 10개 있습니다.)
개발 환경 구성: 555. openssl - CA로부터 인증받은 새로운 인증서를 생성하는 방법
; https://www.sysnet.pe.kr/2/0/12570

개발 환경 구성: 565. PowerShell - New-SelfSignedCertificate를 사용해 CA 인증서 생성 및 인증서 서명 방법
; https://www.sysnet.pe.kr/2/0/12588

개발 환경 구성: 654. openssl - CA로부터 인증받은 새로운 인증서를 생성하는 방법 (2)
; https://www.sysnet.pe.kr/2/0/13187

개발 환경 구성: 662. openssl - 윈도우 환경의 명령행에서 SAN 적용하는 방법
; https://www.sysnet.pe.kr/2/0/13235

개발 환경 구성: 663. openssl을 이용해 인트라넷 IIS 사이트의 SSL 인증서 생성
; https://www.sysnet.pe.kr/2/0/13236

개발 환경 구성: 681. openssl - 인증서 버전(V1 / V3)
; https://www.sysnet.pe.kr/2/0/13371

개발 환경 구성: 686. 비주얼 스튜디오로 실행한 ASP.NET Core 사이트를 WSL 2 인스턴스에서 https로 접속하는 방법
; https://www.sysnet.pe.kr/2/0/13442

개발 환경 구성: 687. OpenSSL로 생성한 사용자 인증서를 ASP.NET Core 웹 사이트에 적용하는 방법
; https://www.sysnet.pe.kr/2/0/13443

Linux: 62. 리눅스/WSL에서 CA 인증서를 저장하는 방법
; https://www.sysnet.pe.kr/2/0/13445

닷넷: 2162. ASP.NET Core 웹 사이트의 SSL 설정을 코드로 하는 방법
; https://www.sysnet.pe.kr/2/0/13447




openssl - CA로부터 인증받은 새로운 인증서를 생성하는 방법 (2)

지난번에 정리한 글이,

openssl - CA로부터 인증받은 새로운 인증서를 생성하는 방법
; https://www.sysnet.pe.kr/2/0/12570

CA 인증서가 있는 상태로 가정해서 쓴 것이라 새로 실습하기에 매끄럽지 않아서 다시 정리합니다. ^^




여러분이 VeriSign처럼 인증서 장사를 시작한다고 가정을 해볼까요? ^^

그럼, 여러분이 CA(Certificate Authority)가 되어야 하고 이에 따라 루트 인증서가 있어야 합니다. 그리고 인증서를 만들기 위한 기본 재료가 바로 "개인키"인데요, openssl을 이용하면 아래와 같이 옵션 조합에 따라 개인키와 인증서를 한꺼번에 만들 수 있습니다.

// test_ca.key 파일에 개인키, test_ca.crt에 (공개키를 담은) 인증서 생성
// 참고: Unable to load config info from ...

C:\temp> openssl req -newkey rsa:2048 -nodes -keyout test_ca.key -x509 -days 365 -out test_ca.crt
Generating a RSA private key
................................+++++
..................+++++
writing new private key to 'test_ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:testca
Email Address []:

참고로, 위에서는 1개의 명령어로 개인 키와 인증서를 생성했지만 다음과 같이 나눠서 하는 것도 가능합니다.

// 1) 개인키를 생성하고,
C:\temp> openssl genrsa -out test_ca.key 2048
...[생략]...

// 2-1) 위의 명령어로 생성한 개인키를 이용해 인증서를 생성하거나,
// 2-2) 별도로 소유하고 있는 개인키가 이미 있다면 1번 과정을 생략하고 기존 키로 인증서를 생성
C:\temp> openssl req -x509 -new -nodes -key test_ca.key -sha256 -days 1825 -out test_ca.crt
...[생략]...

생성된 crt 파일은 공개키를 담은 인증서 파일입니다. (윈도우 환경에서) 이렇게 생성한 test_ca.crt를 더블클릭하면 다음과 같이 인증서가 올바르지 않다는 "X" 마크를 볼 수 있습니다.

how_to_use_ca_cert_1.png

왜냐하면 위의 화면에 나온 메시지에서처럼,

This CA Root certificate is not trusted. To enable trust, install this certificate in the Trusted Root Certification Authorities store.


해당 인증서는 파일로만 존재할 뿐이어서, 이런 상태로는 윈도우 시스템이 해당 인증서를 신뢰하지 않기 때문입니다. 메시지에도 나오지만, 이 인증서를 신뢰하도록 만들고 싶다면 시스템에 명시적으로 등록하는 과정을 거쳐야 합니다.

이를 위해 시작 메뉴의 검색에 "cert"라고 입력하면 아래 화면과 같이,

how_to_use_ca_cert_2.png

  1. Manage computer certificates
  2. Manage user certificates

인증서 관리 콘솔이 검색됩니다. 첫 번째는 "SYSTEM" 레벨에서 관리될 인증서로 주로 로그인하지 않은 계정, 일례로 NT 서비스들이 접근할 수 있는 인증서를 담는 보관소를 대상으로 합니다. 두 번째는 "로그인 중인 사용자" 계정이 접근할 수 있는 인증서 보관소를 관리합니다.

인증서와 관련 있는 대표적인 응용 프로그램으로는, IIS 서비스의 웹 서비스가 있는데 이런 것들은 "로그인 중인 사용자"와 무관하므로 "SYSTEM" 레벨에 등록해야 합니다.

여기서는, "Manage computer certificates"를 선택해 다음과 같이,

how_to_use_ca_cert_3.png

"Trusted Root Cerfitication" 항목의 하위에 있는 "Certificates"를 우클릭, "All Tasks" / "Import..."를 선택해 test_ca.crt 파일을 선택합니다. 일단 이렇게 등록이 되면, 이후로 시스템은 해당 인증서를 유효하다고 판정하므로 다음과 같이 "This certificate is OK"라는 메시지를 보게 됩니다.

how_to_use_ca_cert_4.png

여기까지 했으면, 이제 여러분도 어엿한 CA로서 행세할 수 있습니다. 단지, 여러분과 VeriSign의 차이라면 마이크로소프트가 기본적으로 여러분을 신뢰할 수는 없어 "인증서 관리자"에 여러분의 인증서를 포함시켜 주지는 않는다는 점입니다. 반면, "Trusted Root Cerfitication" 항목을 보면, "VeriSign"을 비롯해 우리가 익히 알고 있는 공인된 인증 기관(CA)들의 인증서가 등록된 것을 볼 수 있습니다.

그 외에는 차이점이 없습니다. 오직 저 한 가지의 차이점만 있는 것인데요, 그래도 은근히 저 차이점으로 인한 '장벽'이 좀 높습니다. 왜냐하면 마이크로소프트가 기본적으로 포함해 주지 않기 때문에 "일반 사용자"는 개별적으로 여러분의 인증서를 위에 설명한 방법과 같이 직접 등록해 줘야 하는 과정을 거쳐야 하기 때문입니다. (물론, 코드로도 가능합니다.)




이제 입장을 바꿔볼까요? ^^ 여러분은 CA 업체가 아닌, 그 CA 업체에 인증서를 서명 받고 싶은 사용자라고 가정해 보겠습니다.

마찬가지로 여러분에게는 고유의 개인키가 하나 있어야 합니다. 따라서 이전에 설명했던 것과 같은 방법으로 개인키를 생성하면 됩니다.

C:\temp> openssl genrsa -out pp_app.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
...+++++
..............................................................................................+++++
e is 65537 (0x010001)

그런 다음, 이 개인키를 바탕으로 "인증서 요청" 파일을 생성합니다.

c:\temp> openssl req -key pp_app.key -new -out pp_app.csr

위의 과정으로 생성한 pp_app.csr은 다음과 같은 내용을 갖는데요,

-----BEGIN CERTIFICATE REQUEST-----
MIICozCCAYsCAQAwXjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
...[생략]...
dffpjAc4Xw==
-----END CERTIFICATE REQUEST-----

csr 파일은 여러분의 공개키를 담은 인증서에 해당합니다. 이 파일을 이제 CA 기관에 제출하면 되는데요, 그럼 CA 측에서는 csr 파일을 CA의 개인키로 서명한 내용을 담은 완전한 유형의 인증서 파일을 생성해 보내줄 것입니다.

그게 끝입니다. 여러분은 그렇게 해서 받은 인증서로 HTTPS 서비스를 하든가, 소프트웨어 서명을 하는데 사용하는 것입니다. (참고로, 인증서의 용도에 따라 비용이 다릅니다.)




마지막으로, 위에서 생략한 부분을 마저 설명해야겠지요? ^^ 즉, 사용자로부터 전달받은 csr 파일을 CA 측에서는 가지고 있던 개인키 파일로 서명하는 작업이 남았는데요, 대략 다음과 같이 해주면 됩니다.

C:\temp> openssl x509 -req -days 3650 -in pp_app.csr -CA test_ca.crt -CAkey test_ca.key -CAcreateserial -out pp_app.crt

위의 명령어로 생성한 pp_app.crt 인증서 파일을 고객 측에게 보내주면 됩니다.

여기까지가 CA 업체의 굵직한 업무를 요약한 것입니다. ^^ 물론, 저 과정에는 한 가지 작업이 빠져 있긴 합니다. 실제 인증 기관은 여러분의 CSR 파일뿐만 아니라, CA가 서명해야 할 대상이 누구인지 확실히 알 수 있는 증명서, 즉 해당 기업이 실제 존재함을 알 수 있는 서류를 요구합니다. 보통 "사업자 등록증" 등의 서류가 필요합니다. 그럼, CA 인증 기관은 해당 서류들을 확인하고 실제 대상임을 확인했으면 그제야 CA의 개인키로 CSR 파일을 서명해 CRT 인증서를 생성해 보내주는 것입니다.

어떠세요? 여러분도 CA 인증 사업에 도전해 볼 수 있지 않을까요? ^^

(기타, CRL 관리와 같은 자잘한 업무가 더 있긴 합니다. ^^)




무료 SSL 인증서로 "Let's Encrypt"를 들어보셨을 것입니다.

"Let's Encrypt"에서 제공하는 무료 SSL 인증서를 IIS에 적용하는 방법 (1)
; https://www.sysnet.pe.kr/2/0/10958

"Let's Encrypt"에서 제공하는 무료 SSL 인증서를 IIS에 적용하는 방법 (2)
; https://www.sysnet.pe.kr/2/0/11483

저것 역시 기반은 위에서 설명한 것과 같습니다. 단지 서류를 요구하지 않는다는 차이가 있는데요, 왜냐하면 HTTPS 서비스의 경우 오고 가는 패킷의 위/변조/도청을 막는 것이 중요할 뿐, 서비스를 제공하는 측의 신원이 중요하지 않은 웹 서비스가 많기 때문입니다. 일례로, 저처럼 개인 블로그를 운영하는 경우 https 서비스를 위해 VeriSign 측에 해마다 비용을 지불하며 인증서 서명을 받기에는 부담이 있습니다.

그런 와중에 "Internet Security Research Group"에서 고맙게도 무료로 "Let's Encrypt" 서비스를 해주고 있는 것입니다.

반면, "소프트웨어 인증서"는 무료가 없습니다. 왜일까요?

윈도우 운영체제의 경우, 경우에 따라 소프트웨어 인증서를 요구하기도 합니다. 왜냐하면, 소프트웨어가 워낙 위/변조가 심한 분야다 보니 그것을 막기 위해 바이너리의 내용을 개인키로 서명하고, 그 서명한 내용을 검증하기 위해 공개키를 담은 인증서를 함께 실행 파일에 포함시켜 "신뢰도"를 가늠하기 때문입니다.

예를 들어, 여러분이 "adobe" 소프트웨어를 친구에게서 복사해 왔다고 가정해 보겠습니다. 여기서 문제는, 과연 그 파일들에 크래커가 심어놓은 악성코드가 심어져 있는지 알 수 있는 방법이 없다는 점입니다. 그런 경우 만약 서명이 되어 있다면, 파일의 위/변조 여부를 쉽게 알 수 있습니다. 하지만 여기에도 또 다른 문제가 있습니다. 즉, 악성코드를 심어놓은 크래커가 자신들이 가지고 있는 개인키로 서명하는 것도 가능하기 때문입니다.

그래서 마이크로소프트는, 신뢰할 수 있는 "인증 기관"에 한해 미리 그들의 "루트 인증서"를 시스템에 등록해 줍니다. 이를 통해, (어둠에 묻혀 있고 싶은 크래커들은) "인증 기관"에 서류를 내 자신들이 누구인지 밝히고 싶지 않을 것이므로 그들의 자체 서명 인증서는 기본적으로 윈도우의 신뢰를 얻지 못합니다.

이러한 신뢰의 문제는 경우에 따라 CA 기관에도 적용됩니다. 실제로 간혹 특정 "인증 기관"이 더 이상 신뢰할 수 없는 상태라 퇴출당했다는 소식이 들리곤 합니다.

中 치후360 자회사, 세계 인증서 시장서 퇴출된다
; https://zdnet.co.kr/view/?no=20170816151244

이것을 달리 말하면, 여러분이 이 글에서 읽은 ^^ 내용에 따라 인증 기관 사업을 하고 싶다면, 산업계에서 인정할 만한 "신뢰성" 요건을 충족해야 한다는 것을 의미합니다. 아마... 쉽진 않겠죠? ^^ 이런 이유로 인해 서류를 받지 않는 Let's Encrypt가 소프트웨어 서명만큼은 해주지 않는 것입니다. (만약 서류 없이 그런 인증서를 발급했다면 퇴출당했을 것입니다.)

참고로, 정식으로 서명 받은 소프트웨어 인증서조차도 문제가 되는 경우가 가끔 있습니다. 일례로 소프트웨어 개발자의 개인키가 크래커들에게 털리는 경우가 있었는데요,

'코드사인 탈취' 어떻게 대응해야 하나?
; https://www.boannews.com/media/view.asp?idx=50454

Samsung’s Android app-signing key has leaked, is being used to sign malware
; https://arstechnica.com/gadgets/2022/12/samsungs-android-app-signing-key-has-leaked-is-being-used-to-sign-malware/

그렇다면 엄연히 해당 인증서는 정식 인증서이므로 오히려 더 위험한 사태를 유발할 수 있는 것입니다. 혹은, 겨우 인증서를 받을 수 있는 요건만 갖춘 유령 회사를 만드는 것도 가능하기 때문에 점점 더 소프트웨어 인증서가 믿을 수 없게 돼버렸습니다.

이로 인한 보완으로 윈도우의 경우 단순히 서명된 소프트웨어를 신뢰하기보다는 다수의 사용자가 다운로드해 사용하는 것도 함께 신뢰도에 반영하는 등의 까다로운 요건을 결합한 "스마트 스크린"이 나오게 된 것입니다. 또는 가격이 더 높아진 EV 인증서도 있고.




마지막으로, CA 측에서 사용자의 인증서를 서명하는 작업에 conf 파일을 이용하면 좀 더 쉽게 옵션을 줄 수 있습니다. conf 파일을 이용해 인증서의 옵션을 제어하는 방법은 이미 설명한 적이 있는데요, 이번 글에서는 추가로 "extendedKeyUsage"를 살펴보겠습니다. ^^

지난 글에서, PP/PPL 보안은,

윈도우의 Protected Process (Light) 보안
; https://www.sysnet.pe.kr/2/0/13169

EKU에 4개의 항목이 더 추가된 인증서를 사용하게 되는데요,

make_pl_ppl_1.png

  • Protected Process Light Verification (1.3.6.1.4.1.311.10.3.22)
  • Windows TCB Component (1.3.6.1.4.1.311.10.3.23)
  • Windows System Component Verification (1.3.6.1.4.1.311.10.3.6)
  • Code Signing (1.3.6.1.5.5.7.3.3)

이런 용도를 추가하는 것은 conf 파일에 다음과 같은 설정을 추가하면 됩니다.

# pp_app.cnf

FQDN = testapp
ALTNAMES = DNS:vm.docker.internal,DNS:localhost,IP:10.96.0.1,IP:0.0.0.0

[ req ]
default_bits = 2048
default_md = sha256
prompt = no
encrypt_key = no
distinguished_name = dn
req_extensions = req_ext

[ dn ]
CN = $FQDN

[ req_ext ]
extendedKeyUsage = serverAuth
subjectAltName = $ALTNAMES
keyUsage = digitalSignature,keyEncipherment

[ x509_ext ]
extendedKeyUsage = serverAuth,1.3.6.1.4.1.311.10.3.22,1.3.6.1.4.1.311.10.3.23,1.3.6.1.4.1.311.10.3.6,1.3.6.1.5.5.7.3.3
authorityKeyIdentifier = keyid,issuer
subjectAltName = $ALTNAMES
keyUsage = digitalSignature,keyEncipherment

이런 설정으로 인증서를 서명해 주면,

C:\temp> openssl req -key pp_app.key -new -out pp_app.csr -config pp_app.cnf

C:\temp> openssl x509 -extfile pp_app.cnf -extensions x509_ext -req -days 3650 -in pp_app.csr -CA test_ca.crt -CAkey test_ca.key -CAcreateserial -out pp_app.crt

pp_app.crt 인증서에도 EKU에 4개의 용도가 추가된 것을 확인할 수 있습니다. 참고로, 이렇게 만들어진 인증서로 소프트웨어를 서명하려면 공개키만 담은 인증서가 아닌, "개인키까지 담은 인증서"를 생성해 등록해야 합니다. 이를 위해 개인키와 함께 CA로부터 서명 받은 인증서를 openssl로 합쳐,

// 개인키(.key) + 공개키 인증서(.crt) ==> PFX 파일 생성

C:\temp> openssl pkcs12 -export -out pp_app.pfx -inkey pp_app.key -in pp_app.crt

만들어진 pp_app.pfx 인증서를 시스템에 등록하면 됩니다. 이후, 소프트웨어 서명은 이런 식으로 진행하는데,

c:\temp> signtool sign /fd SHA256 /v /sm /n "testapp" ConsoleApp1.exe
The following certificate was selected:
    Issued to: testapp
    Issued by: testca
    Expires:   Thu Nov 25 10:55:06 2032
    SHA1 hash: FC34EC3A93141E1946F284EAEDD39401704013FA

Done Adding Additional Store
Successfully signed: ConsoleApp1.exe

Number of files successfully Signed: 1
Number of warnings: 0
Number of errors: 0

혹시 저처럼 PP/PPL 프로세스를 만들고 싶은 분을 위해 미리 말씀드리면 저렇게 인증서 용도가 추가되었다고 해서 PP/PPL이 되는 것은 아닙니다. 이에 대한 자세한 방법은 다음의 글에 소개되고 있으니 이것을 참조하시면 됩니다. ^^

Protecting anti-malware services
; https://learn.microsoft.com/en-us/windows/win32/services/protecting-anti-malware-services-





[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 1/29/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




1  2  3  4  5  6  7  8  9  10  11  12  13  14  [15]  ...
NoWriterDateCnt.TitleFile(s)
13245정성태2/6/20234618.NET Framework: 2093. C# - PEM 파일을 이용한 RSA 개인키/공개키 설정 방법파일 다운로드1
13244정성태2/5/20233976VS.NET IDE: 179. Visual Studio - External Tools에 Shell 내장 명령어 등록
13243정성태2/5/20234845디버깅 기술: 190. windbg - Win32 API 호출 시점에 BP 거는 방법 [1]
13242정성태2/4/20234282디버깅 기술: 189. ASP.NET Web Application (.NET Framework) 프로젝트의 숨겨진 예외 - System.UnauthorizedAccessException
13241정성태2/3/20233815디버깅 기술: 188. ASP.NET Web Application (.NET Framework) 프로젝트의 숨겨진 예외 - System.IO.FileNotFoundException
13240정성태2/1/20233981디버깅 기술: 187. ASP.NET Web Application (.NET Framework) 프로젝트의 숨겨진 예외 - System.Web.HttpException
13239정성태2/1/20233623디버깅 기술: 186. C# - CacheDependency의 숨겨진 예외 - System.Web.HttpException
13238정성태1/31/20235625.NET Framework: 2092. IIS 웹 사이트를 TLS 1.2 또는 TLS 1.3 프로토콜로만 운영하는 방법
13237정성태1/30/20235285.NET Framework: 2091. C# - 웹 사이트가 어떤 버전의 TLS/SSL을 지원하는지 확인하는 방법
13236정성태1/29/20234954개발 환경 구성: 663. openssl을 이용해 인트라넷 IIS 사이트의 SSL 인증서 생성
13235정성태1/29/20234480개발 환경 구성: 662. openssl - 윈도우 환경의 명령행에서 SAN 적용하는 방법
13234정성태1/28/20235522개발 환경 구성: 661. dnSpy를 이용해 소스 코드가 없는 .NET 어셈블리의 코드를 변경하는 방법 [1]
13233정성태1/28/20236874오류 유형: 840. C# - WebClient로 https 호출 시 "The request was aborted: Could not create SSL/TLS secure channel" 예외 발생
13232정성태1/27/20234692스크립트: 43. uwsgi의 --processes와 --threads 옵션
13231정성태1/27/20233605오류 유형: 839. python - TypeError: '...' object is not callable
13230정성태1/26/20234018개발 환경 구성: 660. WSL 2 내부로부터 호스트 측의 네트워크로 UDP 데이터가 1개의 패킷으로만 제한되는 문제
13229정성태1/25/20234961.NET Framework: 2090. C# - UDP Datagram의 최대 크기
13228정성태1/24/20235102.NET Framework: 2089. C# - WMI 논리 디스크가 속한 물리 디스크의 정보를 얻는 방법 [2]파일 다운로드1
13227정성태1/23/20234810개발 환경 구성: 659. Windows - IP MTU 값을 바꿀 수 있을까요? [1]
13226정성태1/23/20234467.NET Framework: 2088. .NET 5부터 지원하는 GetRawSocketOption 사용 시 주의할 점
13225정성태1/21/20233738개발 환경 구성: 658. Windows에서 실행 중인 소켓 서버를 다른 PC 또는 WSL에서 접속할 수 없는 경우
13224정성태1/21/20234074Windows: 221. Windows - Private/Public/Domain이 아닌 네트워크 어댑터 단위로 방화벽을 on/off하는 방법
13223정성태1/20/20234271오류 유형: 838. RDP 연결 오류 - The two computers couldn't connect in the amount of time allotted
13222정성태1/20/20233930개발 환경 구성: 657. WSL - DockerDesktop.vhdx 파일 위치를 옮기는 방법
13221정성태1/19/20234150Linux: 57. C# - 리눅스 프로세스 메모리 정보파일 다운로드1
13220정성태1/19/20234281오류 유형: 837. NETSDK1045 The current .NET SDK does not support targeting .NET ...
1  2  3  4  5  6  7  8  9  10  11  12  13  14  [15]  ...