etc./StackOverFlow

OpenSSL을 사용하여 자체 서명된 SSL 인증서를 생성하는 방법은 무엇입니까?

청렴결백한 만능 재주꾼 2022. 2. 17. 12:24
반응형

질문자 :michelemarcon


임베디드 Linux 장치에 HTTPS 지원을 추가하고 있습니다. 다음 단계에 따라 자체 서명된 인증서를 생성하려고 했습니다.

 openssl req -new > cert.csr openssl rsa -in privkey.pem -out key.pem openssl x509 -in cert.csr -out cert.pem -req -signkey key.pem -days 1001 cat key.pem>>cert.pem

이것은 작동하지만 예를 들어 Google Chrome에서 다음과 같은 몇 가지 오류가 발생합니다.

이것은 아마도 당신이 찾고 있는 사이트가 아닐 것입니다!
사이트의 보안 인증서를 신뢰할 수 없습니다!

내가 뭔가를 놓치고 있습니까? 자체 서명된 인증서를 빌드하는 올바른 방법입니까?



하나의 명령으로 수행할 수 있습니다.

 openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

암호로 개인 키를 보호하지 않으려면 -nodes no DES 약자)를 추가할 수도 있습니다. 그렇지 않으면 "최소 4자" 암호를 입력하라는 메시지가 표시됩니다.

days 매개변수(365)는 만료 날짜에 영향을 주는 숫자로 바꿀 수 있습니다. 그런 다음 "국가 이름"과 같은 항목을 묻는 메시지가 표시되지만 Enter 키를 누르고 기본값을 수락하면 됩니다.

-subj '/CN=localhost' 를 추가하여 인증서 내용에 대한 질문을 억제합니다( localhost 를 원하는 도메인으로 교체).

자체 서명된 인증서는 이전에 브라우저로 가져오지 않는 한 타사에서 검증되지 않습니다. 더 많은 보안이 필요한 경우 인증 기관 (CA)에서 서명한 인증서를 사용해야 합니다.


Diego Woitasen

내가 뭔가를 놓치고 있습니까? 자체 서명된 인증서를 빌드하는 올바른 방법입니까?

자체 서명된 인증서를 만드는 것은 쉽습니다. openssl req 명령을 사용하면 됩니다. 브라우저 및 명령줄 도구와 같이 가장 많은 클라이언트가 사용할 수 있는 클라이언트를 만드는 것은 까다로울 수 있습니다.

브라우저에는 고유한 요구 사항 집합이 있고 IETF 보다 더 제한적이기 때문에 어렵습니다. 브라우저에서 사용하는 요구 사항은 CA/브라우저 포럼에 문서화되어 있습니다(아래 참조 참조). 제한은 (1) 트러스트 앵커 및 (2) DNS 이름의 두 가지 주요 영역에서 발생합니다.

최신 브라우저(예: 2014/2015년에 사용 중인 warez)는 트러스트 앵커에 다시 연결되는 인증서를 원하고 DNS 이름이 인증서에 특정 방식으로 표시되기를 원합니다. 그리고 브라우저는 자체 서명된 서버 인증서에 대해 적극적으로 움직이고 있습니다.

일부 브라우저에서는 자체 서명된 서버 인증서를 쉽게 가져올 수 없습니다. 사실, 안드로이드의 브라우저와 같은 일부 브라우저에서는 불가능합니다. 따라서 완전한 해결책은 자신의 권위자가 되는 것입니다.

자신의 권한이 없는 경우 인증서에 가장 큰 성공 기회를 제공하려면 DNS 이름을 올바르게 지정해야 합니다. 그러나 나는 당신이 당신 자신의 권위자가 되기를 권하고 싶습니다. 자신의 권위자가 되기 쉽고 모든 신뢰 문제를 회피할 것입니다(누가 자신보다 더 신뢰합니까?).


이것은 아마도 당신이 찾고 있는 사이트가 아닐 것입니다!
사이트의 보안 인증서를 신뢰할 수 없습니다!

이는 브라우저가 미리 정의된 트러스트 앵커 목록을 사용하여 서버 인증서의 유효성을 검사하기 때문입니다. 자체 서명된 인증서는 신뢰할 수 있는 앵커로 다시 연결되지 않습니다.

이것을 피하는 가장 좋은 방법은 다음과 같습니다.

  1. 자신의 권한 만들기(즉, CA 되기)
  2. 서버에 대한 인증서 서명 요청(CSR) 생성
  3. CA 키로 서버의 CSR에 서명
  4. 서버에 서버 인증서 설치
  5. 클라이언트에 CA 인증서 설치

1단계 - 자신의 권한 을 생성한다는 것은 CA로 자체 서명된 인증서를 생성하는 것을 의미합니다 CA: true 및 적절한 키 사용. 이는 SubjectIssuer 가 동일한 엔티티이고, CA가 기본 제약 조건 에서 true로 설정되고(Critical로 표시되어야 함), 키 사용이 keyCertSign 및 crlSign(CRL을 사용하는 경우)이며, Subject Key Identifier (SKI crlSign )는 AKI( Authority Key Identifier) 와 동일합니다.

자신의 인증 기관이 되려면 * 인증 기관과 인증서 서명 요청에 서명하는 방법은 무엇입니까?를 참조하십시오. 스택 오버플로에. 그런 다음 브라우저에서 사용하는 신뢰 저장소로 CA를 가져오십시오.

