임베디드 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
작동하지만 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)에서 서명 한 인증서를 사용해야합니다 .
답변
뭔가 빠졌습니까? 이것이 자체 서명 된 인증서를 작성하는 올바른 방법입니까?
자체 서명 된 인증서를 쉽게 만들 수 있습니다. 당신은 openssl req
명령을 사용합니다 . 브라우저 및 명령 줄 도구와 같이 가장 다양한 클라이언트가 사용할 수있는 클라이언트를 만드는 것은 까다로울 수 있습니다.
브라우저에는 자체 요구 사항이 있으며 IETF 보다 제한적이므로 어렵습니다 . 브라우저가 사용하는 요구 사항은 CA / 브라우저 포럼에 설명되어 있습니다 (아래 참조 참조). 제한 사항은 (1) 트러스트 앵커 및 (2) DNS 이름의 두 가지 주요 영역에서 발생합니다.
최신 브라우저 (2014/2015에서 사용중인 warez와 같은)는 트러스트 앵커에 연결되는 인증서를 원하며 인증서에서 특정 방식으로 DNS 이름을 제시하기를 원합니다. 그리고 브라우저는 자체 서명 된 서버 인증서에 대해 적극적으로 움직이고 있습니다.
일부 브라우저에서는 자체 서명 된 서버 인증서를 쉽게 가져올 수 없습니다. 실제로 Android 브라우저와 같은 일부 브라우저에서는 사용할 수 없습니다. 따라서 완전한 해결책은 자신의 권한이되는 것입니다.
자신의 권한이없는 경우 인증서의 성공 가능성을 높이려면 DNS 이름을 가져와야합니다. 그러나 나는 당신이 당신의 자신의 권위가 되길 바랍니다. 자신의 권위가되기가 쉬우 며 모든 신뢰 문제를 회피 할 것입니다 (자신보다 신뢰하는 것이 더 나은가?).
이것은 아마도 당신이 찾고있는 사이트가 아닙니다!
사이트의 보안 인증서를 신뢰할 수 없습니다!
브라우저는 미리 정의 된 트러스트 앵커 목록을 사용하여 서버 인증서의 유효성을 검사하기 때문입니다. 자체 서명 된 인증서는 신뢰할 수있는 앵커에 다시 연결되지 않습니다.
이것을 피하는 가장 좋은 방법은 다음과 같습니다.
- 자신의 권한을 만듭니다 (즉, CA가 됨 )
- 서버에 대한 인증서 서명 요청 (CSR) 작성
- CA 키로 서버의 CSR에 서명
- 서버에 서버 인증서를 설치하십시오.
- 클라이언트에 CA 인증서 설치
1 단계- 자신의 권한 을 생성하는 것은 CA: true
적절한 키 사용과 자체 서명 된 인증서를 생성하는 것을 의미 합니다. 즉, 주체 와 발급자 가 동일한 엔터티이고 CA가 기본 제약 조건 에서 중요로 설정되어 있고 (중요로 표시되어야 함) 키 사용이 keyCertSign
있고 crlSign
(CRL을 사용하는 경우) 주체 키 식별자 (SKI)가 권한 키 식별자 (AKI) 와 동일합니다 .
자체 인증 기관이 되려면 * 인증 기관 에 인증서 서명 요청에 어떻게 서명합니까?를 참조하십시오. 스택 오버플로. 그런 다음 브라우저에서 사용하는 신뢰 저장소로 CA를 가져 오십시오.
2-4 단계는 Startcom 또는 CAcert 와 같은 CA의 서비스를 등록 할 때 공용 서버에 대해 대략 수행하는 작업 입니다. 1 단계와 5 단계를 사용하면 제 3 자 권한을 피하고 자신의 권한으로 행동 할 수 있습니다 (자신보다 신뢰하는 것이 더 낫습니까?).
브라우저 경고를 피하는 다음 가장 좋은 방법은 서버의 인증서를 신뢰하는 것입니다. 그러나 Android의 기본 브라우저와 같은 일부 브라우저는 허용하지 않습니다. 따라서 플랫폼에서 작동하지 않습니다.
자체 서명 된 인증서를 신뢰 하지 않는 브라우저 (및 기타 유사한 사용자 에이전트)의 문제는 사물 인터넷 (IoT)에서 큰 문제가 될 것입니다. 예를 들어 서모 스탯이나 냉장고에 연결하여 프로그래밍하면 어떻게됩니까? 대답은 사용자 경험에 관한 한 아무 것도 아닙니다.
W3C의 WebAppSec 실무 그룹이이 문제를 살펴보기 시작했습니다. 예를 들어 제안 : HTTP를 비보안으로 표시 를 참조하십시오 .
OpenSSL을 사용하여 자체 서명 된 인증서를 만드는 방법
아래 명령과 구성 파일은 자체 서명 인증서를 작성합니다 (서명 요청 작성 방법도 표시 함). 자체 서명 된 인증서에 사용 된 DNS 이름은 CN (일반 이름)이 아니라 SAN (주체 대체 이름 )에 있습니다.
DNS 이름은 구성 파일을 통해 SAN에 배치됩니다 subjectAltName = @alternate_names
(명령 행을 통해 수행 할 수있는 방법은 없습니다). 그런 다음 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
이 때문에 SAN이 아닌 CN에서 DNS 이름을 넣어하는 것이 중요 모두 는 IETF와 CA는 / 브라우저 포럼 연습을 지정합니다. 또한 CN의 DNS 이름은 더 이상 사용되지 않도록 지정하지만 금지되지는 않습니다. 경우 당신이 CN의 DNS 이름을 넣어, 다음은 해야한다 는 CA / B 정책 아래에있는 SAN에 포함. 따라서 주체 대체 이름 사용을 피할 수 없습니다.
SAN에 DNS 이름을 입력하지 않으면 CA / 브라우저 포럼 지침을 따르는 브라우저 및 기타 사용자 에이전트에서 인증서의 유효성이 검사되지 않습니다.
관련 : 브라우저는 CA / Browser Forum 정책을 따릅니다. 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 (e.g. 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. I.e., openssl req -x509 ...
[ x509_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
# You only need digitalSignature below. *If* you don't allow
# RSA Key transport (i.e., 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. I.e., 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
) . SAN의 IP 주소와이 인스턴스의 CN 사이의 관계가 무엇인지 잘 모르겠습니다.
# IPv4 localhost
# IP.1 = 127.0.0.1
# IPv6 localhost
# IP.2 = ::1
X.509 / PKIX 인증서의 DNS 이름 처리에 관한 다른 규칙이 있습니다. 규칙은 다음 문서를 참조하십시오.
- RFC 5280, Internet X.509 공개 키 인프라 인증서 및 인증서 해지 목록 (CRL) 프로필
- RFC 6125, TLS (Transport Layer Security) 컨텍스트에서 X.509 (PKIX) 인증서를 사용하여 인터넷 공개 키 인프라 내에서 도메인 기반 응용 프로그램 서비스 ID의 표현 및 검증
- RFC 6797, 부록 A, HTTP 엄격한 전송 보안 (HSTS)
- RFC 7469, HTTP 용 공개 키 고정 확장
- CA / 브라우저 포럼 기준 요구 사항
- CA / 브라우저 포럼 확장 유효성 검사 지침
RFC 6797 및 RFC 7469는 다른 RFC 및 CA / B 문서보다 제한적이므로 나열되어 있습니다. RFC 6797 및 7469 는 IP 주소도 허용 하지 않습니다 .
답변
여기에 설명 된 옵션입니다 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 는 비트 수임) RSA 키 nbit 크기를 생성합니다 .
-keyout filename
새로 만든 개인 키를 쓸 파일 이름을 제공합니다.
-out filename
기본적으로 쓸 출력 파일 이름 또는 표준 출력을 지정합니다.
-days n
때 -x509 옵션이 지정을 사용하고있는 일의 수에 대한 인증서를 인증합니다. 기본값은 30 일입니다.
-nodes
이 옵션이 지정되면 개인 키가 작성되면 암호화되지 않습니다.
문서는 실제로 위보다 더 자세합니다. 방금 요약했습니다.
답변
2020 년부터 다음 명령은 SAN을 포함하여 모든 요구를 충족시킵니다.
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:example.net,IP:10.0.0.1
) \
-subj "/CN=example.com"
OpenSSL ≥ 1.1.1에서는 다음과 같이 단축 될 수 있습니다.
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:example.net,IP:10.0.0.1"
그것은 인증서를 만듭니다
- 도메인
example.com
및example.net
(SAN)에 유효 - IP 주소
10.0.0.1
(SAN) 에도 유효합니다. - 비교적 강함 (2020 년 기준)
3650
일 (~ 10 년) 동안 유효합니다 .
다음 파일을 작성합니다.
- 개인 키 :
example.key
- 증명서:
example.crt
모든 정보는 명령 행에 제공됩니다. 당신을 귀찮게하는 대화 형 입력 이 없습니다 . 엉망인 설정 파일 이 없습니다 . 필요한 모든 단계는 개인 키 생성에서 자체 서명 된 인증서에 이르기까지 단일 OpenSSL 호출 로 실행됩니다 .
비고 # 1 : 암호화 매개 변수
인증서는 자체 서명되어 있으며 사용자가 수동으로 승인해야하므로 짧은 만기 또는 약한 암호화를 사용하는 것은 적합하지 않습니다.
앞으로 4096
RSA 키에 비트 이상의 비트 를 사용하고보다 강한 해시 알고리즘 을 사용할 수 sha256
있지만 2020 년 기준으로 제정 된 값입니다. 모든 최신 브라우저에서 지원되는 동안 충분히 강력합니다.
비고 # 2 : 매개 변수 ” -nodes
“
이론적으로 -nodes
매개 변수 ( “DES 암호화 없음”을 의미)를 생략 할 수 있으며,이 경우 example.key
비밀번호로 암호화됩니다. 그러나 서버에 암호를 저장해야하거나 재부팅 할 때마다 수동으로 암호를 입력해야하므로 이는 서버 설치에 거의 유용하지 않습니다.
비고 # 3 : 참조
답변
나는 언급 할 수 없으므로 이것을 별도의 답변으로 넣을 것입니다. 허용되는 한 줄짜리 답변과 관련된 몇 가지 문제를 발견했습니다.
- 원 라이너에는 키에 암호가 포함되어 있습니다.
- 하나의 라이너는 많은 브라우저에서 콘솔에 경고를 발생시키는 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
답변
최신 브라우저는 이제 제대로 구성된 자체 서명 된 인증서에 SAN (주체 대체 이름)이없는 경우 보안 오류가 발생합니다. OpenSSL은이를 지정하는 명령 줄 방법을 제공하지 않으므로 많은 개발자의 자습서 및 책갈피가 갑자기 오래되었습니다.
다시 실행하는 가장 빠른 방법은 짧은 독립형 conf 파일입니다.
-
(예 : 측정은 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
-
이 구성 파일을 참조하는 인증서를 작성하십시오.
openssl req -x509 -nodes -days 730 -newkey rsa:2048 \ -keyout cert.key -out cert.pem -config req.cnf -sha256
답변
주요 브라우저는 “SHA-1 인증서”를 안전하지 않은 것으로 표시하기 때문에 SHA-2 해시 알고리즘을 사용 하려면 -sha256 매개 변수 를 추가하는 것이 좋습니다 .
허용 된 답변과 동일한 명령 줄-추가 된 -sha256이있는 @diegows
openssl req -x509 -sha256 -newkey rsa : 2048 -keyout key.pem -out cert.pem-일 XXX
더 많은 정보를 구글 보안 블로그 .
업데이트 월 2018 사용하여 SHA-2는 자체 서명 된 인증서에 보안을 추가하지 않습니다 코멘트에서 언급 한 많은으로. 그러나 여전히 구식 / 안전하지 않은 암호화 해시 기능을 사용하지 않는 좋은 습관으로 사용하는 것이 좋습니다. 전체 엔터티 인증서 위의 인증서가 SHA-1 기반 인 것이 왜 좋은가? 에서 자세한 설명을 볼 수 있습니다 . .