2-4단계는 Startcom 또는 CAcert 와 같은 CA의 서비스를 등록할 때 공용 서버에 대해 지금 수행하는 작업입니다. 1단계와 5단계에서는 제3자의 권위를 피하고 자신의 권위자처럼 행동할 수 있습니다(누가 자신보다 더 신뢰할 수 있습니까?).

브라우저 경고를 피하는 다음으로 가장 좋은 방법은 서버의 인증서를 신뢰하는 것입니다. 그러나 Android의 기본 브라우저와 같은 일부 브라우저에서는 이를 허용하지 않습니다. 따라서 플랫폼에서 작동하지 않습니다.

자체 서명된 인증서를 신뢰하지 않는 브라우저(및 기타 유사한 사용자 에이전트) 문제는 사물 인터넷(IoT)에서 큰 문제가 될 것입니다. 예를 들어, 온도 조절기나 냉장고에 연결하여 프로그래밍하면 어떻게 될까요? 대답은 사용자 경험에 관한 한 좋은 것이 없다는 것입니다.

W3C의 WebAppSec 워킹 그룹은 이 문제를 살펴보기 시작했습니다. 예를 들어 제안: HTTP를 비보안으로 표시 를 참조하십시오.


OpenSSL로 자체 서명된 인증서를 만드는 방법

아래 명령과 구성 파일은 자체 서명된 인증서를 생성합니다(서명 요청 생성 방법도 보여줌). 그들은 한 가지 점에서 다른 답변과 다릅니다. 자체 서명 인증서에 사용되는 DNS 이름은 CN(일반 이름)이 아니라 SAN(주체 대체 이름 )에 있습니다.

subjectAltName = @alternate_names 행이 있는 구성 파일을 통해 SAN에 배치됩니다(명령줄을 통해 이를 수행할 방법이 없음). 그런 다음 alternate_names 섹션이 있습니다(취향에 맞게 조정해야 함).

 [ alternate_names ] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = mail.example.com DNS.4 = ftp.example.com # Add these if you need them. But usually you don't want them or # need them in production. You may need them for development. # DNS.5 = localhost # DNS.6 = localhost.localdomain # IP.1 = 127.0.0.1 # IP.2 = ::1

IETF와 CA/Browser Forums 모두 가 관행을 지정하기 때문에 CN이 아닌 SAN에 DNS 이름을 넣는 것이 중요합니다. 또한 CN의 DNS 이름이 더 이상 사용되지 않음을 지정합니다(그러나 금지되지는 않음). 당신이 CN의 DNS 이름을 넣으면, 다음은 CA / B 정책 아래에있는 SAN에 포함되어야합니다. 따라서 주체 대체 이름 사용을 피할 수 없습니다.

SAN에 DNS 이름을 입력하지 않으면 CA/브라우저 포럼 지침을 따르는 브라우저 및 기타 사용자 에이전트에서 인증서의 유효성을 검사하지 못합니다.

관련: 브라우저는 CA/브라우저 포럼 정책을 따릅니다. IETF 정책이 아닙니다. 이것이 OpenSSL(일반적으로 IETF를 따름)로 생성된 인증서가 때때로 브라우저(브라우저는 CA/B를 따름)에서 유효성을 검사하지 않는 이유 중 하나입니다. 표준이 다르고 발급 정책과 검증 요구 사항이 다릅니다.


자체 서명된 인증서 생성 -x509 옵션 추가 참고):

 openssl req -config example-com.conf -new -x509 -sha256 -newkey rsa:2048 -nodes \ -keyout example-com.key.pem -days 365 -out example-com.cert.pem

서명 요청을 생성합니다 -x509 옵션이 없음에 주의).

 openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \ -keyout example-com.key.pem -days 365 -out example-com.req.pem

자체 서명된 인증서 인쇄 :

 openssl x509 -in example-com.cert.pem -text -noout

서명 요청 인쇄 :

 openssl req -in example-com.req.pem -text -noout

구성 파일( -config 옵션을 통해 전달)

 [ req ] default_bits = 2048 default_keyfile = server-key.pem distinguished_name = subject req_extensions = req_ext x509_extensions = x509_ext string_mask = utf8only # The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description). # Its sort of a mashup. For example, RFC 4514 does not provide emailAddress. [ subject ] countryName = Country Name (2 letter code) countryName_default = US stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = NY localityName = Locality Name (eg, city) localityName_default = New York organizationName = Organization Name (eg, company) organizationName_default = Example, LLC # Use a friendly name here because it's presented to the user. The server's DNS # names are placed in Subject Alternate Names. Plus, DNS names here is deprecated # by both IETF and CA/Browser Forums. If you place a DNS name here, then you # must include the DNS name in the SAN too (otherwise, Chrome and others that # strictly follow the CA/Browser Baseline Requirements will fail). commonName = Common Name (eg server FQDN or YOUR name) commonName_default = Example Company emailAddress = Email Address emailAddress_default = test@example.com # Section x509_ext is used when generating a self-signed certificate. Ie, openssl req -x509 ... [ x509_ext ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer # You only need digitalSignature below. *If* you don't allow # RSA Key transport (ie, you use ephemeral cipher suites), then # omit keyEncipherment because that's key transport. basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment subjectAltName = @alternate_names nsComment = "OpenSSL Generated Certificate" # RFC 5280, Section 4.2.1.12 makes EKU optional # CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused # In either case, you probably only need serverAuth. # extendedKeyUsage = serverAuth, clientAuth # Section req_ext is used when generating a certificate signing request. Ie, openssl req ... [ req_ext ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment subjectAltName = @alternate_names nsComment = "OpenSSL Generated Certificate" # RFC 5280, Section 4.2.1.12 makes EKU optional # CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused # In either case, you probably only need serverAuth. # extendedKeyUsage = serverAuth, clientAuth [ alternate_names ] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = mail.example.com DNS.4 = ftp.example.com # Add these if you need them. But usually you don't want them or # need them in production. You may need them for development. # DNS.5 = localhost # DNS.6 = localhost.localdomain # DNS.7 = 127.0.0.1 # IPv6 localhost # DNS.8 = ::1

Chrome에 대해 다음을 수행해야 할 수 있습니다. 그렇지 않으면 Chrome에서 일반 이름 이 잘못 ERR_CERT_COMMON_NAME_INVALID 불평할 수 있습니다(ERR_CERT_COMMON_NAME_INVALID) . 이 경우 SAN의 IP 주소와 CN 간의 관계가 무엇인지 잘 모르겠습니다.

 # IPv4 localhost # IP.1 = 127.0.0.1 # IPv6 localhost # IP.2 = ::1

X.509/PKIX 인증서의 DNS 이름 처리와 관련된 다른 규칙이 있습니다. 규칙은 다음 문서를 참조하십시오.

RFC 6797 및 RFC 7469는 다른 RFC 및 CA/B 문서보다 더 제한적이므로 나열됩니다. RFC 6797 및 7469도 IP 주소를 허용 하지 않습니다.


jww

OpenSSL ≥ 1.1.1을 사용하는 2021년부터 다음 명령은 SAN을 포함한 모든 요구 사항을 충족합니다.

 openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \ -keyout example.key -out example.crt -subj "/CN=example.com" \ -addext "subjectAltName=DNS:example.com,DNS:www.example.net,IP:10.0.0.1"

Debian ≤ 9 또는 CentOS ≤ 7과 같이 OpenSSL ≤ 1.1.0을 사용하는 이전 시스템에서는 이 명령의 더 긴 버전을 사용해야 합니다.

 openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \ -keyout example.key -out example.crt -extensions san -config \ <(echo "[req]"; echo distinguished_name=req; echo "[san]"; echo subjectAltName=DNS:example.com,DNS:www.example.net,IP:10.0.0.1 ) \ -subj "/CN=example.com"

두 명령 모두 다음과 같은 인증서를 생성합니다.

  • (하위) 도메인 example.comwww.example.net (SAN)에 유효합니다.
  • 10.0.0.1 (SAN)에도 유효합니다.
  • 상대적으로 강하고(2021년 기준)
  • 3650 일(~10년) 동안 유효합니다.

다음 파일이 생성됩니다.

  • 개인 키: example.key
  • 인증서: example.crt

모든 정보는 명령줄에 제공됩니다. 당신을 짜증나게 하는 대화형 입력 은 없습니다. 어지럽혀야 하는 구성 파일 이 없습니다. 필요한 모든 단계는 개인 키 생성에서 자체 서명 인증서까지 단일 OpenSSL 호출로 실행됩니다.

비고 #1: 암호화 매개변수

인증서는 자체 서명되고 사용자가 수동으로 수락해야 하므로 만료 기간이 짧거나 약한 암호화를 사용하는 것은 의미가 없습니다.

미래에는 RSA 키에 4096 비트 이상을 사용 sha256 보다 강력한 해시 알고리즘을 사용할 수 있지만 2021년 현재 이는 정상적인 값입니다. 모든 최신 브라우저에서 지원되는 동안 충분히 강력합니다.

비고 #2: 매개변수 " -nodes "

-nodes 매개변수("DES 암호화 없음"을 의미)를 생략할 수 있습니다. 이 example.key 는 암호로 암호화됩니다. 그러나 이것은 서버 설치에 거의 유용하지 않습니다. 서버에도 암호를 저장해야 하거나 재부팅할 때마다 수동으로 입력해야 하기 때문입니다.

비고 #3: 참조


vog

다음은 설명서 에서 자세히 설명된 @diegows의 답변 에 설명된 옵션입니다.

 openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX
 req

PKCS#10 인증서 요청 및 인증서 생성 유틸리티.

 -x509

이 옵션은 인증서 요청 대신 자체 서명된 인증서를 출력합니다. 이것은 일반적으로 테스트 인증서 또는 자체 서명된 루트 CA를 생성하는 데 사용됩니다.

 -newkey arg

이 옵션은 새 인증서 요청과 새 개인 키를 만듭니다. 인수는 여러 형식 중 하나를 취합니다. rsa:nbits , 여기서 nbits 는 비트 수이며 크기가 nbits 인 RSA 키를 생성합니다.

 -keyout filename

이것은 새로 생성된 개인 키를 쓸 파일 이름을 제공합니다.

 -out filename

기본적으로 쓸 출력 파일 이름 또는 표준 출력을 지정합니다.

 -days n

-x509 옵션을 사용할 때 인증서를 인증할 일 수를 지정합니다. 기본값은 30일입니다.

 -nodes

이 옵션이 지정되면 개인 키가 생성되더라도 암호화되지 않습니다.

문서는 실제로 위의 것보다 더 자세합니다. 여기까지만 요약했습니다.


user456814

코멘트를 할 수 없으므로 별도의 답변으로 두겠습니다. 허용되는 한 줄짜리 답변에서 몇 가지 문제를 발견했습니다.

  • 한 줄짜리 키에 암호가 포함되어 있습니다.
  • one-liner는 많은 브라우저에서 콘솔에 경고를 표시하는 SHA-1을 사용합니다.

다음은 암호를 제거하고 경고를 표시하지 않도록 보안을 강화하고 전체 질문 목록을 제거하기 위해 -subj에 전달하라는 제안을 주석에 포함하는 단순화된 버전입니다.

 openssl genrsa -out server.key 2048 openssl rsa -in server.key -out server.key openssl req -sha256 -new -key server.key -out server.csr -subj '/CN=localhost' openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

'localhost'를 필요한 도메인으로 바꾸십시오. OpenSSL이 암호를 묻는 메시지를 표시하므로 처음 두 명령을 하나씩 실행해야 합니다.

둘을 .pem 파일로 결합하려면:

 cat server.crt server.key > cert.pem

Mike N

최신 브라우저는 이제 SAN(주체 대체 이름)이 누락된 경우 제대로 구성된 자체 서명 인증서에 대해 보안 오류를 발생시킵니다. OpenSSL은 이를 지정하는 명령줄 방법을 제공하지 않으므로 많은 개발자의 자습서와 책갈피가 갑자기 구식입니다.

다시 실행하는 가장 빠른 방법은 짧은 독립 실행형 conf 파일입니다.

  1. OpenSSL 구성 파일 생성(예: req.cnf )

     [req] distinguished_name = req_distinguished_name x509_extensions = v3_req prompt = no [req_distinguished_name] C = US ST = VA L = SomeCity O = MyCompany OU = MyDivision CN = www.company.com [v3_req] keyUsage = critical, digitalSignature, keyAgreement extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = www.company.com DNS.2 = company.com DNS.3 = company.net
  2. 이 구성 파일을 참조하는 인증서 생성

     openssl req -x509 -nodes -days 730 -newkey rsa:2048 \ -keyout cert.key -out cert.pem -config req.cnf -sha256

https://support.citrix.com/article/CTX135602의 구성 예


Community Wiki

주요 브라우저가 "SHA-1 인증서"를 안전하지 않은 것으로 표시하는 것을 고려하고 있기 때문에 SHA-2 해시 알고리즘을 사용 하려면 -sha256 매개변수를 추가하는 것이 좋습니다.

허용된 답변의 동일한 명령줄 - -sha256이 추가된 @diegows

openssl req -x509 -sha256 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX

자세한 내용은 Google 보안 블로그 를 참조하세요 .

2018년 5월 업데이트. SHA-2를 사용하면 자체 서명된 인증서에 보안이 추가되지 않는다는 의견에 많은 사람들이 언급했습니다. 하지만 구식/안전하지 않은 암호화 해시 함수를 사용하지 않는 좋은 습관으로 사용하는 것이 좋습니다. 전체 설명은 최종 엔터티 인증서 위의 인증서가 SHA-1 기반인 것이 좋은 이유는 무엇입니까? .


Maris B.

이것은 자체 서명된 인증서에서 SAN(subjectAltName)을 설정하기 위해 로컬 상자에서 사용하는 스크립트입니다.

이 스크립트는 도메인 이름(example.com)을 사용하고 동일한 인증서에서 *.example.com 및 example.com에 대한 SAN을 생성합니다. 아래 섹션은 주석 처리됩니다. 스크립트의 이름을 지정하고(예: generate-ssl.sh ) 실행 권한을 부여합니다. 파일은 스크립트와 동일한 디렉토리에 작성됩니다.

Chrome 58 이상에서는 자체 서명된 인증서에 SAN을 설정해야 합니다.

 #!/usr/bin/env bash # Set the TLD domain we want to use BASE_DOMAIN="example.com" # Days for the cert to live DAYS=1095 # A blank passphrase PASSPHRASE="" # Generated configuration file CONFIG_FILE="config.txt" cat > $CONFIG_FILE <<-EOF [req] default_bits = 2048 prompt = no default_md = sha256 x509_extensions = v3_req distinguished_name = dn [dn] C = CA ST = BC L = Vancouver O = Example Corp OU = Testing Domain emailAddress = webmaster@$BASE_DOMAIN CN = $BASE_DOMAIN [v3_req] subjectAltName = @alt_names [alt_names] DNS.1 = *.$BASE_DOMAIN DNS.2 = $BASE_DOMAIN EOF # The file name can be anything FILE_NAME="$BASE_DOMAIN" # Remove previous keys echo "Removing existing certs like $FILE_NAME.*" chmod 770 $FILE_NAME.* rm $FILE_NAME.* echo "Generating certs for $BASE_DOMAIN" # Generate our Private Key, CSR and Certificate # Use SHA-2 as SHA-1 is unsupported from Jan 1, 2017 openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout "$FILE_NAME.key" -days $DAYS -out "$FILE_NAME.crt" -passin pass:$PASSPHRASE -config "$CONFIG_FILE" # OPTIONAL - write an info to see the details of the generated crt openssl x509 -noout -fingerprint -text < "$FILE_NAME.crt" > "$FILE_NAME.info" # Protect the key chmod 400 "$FILE_NAME.key"

이 스크립트는 정보 파일도 작성하므로 새 인증서를 검사하고 SAN이 제대로 설정되었는지 확인할 수 있습니다.

 ... 28:dd:b8:1e:34:b5:b1:44:1a:60:6d:e3:3c:5a:c4: da:3d Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Alternative Name: DNS:*.example.com, DNS:example.com Signature Algorithm: sha256WithRSAEncryption 3b:35:5a:d6:9e:92:4f:fc:f4:f4:87:78:cd:c7:8d:cd:8c:cc: ...

Apache를 사용하는 경우 다음과 같이 구성 파일에서 위의 인증서를 참조할 수 있습니다.

 <VirtualHost _default_:443> ServerName example.com ServerAlias www.example.com DocumentRoot /var/www/htdocs SSLEngine on SSLCertificateFile path/to/your/example.com.crt SSLCertificateKeyFile path/to/your/example.com.key </VirtualHost>

새 인증서를 적용하려면 Apache(또는 Nginx 또는 IIS) 서버를 다시 시작해야 합니다.


Drakes

댓글을 달 수 없어 별도의 답변을 추가합니다. NGINX용 자체 서명 인증서를 만들려고 했더니 쉬웠는데 크롬 화이트리스트에 추가하려고 했더니 문제가 생겼습니다. 그리고 내 솔루션은 루트 인증서를 만들고 그것에 의해 하위 인증서에 서명하는 것이 었습니다.

그래서 단계적으로. config_ssl_ca.cnf 파일 생성 주의, config 파일에는 basicConstraints=CA:true 옵션이 있습니다. 이는 이 인증서가 루트여야 함을 의미합니다.

한 번 만들고 다시 사용할 수 있으므로 이는 좋은 방법입니다.

 [ req ] default_bits = 2048 prompt = no distinguished_name=req_distinguished_name req_extensions = v3_req [ req_distinguished_name ] countryName=UA stateOrProvinceName=root region localityName=root city organizationName=Market(localhost) organizationalUnitName=roote department commonName=market.localhost emailAddress=root_email@root.localhost [ alternate_names ] DNS.1 = market.localhost DNS.2 = www.market.localhost DNS.3 = mail.market.localhost DNS.4 = ftp.market.localhost DNS.5 = *.market.localhost [ v3_req ] keyUsage=digitalSignature basicConstraints=CA:true subjectKeyIdentifier = hash subjectAltName = @alternate_names

하위 인증서에 대한 다음 구성 파일은 config_ssl.cnf를 호출합니다.

 [ req ] default_bits = 2048 prompt = no distinguished_name=req_distinguished_name req_extensions = v3_req [ req_distinguished_name ] countryName=UA stateOrProvinceName=Kyiv region localityName=Kyiv organizationName=market place organizationalUnitName=market place department commonName=market.localhost emailAddress=email@market.localhost [ alternate_names ] DNS.1 = market.localhost DNS.2 = www.market.localhost DNS.3 = mail.market.localhost DNS.4 = ftp.market.localhost DNS.5 = *.market.localhost [ v3_req ] keyUsage=digitalSignature basicConstraints=CA:false subjectAltName = @alternate_names subjectKeyIdentifier = hash

첫 번째 단계 - 루트 키 및 인증서 생성

 openssl genrsa -out ca.key 2048 openssl req -new -x509 -key ca.key -out ca.crt -days 365 -config config_ssl_ca.cnf

두 번째 단계에서는 자식 키와 파일 CSR - 인증서 서명 요청을 만듭니다. 아이디어는 루트로 자식 인증서에 서명하고 올바른 인증서를 얻는 것이기 때문에

 openssl genrsa -out market.key 2048 openssl req -new -sha256 -key market.key -config config_ssl.cnf -out market.csr

Linux 터미널을 열고 이 명령을 수행하십시오.

 echo 00 > ca.srl touch index.txt

16진수로 사용할 다음 일련 번호가 포함된 ca.srl 텍스트 파일입니다. 필수적인. 이 파일이 있어야 하며 유효한 일련 번호를 포함해야 합니다.

마지막 단계에서 구성 파일을 하나 더 만들고 config_ca.cnf라고 합니다.

 # we use 'ca' as the default section because we're usign the ca command [ ca ] default_ca = my_ca [ my_ca ] # a text file containing the next serial number to use in hex. Mandatory. # This file must be present and contain a valid serial number. serial = ./ca.srl # the text database file to use. Mandatory. This file must be present though # initially it will be empty. database = ./index.txt # specifies the directory where new certificates will be placed. Mandatory. new_certs_dir = ./ # the file containing the CA certificate. Mandatory certificate = ./ca.crt # the file contaning the CA private key. Mandatory private_key = ./ca.key # the message digest algorithm. Remember to not use MD5 default_md = sha256 # for how many days will the signed certificate be valid default_days = 365 # a section with a set of variables corresponding to DN fields policy = my_policy # MOST IMPORTANT PART OF THIS CONFIG copy_extensions = copy [ my_policy ] # if the value is "match" then the field value must match the same field in the # CA certificate. If the value is "supplied" then it must be present. # Optional means it may be present. Any fields not mentioned are silently # deleted. countryName = match stateOrProvinceName = supplied organizationName = supplied commonName = market.localhost organizationalUnitName = optional commonName = supplied

왜 그렇게 어려운지, 루트로 하위 인증서에 서명하기 위해 구성을 하나 더 만들어야 하는 이유를 물을 수 있습니다. 하위 인증서에는 SAN 블록(주체 대체 이름)이 있어야 하기 때문에 대답은 간단합니다. "openssl x509" 유틸리티로 하위 인증서에 서명하면 루트 인증서가 하위 인증서의 SAN 필드를 삭제합니다. 따라서 SAN 필드가 삭제되지 않도록 "openssl x509" 대신 "openssl ca"를 사용합니다. 새 구성 파일을 만들고 모든 확장 필드 copy_extensions = copy 를 복사하도록 지시 합니다.

 openssl ca -config config_ca.cnf -out market.crt -in market.csr

이 프로그램은 2가지 질문을 합니다.

  1. 인증서에 서명하시겠습니까? "Y"라고 말하세요
  2. 인증서 요청 1개 중 1개 인증, 커밋? "Y"라고 말하세요

터미널에서 "Database"라는 단어가 있는 문장을 볼 수 있습니다. 이는 "touch" 명령으로 생성한 index.txt 파일을 의미합니다. 여기에는 "openssl ca" 유틸리티로 생성한 모든 인증서의 모든 정보가 포함됩니다. 인증서 유효한 사용을 확인하려면:

 openssl rsa -in market.key -check

CRT에서 내부 내용을 보려면 다음을 수행하십시오.

 openssl x509 -in market.crt -text -noout

CSR의 내부 내용을 보려면 다음을 수행하십시오.

 openssl req -in market.csr -noout -text

mrkiril

2017 한 줄:

 openssl req \ -newkey rsa:2048 \ -x509 \ -nodes \ -keyout server.pem \ -new \ -out server.pem \ -subj /CN=localhost \ -reqexts SAN \ -extensions SAN \ -config <(cat /System/Library/OpenSSL/openssl.cnf \ <(printf '[SAN]\nsubjectAltName=DNS:localhost')) \ -sha256 \ -days 3650

이것은 다른 구성 파일 없이 SAN을 제공하므로 Chrome 57에서도 작동합니다. 여기 의 답변 에서 가져 왔습니다 .

이렇게 하면 개인 키와 인증서가 모두 포함된 단일 .pem 파일이 생성됩니다. 필요한 경우 별도의 .pem 파일로 이동할 수 있습니다.


joemillervi

한 줄짜리 버전 2017:

센트OS:

 openssl req -x509 -nodes -sha256 -newkey rsa:2048 \ -keyout localhost.key -out localhost.crt \ -days 3650 \ -subj "CN=localhost" \ -reqexts SAN -extensions SAN \ -config <(cat /etc/pki/tls/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))

우분투:

 openssl req -x509 -nodes -sha256 -newkey rsa:2048 \ -keyout localhost.key -out localhost.crt \ -days 3650 \ -subj "/CN=localhost" \ -reqexts SAN -extensions SAN \ -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))

편집: Ubuntu의 'subj' 옵션 앞에 슬래시를 추가했습니다.


user327843

일반적인 절차가 정확합니다. 명령 구문은 다음과 같습니다.

 openssl req -new -key {private key file} -out {output file}

그러나 브라우저가 알려진 인증 기관(CA)으로 인증서의 유효성을 검사하여 식별을 확인할 수 없기 때문에 경고가 표시됩니다.

자체 서명된 인증서이므로 CA가 없으므로 경고를 무시하고 안전하게 진행할 수 있습니다. 공용 인터넷에서 누구나 인식할 수 있는 실제 인증서를 얻으려면 다음 절차를 따르십시오.

  1. 개인 키 생성
  2. 해당 개인 키를 사용하여 CSR 파일 생성
  3. CA(Verisign 등)에 CSR 제출
  4. CA에서 받은 인증서를 웹서버에 설치
  5. cert 유형에 따라 인증 체인에 다른 인증서 추가

이에 대한 자세한 내용은 연결 보안: OpenSSL을 사용하여 보안 인증서 생성의 게시물에 있습니다.


nneko

하나의 라이너 FTW. 나는 그것을 간단하게 유지하는 것을 좋아합니다. 필요한 모든 인수를 포함하는 하나의 명령을 사용하지 않는 이유는 무엇입니까? 이것이 내가 좋아하는 방법입니다. x509 인증서와 PEM 키를 생성합니다.

 openssl req -x509 \ -nodes -days 365 -newkey rsa:4096 \ -keyout self.key.pem \ -out self-x509.crt \ -subj "/C=US/ST=WA/L=Seattle/CN=example.com/emailAddress=someEmail@gmail.com"

이 단일 명령에는 일반적으로 인증서 세부 정보에 대해 제공하는 모든 답변이 포함되어 있습니다. 이런 식으로 매개변수를 설정하고 명령을 실행하고 출력을 얻은 다음 커피를 마실 수 있습니다.

>> 더 보기 <<


OkezieE

키 생성

/etc/apparmor.d/usr.sbin.mysqld /etc/mysql/*.pem r 포함되어 있기 때문에 인증서 저장을 위해 /etc/mysql 을 사용하고 있습니다.

 sudo su - cd /etc/mysql openssl genrsa -out ca-key.pem 2048; openssl req -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem; openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem -out server-req.pem; openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem; openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem -out client-req.pem; openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem;

구성 추가

/etc/mysql/my.cnf

 [client] ssl-ca=/etc/mysql/ca-cert.pem ssl-cert=/etc/mysql/client-cert.pem ssl-key=/etc/mysql/client-key.pem [mysqld] ssl-ca=/etc/mysql/ca-cert.pem ssl-cert=/etc/mysql/server-cert.pem ssl-key=/etc/mysql/server-key.pem

내 설정에서 Ubuntu 서버는 /var/log/mysql/error.log

후속 메모:

  • SSL error: Unable to get certificate from '...'

    MySQL은 Apparmors 구성에 있지 않은 경우 인증서 파일에 대한 읽기 액세스가 거부될 수 있습니다 . 이전 단계^에서 언급했듯이 모든 인증서를 /etc/mysql/ .pem 파일로 저장합니다. 이 파일은 기본적으로 apparmor에서 승인합니다(또는 apparmor/SELinux를 수정하여 저장한 모든 위치에 액세스할 수 있도록 합니다.).

  • SSL error: Unable to get private key

    MySQL 서버 버전이 기본 rsa:2048 형식을 지원하지 않을 수 있습니다.

    다음을 사용하여 생성된 rsa:2048 을 일반 rsa 로 변환합니다.

     openssl rsa -in server-key.pem -out server-key.pem openssl rsa -in client-key.pem -out client-key.pem
  • 로컬 서버가 SSL을 지원하는지 확인하십시오 .

     mysql -u root -p mysql> show variables like "%ssl%"; +---------------+----------------------------+ | Variable_name | Value | +---------------+----------------------------+ | have_openssl | YES | | have_ssl | YES | | ssl_ca | /etc/mysql/ca-cert.pem | | ssl_capath | | | ssl_cert | /etc/mysql/server-cert.pem | | ssl_cipher | | | ssl_key | /etc/mysql/server-key.pem | +---------------+----------------------------+
  • 데이터베이스에 대한 연결이 SSL 암호화되었는지 확인 :

    연결 확인 중

    MySQL 인스턴스에 로그인하면 다음 쿼리를 실행할 수 있습니다.

     show status like 'Ssl_cipher';

    연결이 암호화되지 않은 경우 결과는 비어 있습니다.

     mysql> show status like 'Ssl_cipher'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Ssl_cipher | | +---------------+-------+ 1 row in set (0.00 sec)

    그렇지 않으면 사용 중인 암호에 대해 길이가 0이 아닌 문자열을 표시합니다.

     mysql> show status like 'Ssl_cipher'; +---------------+--------------------+ | Variable_name | Value | +---------------+--------------------+ | Ssl_cipher | DHE-RSA-AES256-SHA | +---------------+--------------------+ 1 row in set (0.00 sec)
  • 특정 사용자의 연결에 ssl 필요('ssl 필요'):

    • SSL

    계정에 대해 SSL 암호화 연결만 허용하도록 서버에 지시합니다.

     GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' REQUIRE SSL;

    연결하려면 클라이언트가 --ssl-ca 옵션을 지정하여 서버 인증서를 인증해야 하며, --ssl-key 및 --ssl-cert 옵션을 추가로 지정할 수 있습니다. --ssl-ca 옵션과 --ssl-capath 옵션이 모두 지정되지 않은 경우 클라이언트는 서버 인증서를 인증하지 않습니다.


대체 링크: SSL을 사용하여 MySQL 에 대한 안전한 PHP 연결의 긴 자습서 .


Community Wiki

자세히 설명했듯이 자체 서명된 인증서 는 인터넷에서 신뢰할 수 없습니다 . 자체 서명 인증서를 모든 브라우저가 아닌 많은 브라우저에 추가할 수 있습니다. 또는 자신의 인증 기관이 될 수 있습니다 .

인증 기관에서 서명된 인증서를 원하지 않는 주된 이유는 비용입니다. 시만텍은 인증서에 대해 연간 995~1,999달러를 청구합니다. 내부 네트워크용 인증서에 대해서만 시만텍은 연간 399달러를 청구 합니다. 신용 카드 결제를 처리하거나 수익성이 높은 회사의 수익 센터에서 일하는 경우 그 비용을 정당화하기 쉽습니다. 인터넷에서 개인 프로젝트를 만들거나 최소한의 예산으로 운영하는 비영리 조직을 위해 또는 조직의 비용 센터에서 일하는 경우 비용 센터는 항상 더 많은 일을 하려고 하는 경우 많은 사람들이 감당할 수 있는 것 이상입니다. 적은.

대안은 사용하는 것입니다 certbot를 (참조 certbot에 대해 ). Certbot은 웹 서버용 SSL/TLS 인증서를 가져와 배포하는 사용하기 쉬운 자동 클라이언트입니다.

certbot을 설정하면 Let's Encrypt 인증 기관에서 발급한 인증서를 생성하고 유지 관리할 수 있습니다.

나는 우리 조직을 위해 주말에 이것을 했다. 내 서버(Ubuntu 16.04)에 certbot에 필요한 패키지를 설치한 다음 certbot을 설정하고 활성화하는 데 필요한 명령을 실행했습니다. 하나는 certbot용 DNS 플러그인 이 필요할 수 있습니다. 현재 DigitalOcean을 사용하고 있지만 곧 다른 서비스로 마이그레이션할 수 있습니다.

일부 지침은 정확하지 않았으며 Google에서 알아내는 데 약간의 시간과 시간이 걸렸습니다. 이것은 처음에는 상당한 시간이 걸렸지만 이제는 몇 분 안에 할 수 있다고 생각합니다.

DigitalOcean의 경우 내가 고심했던 영역 중 하나는 DigitalOcean 자격 증명 INI 파일의 경로를 입력하라는 메시지가 표시되었을 때였습니다. 스크립트가 참조하는 것은 애플리케이션 및 API 페이지와 해당 페이지의 토큰/키 탭입니다. DigitalOcean의 API에 대한 개인 액세스 토큰(읽기 및 쓰기)이 있거나 생성해야 합니다. 이것은 65자의 16진수 문자열입니다. 그런 다음 이 문자열을 certbot을 실행 중인 웹 서버의 파일에 넣어야 합니다. 해당 파일은 첫 번째 줄에 주석을 포함할 수 있습니다(주석은 #로 시작함). 두 번째 줄은 다음과 같습니다.

 dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff

DigitalOcean의 API에 대한 읽기+쓰기 토큰을 설정하는 방법을 알아낸 후에는 certbot을 사용하여 와일드카드 인증서 를 설정하는 것이 매우 쉬웠습니다. 와일드카드 인증서를 설정할 필요는 없으며 대신 인증서를 적용할 각 도메인과 하위 도메인을 지정할 수 있습니다. DigitalOcean의 개인 액세스 토큰이 포함된 자격 증명 INI 파일이 필요한 것은 와일드카드 인증서였습니다.

공개 키 인증서(ID 인증서 또는 SSL 인증서라고도 함)는 만료되며 갱신이 필요합니다. 따라서 정기적으로(반복적으로) 인증서를 갱신해야 합니다. certbot 문서는 인증서 갱신을 다룹니다.

내 계획은 openssl 명령을 사용하여 내 인증서의 만료 날짜를 가져오고 만료될 때까지 30일 이하일 때 갱신을 트리거하는 스크립트를 작성하는 것입니다. 그런 다음 이 스크립트를 cron에 추가하고 하루에 한 번 실행합니다.

다음은 인증서의 만료 날짜를 읽는 명령입니다.

 root@prod-host:~# /usr/bin/openssl x509 -enddate -noout -in path-to-certificate-pem-file notAfter=May 25 19:24:12 2019 GMT

Peter Jirak Eldritch

openssl 사용하면 단일 명령으로 자체 서명된 인증서를 생성할 수 있습니다( -newkey 는 개인 키를 생성하도록 -x509 는 서명 요청 대신 자체 서명된 인증서를 발행하도록 지시함):

 openssl req -x509 -newkey rsa:4096 \ -keyout my.key -passout pass:123456 -out my.crt \ -days 365 \ -subj /CN=localhost/O=home/C=US/emailAddress=me@mail.internal \ -addext "subjectAltName = DNS:localhost,DNS:web.internal,email:me@mail.internal" \ -addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

개인 키를 생성하고 별도의 단계에서 자체 서명 인증서를 구성할 수 있습니다.

 openssl genrsa -out my.key -passout pass:123456 2048 openssl req -x509 \ -key my.key -passin pass:123456 -out my.csr \ -days 3650 \ -subj /CN=localhost/O=home/C=US/emailAddress=me@mail.internal \ -addext "subjectAltName = DNS:localhost,DNS:web.internal,email:me@mail.internal" \ -addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

결과 인증서 검토::

 openssl x509 -text -noout -in my.crt

Java keytool 은 PKCS#12 저장소를 생성합니다::

 keytool -genkeypair -keystore my.p12 -alias master \ -storetype pkcs12 -keyalg RSA -keysize 2048 -validity 3650 \ -storepass 123456 \ -dname "CN=localhost,O=home,C=US" \ -ext 'san=dns:localhost,dns:web.internal,email:me@mail.internal'

자체 서명된 인증서를 내보내려면:

 keytool -exportcert -keystore my.p12 -file my.crt \ -alias master -rfc -storepass 123456

결과 인증서 검토::

 keytool -printcert -file my.crt

certtool 은 CLI에서 다른 속성을 전달하는 것을 허용하지 않습니다. 구성 파일을 엉망으로 만들고 싶지 않습니다((


gavenkoa

이것은 나를 위해 일했습니다

 openssl req -x509 -nodes -subj '/CN=localhost' -newkey rsa:4096 -keyout ./sslcert/key.pem -out ./sslcert/cert.pem -days 365

서버.js

 var fs = require('fs'); var path = require('path'); var http = require('http'); var https = require('https'); var compression = require('compression'); var express = require('express'); var app = express(); app.use(compression()); app.use(express.static(__dirname + '/www')); app.get('/*', function(req,res) { res.sendFile(path.join(__dirname+'/www/index.html')); }); // your express configuration here var httpServer = http.createServer(app); var credentials = { key: fs.readFileSync('./sslcert/key.pem', 'utf8'), cert: fs.readFileSync('./sslcert/cert.pem', 'utf8') }; var httpsServer = https.createServer(credentials, app); httpServer.listen(8080); httpsServer.listen(8443); console.log(`RUNNING ON http://127.0.0.1:8080`); console.log(`RUNNING ON http://127.0.0.1:8443`);

Leonardo Pineda

출처 : http:www.stackoverflow.com/questions/10175812/how-to-generate-a-self-signed-ssl-certificate-using-openssl

반응형