목차
1. HTTPS 도입 이유
2. HTTPS 정의
3. HTTPS 개요
4. 웹사이트에서 HTTPS 사용률
5. 브라우저 통합
6. 보안
1. HTTPS 도입 이유
언젠가는 해야겠다고 생각하고 있다가 이번에 https에 대한 이론 정리 및 프로젝트에 적용해보려고 합니다. 페이스북 로그인 API 사용 정책에 페이스북 로그인을 사용하여 가입한 사용자가 페이스북 웹페이지를 통해 제 프로젝트에 회원탈퇴 및 피드 삭제를 요청하면 제가 설정한 서버로 콜백 API url이 호출되고 이 요청에대해 사용자 정보 삭제 및 피드 삭제를 처리해야합니다.
여기서 사용자 삭제 콜백 url을 페이스북 개발자사이트에 등록해야하는데 https 프로토콜만 허용합니다. 현재 http로 설정이 되어있어 이를 https로 적용해보려고 합니다.
2. HTTPS 정의
HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer) 는 HTTP(Hypertext Transfer Protocol)의 확장입니다. 이것은 컴퓨터 네트워크를 통한 보안 통신을 위해 사용되며 인터넷에서 널리 사용됩니다. HTTPS에서 통신 프로토콜은 TLS(Transport Layer Security) 또는 이전에는 SSL(Secure Socket Layer)을 사용하여 암호화됩니다. 따라서 프로토콜은 TLS를 통한 HTTP 또는 SSL을 통한 HTTP 라고도 합니다.
TLS: 암호화 프로토콜은 두 당사자가 개인정보 보호 및 데이터 무결성을 통신하도록 하여 안전한 연결을 제공합니다. TLS 프로토콜은 SSL프로토콜에서 발전한 것입니다.
SSL: SSL은 웹사이트와 브라우저 사이에 전송된 데이터를 암호화하여 인터넷 연결의 보안을 유지하는 표준 기술입니다.
HTTPS의 주요 동기는 접속한 웹사이트의 인증과 개인 정보의 보호 그리고 전송중 교환한 데이터의 무결성 입니다. 이는 클라이언트와 서버 사이 통신 양방향 암호화는 도청과 변조로부터 통신을 보호하여 man-in-the-middle 공격을 보호합니다. HTTPS의 인증 측면은 신뢰된 제 3자에게 서버 사이드 디지털 인증서 서명을 요청합니다. 이것은 역사적으로 전체적으로 인증된 HTTPS 연결은 주로 오직 보안 결제 트랜잭션에서만 발견된다는 것을 의미하는 비싼 동작입니다. 서비스와 다른 보안이 적용된 회사 정보 시스템이 월드 와이드 웹이 있는 것입니다. 2016년 Electronic Frontier Foundation으로 부터 웹브라우저 개발자의 지원과 함께 프로토콜이 더욱 일반적으로 쓰이게 만든 것으로부터 시작된 캠패인입니다. 웹 사용자로부터 HTTPS는 이제 기존 보안되지 않은 HTTP 보다 더욱 많이 사용됩니다. 우선적으로 보안 계정 그리고 모든 사용자 통신, 아이디, 웹 탐색을 비공개로하는 모든 타입의 웹사이트에서 페이지 진품인지 보호합니다.
3. HTTPS 개요
URI(Uniform Resource Identifier) 스키마인 HTTPS는 HTTP 스키마와 사용 구문이 동일합니다. 하지만 HTTPS 트래픽을 보호하기 위해 추가된 SSL/TLS 암호화 계층을 사용하도록 브라우저에 신호를 보냅니다. SSL/TLS는 특히 HTTP에 적합합니다. 때문에 이것은 비록 통신이 하나의 측면만 인증되더라도 어떠한 보호를 제공 할 수 있습니다. 이것은 일반적으로 서버만 인증되는 인터넷을 통한 HTTP 트랜잭션의 경우입니다. (클라이언트가 서버의 인증서를 검사함).
HTTPS는 안전하지 않은 네트워크를 통해 보안 채널을 만듭니다. 이는 적절한 암호 제품군이 사용되고 서버 인증서가 확인되고 신뢰할 수 있는 경우 변조와 man-in-the-middle 공격으로부터 합리적은 보호를 보장합니다.
HTTPS는 TLS위에 HTTP를 완전히 피기백하기 때문에 기본 HTTP 프로토콜 전체를 암호화 할 수 있습니다. 여기에는 요청 URL(특정 웹 페이지가 요청됨), 쿼리 매개변수, 헤더 및 쿠키 (종종 사용자에 대한 식별 정보가 포함됨)가 포함됩니다. 그러나 웹사이트 주소와 포트 번호는 반드시 기본 TCP/IP 프로토콜의 일부이기 때문에 HTTPS는 이러한 공개를 보호할 수 없습니다. 실제로 이것은 올바르게 구성된 웹서버에서도 도청자가 웹서버의 IP 주소와 포트 번호, 때로는 도메인 이름(예: www.example.org, URL의 나머지 부분은 아님)을 유추할 수 있음을 의미합니다. 사용자는 전송된 데이터의 양 및 통신 기간과 함께 통신하지만 통신 내용은 아닙니다.
웹 브라우저는 소프트웨어에 사전 설치된 인증 기관을 기반으로 HTTPS 웹 사이트를 신뢰하는 방법을 알고 있습니다. 인증 기관은 유효한 인증서를 제공하기 위해 웹 브라우저 작성자에 의해 이러한 방식으로 신뢰됩니다. 따라서 사용자는 다음 사항에 모두 해당하는 경우에만 웹사이트에 대한 HTTPS 연결을 신뢰해야합니다.
- 사용자는 브라우저 소프트웨어가 올바르게 사전 설치된 인증 기관과 함께 HTTPS를 올바르게 구현한다고 신뢰합니다.
- 사용자는 합법적인 웹사이트에 대해서만 보증하는 인증 기관을 신뢰합니다.
- 웹사이트는 신뢰할 수 있는 기관에서 서명한 유효한 인증서를 제공합니다.
- 인증서가 웹사이트를 올바르게 식별합니다.(예 브라우저가 "https://example.com" 을 방문할 때 수신된 인증서는 다른 엔티티가 아닌 에 "example.com" 대해 적절함.)
- 사용자는 프로토콜으 암호화 계층(SSL/TLS)이 도청자로부터 충분히 안전하다고 믿습니다.
HTTPS는 안전하지 않은 네트워크와 변조의 대상이 될 수 있는 네트워크에서 특히 중요합니다. 공용 Wi-Fi 액세스 포인트와 같은 안전하지 않은 네트워크를 사용하면 동일한 로컬 네트워크에 있는 모든 사용자가 패킷을 스니핑하고 HTTPS로 보호되지 않는 민감한 정보를 검색 할 수 있습니다. 또한 일부 무료 및 유료 WLAN 네트워크는 다른 웹사이트에 자체 광고를 게재하기 위해 패킷 주입에 참여하여 웹페이지를 변조 하는 것으로 관찰되었습니다.
이 관행은 웹페이지에 멀웨어를 삽입하고 사용자의 개인 정보를 훔치는 등 다양한 방법으로 악의적으로 악용될 수 있습니다.
HTTPS는 Tor 네트워크를 통해 연결에도 중요합니다. 그렇지 않으면 악의적인 Tor 노드가 안전하지 않은 방식으로 이를 통과하는 콘텐츠를 손상시키거나 변경하고 멀웨어를 주입할 수 있기 때문입니다. 이것이 Electronic Frontier Foundation과 Tor 프로젝트가 Tor 브라우저에 포함된 HTTPS Everywhere 개발을 시작한 이유 중 하나입니다.
글로벌 대규모 감시 및 개인 정보 도용 범죄자에 대한 정보가 더 많이 공개됨에 따라 사용되는 인터넷 연결 유형에 관계없이 모든 웹 사이트에서 HTTPS 보안을 사용하는 것이 점점 더 중요해지고 있습니다. 사용자가 방문하는 개별 페이지에 대한 메타데이터는 민감한 것으로 간주되지 않을 수 있지만 집계되면 사용자에 대한 많은 정보가 노출되고 사용자의 개인정보가 손상될 수 있습니다.
또한 HTTPS를 배포하면 페이지 로드 시간, 크기 및 대기 시간을 줄이도록 설계된 차세대 HTTP인 HTTP/2(또는 그 이전 버전인 SPDY 프로토콜)를 사용할 수 있습니다.
HSTS(HTTP Strict Transport Security)를 HTTPS와 함께 사용하여 메시지 가로채기(main-in-the-middle) 공격, 특히 SSL 스트리핑으로부터 사용자를 보호하는 것이 좋습니다.
HTTPS는 RFC 2660에 지정된 거의 사용되지 않는 보안(S-HTTP)와 혼동되어서는 안됩니다.
4. 웹사이트에서 HTTPS 사용률
2018년 4월 기준 Alexa 상위 100만개 웹사이트 중 33.2% HTTPS를 기본으로 사용하고 있습니다. 인터넷에서 가장 유명한 137,971개의 사이트에서 57.1%가 HTTPS의 암호화를 구현하였습니다. 그리고 파이어폭스 원격 측정에서 70%의 페이지가 HTTPS를 사용하고있습니다.
5. 브라우저 통합
대부분 브라우저는 만약 그들이 유효하지 않은 인증서를 받았을 경우 경고를 표시합니다. 예전 브라우저들은 유효하지 않은 인증서와 함께 접속할 때 사용자에게 계속 진행을 원하는지 묻는 다이얼로그를 표시했습니다. 새로운 브라우저들은 다이얼로그가 아닌 페이지 전체에 경고를 표시하는것으로 변경되었습니다. 새로운 브라우저들은 또한 사이트의 보안 정보를 주소창에 두드러지게 표시합니다. 확장된 유효 인증서는 인증 정보에 적법한 단체 보여줍니다. 대부분 브라우저는 또한 암호화되고 그렇지 않은 혼합된 컨텐츠가 포함된 웹사이트에 접속 할 때 사용자에게 경고를 표시합니다. 추가적으로 많은 웹 필터들은 사용자가 금지된 웹사이트에 방문했을 때 보안 경고를 합니다.
Electronic Frontier Foundation은 "이상적은 세계는 모든 웹이 기본적으로 HTTPS를 사용하는 것입니다." 라고 주장하며 모질라, 파이어폭스, 구글, 크롬 및 안드로이드용 HTTPS Everywhere라는 애드온을 제공했습니다. 이 애드온은 자주 사용하는 수백개의 웹사이트에 기본적으로 HTTPS를 활성화합니다.
웹 브라우저에서 HTTPS 콘텐츠만 로드하도록 강제하는 기능은 Firefox 버전 83부터 지원되었습니다.
https://en.wikipedia.org/wiki/HTTPS
6. 보안
HTTPS의 보안은 근본적으로 TLS 입니다. 이것은 전형적으로 장기간 공개및 개인키를 사용 세션키를 만들어 서버와 클라이언트 사이에 데이터흐름을 암호화 하는데 사용하는 단기간의 세션키를 만듭니다. X.509 인증서가 서버에(때로는 클라이언트에) 인증하는데 사용됩니다. 결과적으로 인증서 권한들과 공개 키 인증서는 인증서와 그것의 주인 사이 관계 또한 사인을 생성, 인증서의 유효성 관리 를 인증하는것을 필요합니다. 이는 trust of web을 통해 신원을 확인하는 것보다 더 유리할 수 있지만 2013년 대량 감시 공개는 메시지 가로채기 공격을 허용하는 잠재적인 약점으로 인증기관의 주의를 끌었습니다. 이 맥락에서 중요한 속성은 순방향 비밀성으로, 과거에 기록된 암호화된 통신을 검색하고 해독할 수 없도록 하여 미래에 장기 비밀 키나 암호가 손상될 경우 해독할 수 있습니다. 모든 웹 서버가 순방향 비밀성을 제공하는 것은 아닙니다.
HTTPS가 유효하려면 사이트가 HTTPS를 통해 완전히 호스팅되어야 합니다. 사이트 콘텐츠 중 일부가 HTTP(예: 스크립트 또는 이미지)를 통해 로드되거나 로그인 페이지와 같은 민감한 정보가 포함된 특정 페이지만 HTTPS를 통해 로드되고 나머지 사이트는 로드되는 경우 일반 HTTP를 통해 사용자는 공격 및 감시에 취약합니다. 또한 HTTPS를 통해 제공되는 사이트의 쿠키에는 보안 속성이 활성화되어 있어야 합니다. 민감한 정보가 있는 사이트에서는 HTTPS대신 HTTP를 사용하여 해당 사이트에 액세스할 때마다 사용자와 세션이 노출됩니다.
-----------
[안드로이드 개인프로젝트][HTTPS][2] WAS에 자체 서명된 SSL 인증서 설정하기
1. 스프링 프로젝트에 HTTPS 활성화 하기
2. 자체 서명된 인증서 사용하기
3. 자체 서명된 인증서와 Shell
1. 스프링부터 프로젝트에 HTTPS 활성화하기
기본적으로 REST의 앤드포인트는 일반형식의 HTTP를 전송으로 사용합니다. 여러분은 skipper.yml과 같은 환경 구성파일에 인증서를 추가하여 쉽게 HTTPS로 전환할 수 있습니다.
server:
port: 8443 1
ssl:
key-alias: yourKeyAlias 2
key-store: path/to/keystore 3
key-store-password: yourKeyStorePassword 4
key-password: yourKeyPassword 5
trust-store: path/to/trust-store 6
trust-store-password: yourTrustStorePassword 7
1. 기본 포트는 7577이므로 포트를 더 일반적인 HTTPs-전형 포트로 변경하도록 선택할 수 있습니다.
2. 키 저장소에 키가 저장되는 별칭(또는 이름)입니다.
3. 키 저장소 파일의 경로입니다. classpath 접두사를 사용하여 클래스 경로 리소스를 지정할 수도 있습니다. classpath:path/to/keystore
4. 키 저장소의 암호입니다.
5. 키의 암호입니다.
6. 신뢰 저장소 파일의 경로입니다. classpath 접두사를 사용하여 클래스 경로 리소스를 지정할 수도 있습니다. classpath:path/to/trust-store
7. 신뢰 저장소의 암호입니다.
HTTPS가 활성화되면 REST 엔드포인트가 상호 작용하는 프로토콜로 HTTP를 완전히 대체합니다. 일반 HTTP 요청은 실패하므로 이에 따라 Skipper Shell을 구성해야 합니다.
2. 자체 서명된 인증서 사용하기
테스트 목적으로 또는 개발 중에 자체 서명된 인증서를 만드는 것이 편리할 수 있습니다. 시작하려면 다음 명령을 실행하여 인증서를 만듭니다.
$ keytool -genkey -alias skipper -keyalg RSA -keystore skipper.keystore \
-validity 3650 -storetype JKS \
-dname "CN=localhost, OU=Spring, O=Pivotal, L=Holualoa, ST=HI, C=US"
-keypass skipper -storepass skipper
CN은 여기서 유일하게 중요한 매개변수입니다. 액세스하려는 도메인과 일치해야 합니다. 예) 로컬 호스트.
그런 다음 skipper.yml 파일에 다음을 추가합니다.
server:
port: 8443
ssl:
enabled: true
key-alias: skipper
key-store: "/your/path/to/skipper.keystore"
key-store-type: jks
key-store-password: skipper
key-password: skipper
이것은 Skipper 서버에 필요한 전부입니다. 서버를 시작하면 https://localhost:8443/을 통해 서버에 액세스할 수 있어야 합니다. 이것은 자체 서명된 인증서이므로 브라우저에서 무시해야 하는 경고가 표시됩니다.
3. 자체 서명된 인증서와 Shell
기본적으로 자체 서명된 인증서는 Shell을 위해 발생 된 것이며 Shell이 자체 서명된 인증서와 함께 작동하도록 하려면 추가적인 단계가 필요합니다. 두 가지 옵션을 사용할 수 있습니다.
- JVM 신뢰 저장소에 자체 서명된 인증서 추가
- 인증서 유효성 검사 건너뛰기
자체 서명된 인증서를 JVM 신뢰 저장소에 추가
JVM 신뢰 저장소 옵션을 사용하려면, 우리는 이전에 keystore로부터 생성된 인증서를 추출 해야합니다.
$ keytool -export -alias skipper -keystore skipper.keystore -file skipper_cert -storepass skipper
다음, 우리는 다음 Shell에서 사용한 신뢰저장소 생성이 필요합니다.
keytool -importcert -keystore skipper.truststore -alias skipper -storepass skipper -file skipper_cert -noprompt
이제 여러분은 Skipper Shell이 다음 JVM 인수를 사용하는 것을 시작할 준비가 되었습니다.
$ java -Djavax.net.ssl.trustStorePassword=skipper \
-Djavax.net.ssl.trustStore=/path/to/skipper.truststore \
-Djavax.net.ssl.trustStoreType=jks \
-jar spring-cloud-skipper-shell-1.0.0.BUILD-SNAPSHOT.jar
SSL을 통해 연결을 설정하는 데 문제가 있는 경우 javax.net.debug JVM 인수를 사용하고 ssl로 설정하여 추가 로깅을 활성화할 수 있습니다.
다음을 사용하요 Skipper 서버를 대상으로 지정하는 것을 잊지 마십시오.
skipper:>skipper config --uri https://localhost:8443/api
인증서 유효성 검사 건너뛰기
다른 대안으로 여러분은 또한 다음 선택적 명령줄에 매개 변수를 제공하여 인증서 유효성 검사를 건너뛸 수 있습니다.
--spring.cloud.skipper.client.skip-ssl-validation=true
이 명령줄 매개변수를 사용하여 Shell은 (자체 서명된) SSL 인증서를 수락합니다.
만약 가능하다면 여러분은 이 선택사항을 피해야합니다. trust manager을 비활성화 하는 것은 SSL의 목적이 무효화되고 메시지 가로채기(man-in-the-middle) 공격에 취약해집니다.
---------------------------
[안드로이드 개인프로젝트][HTTPS][3] 안드로이드 에서 HTTPS 이해
1. 개요
2. 콘셉트
3. HTTPS 예제
4. 서버 인증서를 확인하는 일반적인 문제
5. SSLSocket 직접 사용에 대한 경고
6. 거부 리스트
7. 고정(Pinning)
8. 클라이언트 인증서
9. Nogotofail: 네트워크 트래픽 보안 테스트 도구
1. 개요
SSL(Secure Socket Layer, 보안 소켓 레이어) - 현재는 기술적으로 TLS(Transport Layer Security, 전송 보안 계층)로 알려짐 - 은 클라이언트와 서버 간 암호화된 소통 위한 일반적인 빌딩블록입니다. 이것은 애플리케이션이 SSL을 악의적인 엔티티가 네트워크를 통해 앱의 데이터를 가로채는것과같이 올바르지 않게 사용하게할 가능성이 있습니다. 여러분이 이것이 여러분의 앱에 발생하지 않도록 보증하는것을 돕는것은 이 글에서 보안 네트워크 프로토콜사용하고 PKI(Public-Key Infrastructure) 사용 대한 어떤 커다란 걱정 보낼 할 때 일반적인 위험 강조합니다.
여러분은 또한 Android Security Overview 를 Permissions Overview 와 마찬가지로 읽어야 합니다.
2. 콘셉트
전형적으로 SSL은 서버의 공개키 뿐만아니라 개인키도 포함하고있는 인증서와 함께 구성된 시나리오를 사용합니다. 클라이언트와 서버사이 핸드쉐이크 부분으로서 서버는 공개키 암호화와 함께 인증서를 서명 함으로써 개인키를 가지고 있음을 증명합니다.
그러나 누구나 자신의 인증서와 개인 키를 생성할 수 있으므로 간단한 핸드셰이크는 서버가 인증서의 공개 키와 일치하는 개인 키를 알고 있다는 점 외에는 서버에 대해 아무 것도 증명하지 않습니다. 이 문제를 해결하기위한 한가지 방법은 클라이언트가 하나 이상의 신뢰된 인증서를 갖도록 하는 것 입니다. 만약 인증서가 세트에 없으면 서버를 신뢰 할 수 없습니다.
이 단순한 접근은 여러가지 불리한 면이 있습니다. 서버는 시간이 지남에 따라 인증서에서 새로운 인증서와 함께 공개키로 교체 할 강력한 키(키 교환)를 업그레이드를 해야합니다. 불행하게도 현재 본질적으로 서버 구성 변경으로 인해 클라이언트 앱은 업데이트를 해야만합니다.예를들면 만약 이것이 써드파티 웹 서비스 일 경우와 같이 이것은 만약 서버가 앱 개발자의 통제하가 아니라면 특히 문제입니다. 만약 앱이 웹브라우저 또는 이메일 앱과같은 같은 제멋대로인 서버와 대화해야한다면 이 접근은 또한 문제를 가집니다.
이 불합리한면을 해결하기위해 서버는 일반적으로 CAs(Certificate Authoritiess)라 불리는 잘 알려진 발행자 로부터 인증서와 함께 구성됩니다. 호스트 플랫폼은 일반적으로 잘알려진 신뢰된 CAs 리스트를 포함합니다. 안드로이드8.0(API level 26)로서 안드로이드는 100개 이상의 각 배포에서 업데이트되고 기기간으로 부터 교환하지 않는 CA를 포함합니다. 서버와 비슷하게 CA는 인증서와 비밀키를 갖습니다. 서버를 위해 인증서를 발행하는 것은 CA가 그들의 개인키를 사용하여 서버 인증서에 서명합니다. 클라이언트는 서버가 인증서를 플랫폼을 통해 알려진 CA로부터 발행된 갖는것을 검증 할 수 있습니다.
그러나 일부 문제를 해결하는 동안 CA를 사용하면 다른 문제가 발생합니다. CA가 많은 서버에 대한 인증서를 발급하기 때문에 여러분은 여전히 서버와 대화를 원하는 확인해야하는 어떤 방법이 필요합니다. 이것을 해결하기위해 인증서는 CA가 gmail.com 또는 와일드카드가 설정된 *.google.com 과 같은 각 서버의 상세 이름을 식별함으로써 발급됩니다.
다음 예제는 이 컨셉 조금더 상세히 만들 것 입니다. 아래있는 명령어 라인에 스니핏인 openssl 툴의 s_client 명령은 위키피디아 서버의 인증서 정보로 보입니다. HTTPS의 기본이기 때문에 이것의 상세 포트는 443 입니다. 명령어는 openssl s_client의 출력을 포맷들은 X.509 표준 인증서에대한 정보인 openssl x509에 보냅니다. 특히 명령어는 서버명 정보, CA 식별자인 발행자를 담고있는 대상에대해 묻습니다.
$ openssl s_client -connect wikipedia.org:443 | openssl x509 -noout -subject -issuer
subject= /serialNumber=sOrr2rKpMVP70Z6E9BT5reY008SJEdYv/C=US/O=*.wikipedia.org/OU=GT03314600/OU=See www.rapidssl.com/resources/cps (c)11/OU=Domain Control Validated - RapidSSL(R)/CN=*.wikipedia.org
issuer= /C=US/O=GeoTrust, Inc./CN=RapidSSL CA
여러분은 또한 RapidSSL CA의 *.wikipedia.org와 매치되는 서버를 위한 인증서가 발행된 것을 볼 수 있습니다.
3. HTTPS 예제
여러분이 웹서버와 잘 알려진 CA로부터 발행된 인증서가 있는것을 가정하면, 여러분은 다음에 간단한 예제 코드와 함께 보안 요청을 만들 수 있습니다.
val url = URL("https://wikipedia.org")
val urlConnection: URLConnection = url.openConnection()
val inputStream: InputStream = urlConnection.getInputStream()
copyInputStreamToOutputStream(inputStream, System.out)
그렇습니다. 이것은 정말 단순합니다. 만약 여러분이 잘 만들어진 HTTP 요청을 원한다면, 여러분은 HttpURLConnection으로 변경 할 수 있습니다. HttpUrlConnection을 위한 안드로이드 문서는 어떻게 요청과 응답, 내용을 포스팅하는것, 쿠키를 관리하는것, 프록시를 사용하는것, 응답을 캐치하는 등 에대한 처리를 하는지 더욱 많은 예제를 가지고 있습니다. 하지만 인증서와 호스트명에 유효성을 위한 상세한 조건에서, 안드로이드 프레임워크는 이 API를 통해 여러분을 위해 이것을 보호합니다. 이것은 가능하다면 여러분이 있고 싶은 곳입니다. 즉, 아래에 몇 가지 다른 고려 사항이 있습니다.
4. 서버 인증서를 확인하는 일반적인 문제
가정하면 getInputStream()으로부터 내용을 받는것 대신에, 이것은 예외를 발생합니다.
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
이것은 다음과 같은 여러가지 이유로 발생 할 수 있습니다.
1. 발행된 서버 인증서가 알려지지않은 CA 일 경우
2. 서버 인증서가 CA로부터 사인되지 않고 스스로 사인한 경우
3. 서버 구성파일에 중간 CA가 없는 경우
다음 섹션은 여러분의 서버 보안에 접속을 유지하는 동안 어떻게 이문제들을 해결하는지 논의합니다.
알 수 없는 인증 기관
이러한 경우 SSLHandshakeException이 여러분이 가지고 있는 시스템으로부터 신뢰할 수 없는 CA 인증서 때문에 발생합니다. 이것은 안드로이드 또는 여러분의 실행하고있는 이전 버전에서 아직 신뢰되지 않은 새로운 CA 로부터 여러분이 가지고있는 인증서 때문에 될 수 있습니다. CA는 공용 CA가 아니라 정부, 기업 또는 교육 기관과 같은 조직에서 자체적으로 사용하기 위해 발급한 사설 CA이기 때문에 알려지지 않은 경우가 더 많습니다.
다행히도 응용 프로그램 내부의 코드를 수정할 필요 없이 응용 프로그램의 네트워크 보안 구성을 구성하여 사용자 지정 CA를 신뢰하도록 응용 프로그램을 가르칠 수 있습니다.
주의: 많은 웹사이트들은 아무것도 아닌 TrustManager을 설치하는 안좋은 해결 방법을 설명합니다. 만약 여러분이 이것을 한다면 여러분의 통신은 암호화 될 수 없습니다. 왜냐하면 누구나 DNS 트릭을 사용하여 서버인 것처럼 가장하는 자체 프록시를 통해 사용자 트래픽을 전송함으로써 공용 Wi-Fi 핫스팟에서 사용자를 공격할 수 있기 때문입니다. 공격자는 비밀번호와 다른 개인적인 데이터를 저장 할 수 있습니다. 이것은 공격자가 신뢰된 소스로부터 인증서가오는-여러분의 앱이 누구화 대화 할 수 있는- 실제로 유효한 TrustManager없이 인증서를 생성할 수 있기 때문에 동작합니다.
자체 서명된 서버 인증서
SSLHandShakeException의 두번째 케이스는 이것은 서버가 스스로 CA임을 의미하는 자체 서명된 인증서 때문입니다. 이것은 여러분은 이전 섹션과 똑같은 접근을 사용 할 수 있는 알려지지 않은 인증서 권한 비슷합니다.
여러분의 애플리케이션이 자체 서명된 인증서에 신뢰를 갖기위해는 여러분은 또한 여러분 애플리케이션의 네트워크 보안 환경을 설정 할 수 있습니다.
중간 인증 기관 누락
SSLHandShakeException의 세번째 케이스는 중간 인증기관 누락으로 발생하는 것입니다. 가장 공공의 CA는 서버 인증서에 바로 사인하지 않습니다. 대신에 그들은 루트 CA를 참조함으로써 중간 CA에 사인 할 그들의 메인 CA 인증서를 사용합니다. 루트 CA가 손상 위험을 줄이기 위해 오프라인으로 저장될 수 있도록 하기 위해 이 작업을 수행합니다. 하지만 안드로이드와같은 운영체제는 전형적으로 루트 CA 만을 신뢰합니다. 그러나 Android와 같은 운영 체제는 일반적으로 루트 CA만 직접 신뢰하므로 중간 CA에서 서명한 서버 인증서와 루트 CA를 알고 있는 인증서 검증자 사이에 짧은 신뢰 격차가 있습니다. 이 문제를 해결하기 위해 서버는 SSL 핸드셰이크 중에 클라이언트에게 인증서만 보내지 않고 신뢰할 수 있는 루트 CA에 도달하는 데 필요한 중간체를 통해 서버 CA에서 인증서 체인을 보냅니다.
이것이 실제로 어떻게 보이는지 보려면 openssl s_client 명령으로 볼 때 mail.google.com 인증서 체인이 있습니다.
$ openssl s_client -connect mail.google.com:443
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google LLC/CN=mail.google.com
i:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
1 s:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
---
이것은 서버가 중간 CA인 Thawte SGC CA에서 발급한 mail.google.com에 대한 인증서를 보내고 안드로이드로부터 신뢰된 주요 CA인 Verisign CA에서 발급한 Thawte SGC CA에 대한 두 번째 인증서를 보낸다는 것을 보여줍니다.
하지만 이것은 필수 중간CA를 포함하지 않는 서버에 구성하기 일반적이지 않습니다. 예를들면 이곳은 안드로이드 브라우저에서 에러와 앱에서 예외가 발생 할 수 있는 서버입니다.
$ openssl s_client -connect egov.uscis.gov:443
---
Certificate chain
0 s:/C=US/ST=District Of Columbia/L=Washington/O=U.S. Department of Homeland Security/OU=United States Citizenship and Immigration Services/OU=Terms of use at www.verisign.com/rpa (c)05/CN=egov.uscis.gov
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 International Server CA - G3
---
주목할 흥미로운 것은 이곳은 이 대부분 데스크탑 브라우저에서 서버 완전이 알려지지 않은 CA 와같은 에러를 발생하지않게 방문하는것 입니다. 이것은 대부분 데스크탑 브라우저 캐시가 시간이 지남에따라 중간 CA 신뢰 했기 때문입니다. 브라우저가 한 사이트를 방문하여 중간 CA에 대해 알게 되면 다음 번에 인증서 체인에 중간 CA를 포함할 필요가 없습니다.
일부 사이트는 리소스를 제공하는 데 사용되는 보조 웹 서버를 위해 의도적으로 이 작업을 수행합니다. 예를 들어, 전체 인증서 체인이 있는 서버에서 기본 HTML 페이지를 제공할 수 있지만 이미지, CSS 또는 JavaScript와 같은 리소스용 서버에는 대역폭을 절약하기 위해 CA가 포함되지 않습니다. 불행히도 때때로 이러한 서버는 사용자가 Android 앱에서 호출하려는 웹 서비스를 제공할 수 있지만 이는 그다지 관대하지 않습니다.
이 문제를 해결하기위해 서버체인에 중간CA를 포함하여 서버에 설정합니다. 대부분 CA들은 모든 웹서버를 위해 이것들을 어떻게 하는지 문서를 제공합니다.
5. SSLSocket 직접 사용에 대한 경고
지금까지 예제는 HttpsURLConnection을 사용하는 HTTPS에 중점을 두었습니다. 때떄로 앱은 HTTP로부터 분리된 SSL사용을 필요로 합니다. 예를들면 이메일 앱은 SMTP SMTP, POP3, IMAP의 SSL 변수를 사용할 수 있습니다. 이런 경우 앱은 HttpUrlConnection에서 내부적으로 동작하는 것과 같은 방법인 직접적으로 SSLSocket를 필요로 합니다.
인증서 확인 문제를 처리하기 위해 지금까지 설명한 기술은 SSLSocket에도 적용됩니다. 실제로 사용자 정의 TrustManager를 사용할 때 HttpsURLConnection에 전달되는 것은 SSLSocketFactory입니다. 그래서 만약 여러분이 SSLSocket 사용자 정의 TrustManager가 필요로 할 때 같은 스탭을 따르고 SSLSocketFactory가 여러분의 SSLSocket를 생성하는 것을 사용합니다.
주의: SSLSocket은 호스트명 확인을 수행하지 않습니다. 예상 호스트 이름으로 getDefaultHostnameVerifier()를 호출하여 자체 호스트 이름 확인을 수행하는 것은 앱에 달려 있습니다. HostnameVerifier.verify()는 오류 시 예외를 발생시키지 않고 대신 명시적으로 확인해야 하는 부울 결과를 반환합니다.
6. 거부 리스트
SSL은 CA에 크게 의존하여 제대로 확인된 서버 및 도메인 소유자에게만 인증서를 발급합니다. 드물게 CA는 트릭에 당하거나 드문 경우지만 CA가 속임을 당하거나 Comodo 또는 DigiNotar의 경우 위반되어 호스트 이름에 대한 인증서가 서버 또는 도메인 소유자가 아닌 다른 사람에게 발급됩니다.
이 위험을 완화하기 위해 Android는 특정 인증서 또는 전체 CA를 거부 목록에 추가할 수 있습니다. 이 항목들이 역사적으로 운영체제에 탑제되는 동안 Android4.2에 이 리스트를 시작하는것은 원격으로 업데이트 될 수 있습니다. 이 목록은 역사적으로 운영 체제에 구축되었지만 Android 4.2부터 이 목록을 원격으로 업데이트하여 향후 손상을 처리할 수 있습니다.
7. 고정(Pinning)
주의: 다른 인증 기관으로 변경하여 애플리케이션이 클라이언트 소프트웨어 업데이트를 받지 않고 서버에 연결할 수 없도록 하는 등 향후 서버 구성 변경의 위험이 높기 때문에 Android 애플리케이션에는 인증서 고정을 사용하지 않는 것이 좋습니다.
만약 여러분이 어플리케이션에 고정을 원한다면 다중 백업핀으로 포함하는것은 치명적입니다. 애플리케이션을 고정하려면 완전히 제어할 수 있는 하나 이상의 키와 호환성 문제를 방지하기 위해 충분히 짧은 만료 기간을 포함하여 여러 백업 핀을 포함하는 것이 중요합니다. Network Security Config는 이러한 기능으로 고정을 제공합니다.
8. 클라이언트 인증서
이 문서는 SSL의 사용자가 서버와의 통신을 안전하게 하는 것 에 집중했습니다. SSL은 또한 서버가 클라이언트의 ID를 확인할 수 있도록 하는 클라이언트 인증서의 개념을 지원합니다. 이 문서의 범위를 벗어나지만 관련된 기술은 사용자 지정 TrustManager를 지정하는 것과 유사합니다.
9. Nogotofail: 네트워크 트래픽 보안 테스트 도구
Nogotofail은 알려진 TLS/SSL 취약성 및 잘못된 구성에 대해 앱이 안전한지 쉽게 확인할 수 있는 도구입니다. 네트워크 트래픽이 통과할 수 있는 모든 장치에서 네트워크 보안 문제를 테스트하기 위한 강력하고 확장 가능한 자동화 도구입니다.
Nogotofail은 세 가지 주요 사용 사례에 유용합니다.
- 버그 및 취약점을 찾습니다.
- 수정 사항을 확인하고 회귀를 관찰합니다.
- 어떤 애플리케이션과 장치가 어떤 트래픽을 생성하는지 이해합니다.
Nogotofail은 Android, iOS, Linux, Windows, Chrome OS, OSX, 실제로 인터넷에 연결하는 데 사용하는 모든 장치에서 작동합니다. 라우터, VPN 서버 또는 프록시로 배포할 수 있는 공격 엔진 자체뿐만 아니라 Android 및 Linux에서 설정을 구성하고 알림을 받을 수 있는 사용하기 쉬운 클라이언트가 있습니다.
Nogotofail 오픈 소스 프로젝트(Nogotofail open source project)에서 도구에 액세스할 수 있습니다.
https://developer.android.com/training/articles/security-ssl?hl=en
--------
[안드로이드 개인프로젝트][HTTPS][4] 안드로이드 에서 HTTPS 적용하기
목차
1. 안드로이드 API 통신 주소 https로 변경 후 오류 발생
2. 문제점 예상
3. 해결방법
4. 사용자지정 CA를 신뢰하도록 네트워크 보안 구성하기
5. 사용자지정 CA를 신뢰하도록 네트워크 보안 구성한 후 두번째 오류 발생
6. 문제점 예상
7. 구글링 해결방법 적용
8. 마무리
1. 안드로이드 API 통신 주소 https로 변경 후 오류 발생
기존에 http 통신을 사용하다 이번에 페이스북 로그인 API 사용 정책과 관련하여 https를 반드시 도입해야하는 상황이 생겼습니다. 웹앱플리케이션 서버에 인증서를 만들어 https를 설정하는것까지 성공 후 안드로이드에 통신하는 주소를 https로 변경했습니다. 변경 후 먼저 다음과 같은 에러가 발생했습니다.
HTTP FAILED: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
오류 내용을 보면 인증서를 위한 트러스트 앵커의 경로가 없다고 나옵니다. 트러스트 앵커애 대해 검색해봤지만 아래 내용가지고는 아직 정확하게 이해가 되지 않습니다. 대략 인증서라고 하는 것 같습니다.
trust anchor(트러스트 앵커)
X.509 인증서에서 인증 기관의 루트 인증서입니다. 루트 인증서에서 최종 인증서까지의 인증서로 트러스트 체인이 설정됩니다.
출처: https://docs.oracle.com/cd/E56343_01/html/E53812/netsecgloss-1.html#NWSECnetsecgloss-3
트러스트 앵커 란 무엇입니까?
뿌리 인증 기관 (CA) 는 트러스트 앵커 신뢰의 사슬에서. 이 트러스트 앵커의 유효성은 체인 전체의 무결성에 매우 중요합니다. CA가 공개적으로 신뢰할 수있는 (SSL.com과 같은) 루트 CA 인증서는 주요 소프트웨어 회사의 브라우저 및 운영 체제 소프트웨어에 포함되어 있습니다. 이 포함은 CA의 루트 인증서로 돌아가는 신뢰 체인의 인증서를 소프트웨어에서 신뢰할 수 있도록합니다.
출처: https://www.ssl.com/ko/%EC%9E%90%EC%A3%BC-%EB%AC%BB%EB%8A%94-%EC%A7%88%EB%AC%B8/%EC%9D%B8%EC%A6%9D-%EA%B8%B0%EA%B4%80%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C/
2. 문제점 예상
HTTP 통신에서 세션을 맺는 과정에서 HandShake 절차가 진행되는데 이때 서버로 부터 인증서를 받고 이 인증서가 신뢰 할 수 있는 인증서인지 검증하는 과정이 필요한데 현재 앱에는 이 인증서를 검증할만한 설정이 되어있지 않다고 판단하였습니다.
3. 해결방법
안드로이드 공식 사이트에 이와 관련되 문제를 해결하는 방법이 나와있었습니다. 제가 만든 인증서는 자체 발급한 인증서를 사용하고 있어 안드로이드 시스템에서 신뢰 할 수 없는 것 같습니다. 이를 해결하기위해서는 안드로이드에 네트워크 보안 구성을 사용자 지정 CA로 하는 방법이 있어 이 방법을 적용하면 될 것 같습니다.
이것은 다음과 같은 여러가지 이유로 발생 할 수 있습니다.
1. 발행된 서버 인증서가 알려지지않은 CA 일 경우
2. 서버 인증서가 CA로부터 사인되지 않고 스스로 사인한 경우
3. 서버 구성파일에 중간 CA가 없는 경우
다음 섹션은 여러분의 서버 보안에 접속을 유지하는 동안 어떻게 이문제들을 해결하는지 논의합니다.
알 수 없는 인증 기관
이러한 경우 SSLHandshakeException이 여러분이 가지고 있는 시스템으로부터 신뢰할 수 없는 CA 인증서 때문에 발생합니다. 이것은 안드로이드 또는 여러분의 실행하고있는 이전 버전에서 아직 신뢰되지 않은 새로운 CA 로부터 여러분이 가지고있는 인증서 때문에 될 수 있습니다. CA는 공용 CA가 아니라 정부, 기업 또는 교육 기관과 같은 조직에서 자체적으로 사용하기 위해 발급한 사설 CA이기 때문에 알려지지 않은 경우가 더 많습니다.
다행히도 응용 프로그램 내부의 코드를 수정할 필요 없이 응용 프로그램의 네트워크 보안 구성(https://developer.android.com/training/articles/security-config#TrustingAdditionalCas)을 구성하여 사용자 지정 CA를 신뢰하도록 응용 프로그램을 가르칠 수 있습니다.
https://developer.android.com/training/articles/security-ssl?hl=en#CommonProblems
4. 사용자지정 CA를 신뢰하도록 네트워크 보안 구성하기
https://developer.android.com/training/articles/security-config
1. res/xml/network_security_config.xml
만들기
<network-security-config>
<domain-config>
<domain includeSubdomains="true">api 사용하는 도메인 ex)google.com</domain>
<trust-anchors>
<certificates src="@raw/my_ca"/>
<certificates src="system"/>
</trust-anchors>
</domain-config>
</network-security-config>
2. 안드로이드 매니페스트 파일에 네트워크 보안 환경 설정하기
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="@xml/network_security_config"
... >
...
</application>
</manifest>
인증서는 이 곳을 참조해 만들었습니다.
https://srandroid.tistory.com/425?category=1042293
아래 명령어를 실행하면 skipper이라는 인증서가 만들어지고 이 인증서를 안드로이드 raw폴더에 복사했습니다.
$ keytool -genkey -alias skipper -keyalg RSA -keystore skipper.keystore \
-validity 3650 -storetype JKS \
-dname "CN=localhost, OU=Spring, O=Pivotal, L=Holualoa, ST=HI, C=US"
-keypass skipper -storepass skipper
5. 사용자지정 CA를 신뢰하도록 네트워크 보안 구성한 후 두번째 오류 발생
Hostname not verified 호스트 명이 확인되지 않는다고 합니다. 먼저 SSLPeerUnverifiedException에 대해서 알아봤습니다.
피어의 ID가 확인되지 않았음을 나타냅니다. 피어가 자신을 식별할 수 없는 경우(예: 인증서가 없거나, 사용 중인 특정 암호 제품군이 인증을 지원하지 않거나, SSL 핸드셰이킹 중에 피어 인증이 설정되지 않은 경우) 이 예외가 발생합니다.
https://developer.android.com/reference/javax/net/ssl/SSLPeerUnverifiedException
6. 문제점 예상
아쉽게도 정확한 원인은 잘 모르겠습니다. 예상은 SSL 핸드셰이킹 중에 피어 인증이 설정되지 않은 경우 라고 생각하고 있습니다. 핸드셰이킹 과정중에 호스트명을 확인하는게 있는데 그부분이 잘못된 것 같습니다. 인증서도 발생시 호스트명을 호출하는 url로 적었고 안드로이드 사용자 보안 네트워크 설정하는 부분에도 설정을 하였는데 해결이 되지 않았습니다.
-- 인증서 생성시
$ keytool -genkey -alias skipper -keyalg RSA -keystore skipper.keystore \
-validity 3650 -storetype JKS \
-dname "CN=API도메인, OU=Spring, O=Pivotal, L=Holualoa, ST=HI, C=US"
-keypass skipper -storepass skipper
-- 안드로이드 환경 설정에서
<domain includeSubdomains="true">API도메인 ex)google.com</domain>
안드로이드에서 사용자 CA를 사용할때는 호스트명을 확인하는 과정을 수동으로 설정해야하는 것 같습니다.(정확하지 않음)
주의: SSLSocket은 호스트명 확인을 수행하지 않습니다. 예상 호스트 이름으로 getDefaultHostnameVerifier()를 호출하여 자체 호스트 이름 확인을 수행하는 것은 앱에 달려 있습니다. HostnameVerifier.verify()는 오류 시 예외를 발생시키지 않고 대신 명시적으로 확인해야 하는 부울 결과를 반환합니다.
https://developer.android.com/training/articles/security-ssl?hl=en#WarningsSslSocket
7. 구글링 해결방법 적용
구글링에는 주로 그냥 true를 반환하게 해결책을 제시하고 있는데 로그를 찍어봤는데 p0(요청 호스트명) 과 p1 객체에 호스트명이 동일하여 저는 아래와 같이 수정하여 해결하였습니다.
httpClient.hostnameVerifier(object : HostnameVerifier{
override fun verify(p0: String?, p1: SSLSession?): Boolean {
Logger.d("!!!!!$p0")
Logger.d( "!!!!!${p1?.cipherSuite} \n" +
"${p1?.creationTime} \n" +
"${p1?.peerHost} \n" +
"${p1?.peerPort} \n" +
"${p1?.protocol} \n" +
"")
return p0.equals(p1?.peerHost)
}
})
8. 마무리
잘못 설정하면 앱이 잘릴 수 있다는데 시간관계상 일단 업로드해보고 다른 해결 방법을 찾아봐야겠습니다.
-------
[안드로이드 개인프로젝트][HTTPS][3] WAS에 공인 SSL 인증서 적용하기
1. goDaddy에 가입하여 호스트 및 SSL 인증서 구매하기
도메인과 SSL 인증서만 구매했으면됬었는데
그땐 왜그랬는지 cPanel이라는 제품을 구매해서 저기 안에 SSL인증서와 도메인까지 포함이 된다고 본 것 같아
17만원정도되는 비용을 지불하였습니다ㅠㅠ
구매하실때 도메인과 SSL인증서만 구매하시길 바랍니다. (약 7~8만원정도가 나올 것 같습니다.)
2. CSR(Certificate Signing Request, 인증서 서명 요청) 생성하기
CSR을 생성하기전에 신청자는 개인키를 생성해야합니다.
openssl genrsa -des3 -out vrscoo.com.key 2048
openssl req -new -key vrscoo.com.key > vrscoo.com.csr
CRS에 대한 자세한 정보에 대해 정리했습니다.(위키백과 참고)
https://srandroid.tistory.com/445
------
[안드로이드 개인프로젝트][HTTPS][5] Certificate Signing Request 이해
공개 키 기반 구조(Public Key Infrastructure, PKI) 시스템에서 인증서 서명 요청(Certificate Signing Request, CSR)은 디지털 신분증을 신청하기위해 신청자가 공개 키 인프라의 등록 기관으로 보내는 매시지입니다. 이것은 주로 인증서가 발행처, 신분정보(도메인과같은), 통합 보안(디지털 서명과 같은)에 대한 공개키를 담고있습니다. CRS의 가장 일반적인 포맷은 PKCS #10 스팩입니다. 또다른것은 Signed Public Key와 어떤 웹브라우저로부터 생성된 Challenge SPKAC 포맷 입니다.
1. 절차
CSR을 생성하기 전에, 신청자는 먼저 개인키를 간직하는 키-쌍을 생성해야합니다. CSR은 신청자의 개인키로 반드시 서명한 식별정보(X.509 인증서의 경우에 구별된 이름과같은)를 포함합니다. CSR은 또한 신청자로부터 선택된 공개키를 포함합니다. CSR은 또한 인증기관으로부터 요청된 식별자의 증거들 또는 다른 자격으로부터 동반 될 수 있습니다.
CSR에서 요청된 전형적인 정보(X.509 인증서 샘플로부터 샘플 컬럼인)입니다. DN(고유 이름)에 대한 대안이 있는 경우가 많으며 선호하는 값이 나열됩니다.
만약 요청이 성공적이라면, 인증 기관은 인증기관의 개인키를 사용하여 전자적으로 서명된 인증서를 보내줍니다.
2. 구조
인증서 요청은 3가지 메인 파트로 구성됩니다. 인증 요청 정보, 사인 알고리즘 그리고 인증 요청 정보에 디지털 사인 작성. 첫번째 파트는 공개키를 포함한 중요한 정보를 포함합니다. 요청자의 서명은 엔터티가 다른 사람의 공개 키에 대한 가짜 인증서를 요청하는 것을 방지합니다. 그러므로 개인키 생성을 필요로 합니다. 하지만 이것은 CSR의 파트가 아닙니다.
개인 ID 인증서 및 서명 인증서에 대한 CSR에는 비지니스 ID의 경우 조직의 이름 또는 ID 소유자의 이메일주소를 반드시 포함해야합니다.
첫 번째 부분인 ASN.1 유형 CertificationRequestInfo는 버전 번호(알려진 모든 버전의 경우 0, 사양의 1.0, 1.5 및 1.7), 주체 이름, 공개 키(알고리즘 식별자 + 비트 문자열), 인증서의 주제에 대한 추가 정보를 제공하는 속성 모음. 속성에는 필수 인증서 확장, 해지를 제한하기 위한 인증 확인 비밀번호, 로컬 또는 향후 유형을 포함하여 인증서 주제에 대한 추가 정보가 포함될 수 있습니다.
3. 예제
PKCS#10 표준은 X.509와 함께 사용한 CSR의 인코딩에 대한 바이너리 포맷을 정의합니다. 이것은 ASN.1로 표현됩니다. 다음은 OpenSSL을 사용하여 ASN.1 구조를 어떻게 시험 할 수 있는지 볼 수 있는 예제입니다.
openssl asn1parse -i -in your_request
아래 예제와 같이 CSR은 PKCS#10으로 인코딩된 Base64로서 표현됩니다.
-----BEGIN CERTIFICATE REQUEST-----
MIICzDCCAbQCAQAwgYYxCzAJBgNVBAYTAkVOMQ0wCwYDVQQIDARub25lMQ0wCwYD
VQQHDARub25lMRIwEAYDVQQKDAlXaWtpcGVkaWExDTALBgNVBAsMBG5vbmUxGDAW
BgNVBAMMDyoud2lraXBlZGlhLm9yZzEcMBoGCSqGSIb3DQEJARYNbm9uZUBub25l
LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMP/U8RlcCD6E8AL
PT8LLUR9ygyygPCaSmIEC8zXGJung3ykElXFRz/Jc/bu0hxCxi2YDz5IjxBBOpB/
kieG83HsSmZZtR+drZIQ6vOsr/ucvpnB9z4XzKuabNGZ5ZiTSQ9L7Mx8FzvUTq5y
/ArIuM+FBeuno/IV8zvwAe/VRa8i0QjFXT9vBBp35aeatdnJ2ds50yKCsHHcjvtr
9/8zPVqqmhl2XFS3Qdqlsprzbgksom67OobJGjaV+fNHNQ0o/rzP//Pl3i7vvaEG
7Ff8tQhEwR9nJUR1T6Z7ln7S6cOr23YozgWVkEJ/dSr6LAopb+cZ88FzW5NszU6i
57HhA7ECAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4IBAQBn8OCVOIx+n0AS6WbEmYDR
SspR9xOCoOwYfamB+2Bpmt82R01zJ/kaqzUtZUjaGvQvAaz5lUwoMdaO0X7I5Xfl
sllMFDaYoGD4Rru4s8gz2qG/QHWA8uPXzJVAj6X0olbIdLTEqTKsnBj4Zr1AJCNy
/YcG4ouLJr140o26MhwBpoCRpPjAgdYMH60BYfnc4/DILxMVqR9xqK1s98d6Ob/+
3wHFK+S7BRWrJQXcM8veAexXuk9lHQ+FgGfD0eSYGz0kyP26Qa2pLTwumjt+nBPl
rfJxaLHwTQ/1988G0H35ED0f9Md5fzoKi5evU1wG5WRxdEUPyt3QUXxdQ69i0C+7
-----END CERTIFICATE REQUEST-----
위의 인증서 사인 요청의 ASN.1 구조(openssl 로부터 파싱된)는 첫번째 숫자는 byte offset, d=depth, hl=현재 타입의header length, l=내용의 길이 로 나타냅니다.
0:d=0 hl=4 l= 716 cons: SEQUENCE
4:d=1 hl=4 l= 436 cons: SEQUENCE
8:d=2 hl=2 l= 1 prim: INTEGER :00
11:d=2 hl=3 l= 134 cons: SEQUENCE
14:d=3 hl=2 l= 11 cons: SET
16:d=4 hl=2 l= 9 cons: SEQUENCE
18:d=5 hl=2 l= 3 prim: OBJECT :countryName
23:d=5 hl=2 l= 2 prim: PRINTABLESTRING :EN
27:d=3 hl=2 l= 13 cons: SET
29:d=4 hl=2 l= 11 cons: SEQUENCE
31:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
36:d=5 hl=2 l= 4 prim: UTF8STRING :none
42:d=3 hl=2 l= 13 cons: SET
44:d=4 hl=2 l= 11 cons: SEQUENCE
46:d=5 hl=2 l= 3 prim: OBJECT :localityName
51:d=5 hl=2 l= 4 prim: UTF8STRING :none
57:d=3 hl=2 l= 18 cons: SET
59:d=4 hl=2 l= 16 cons: SEQUENCE
61:d=5 hl=2 l= 3 prim: OBJECT :organizationName
66:d=5 hl=2 l= 9 prim: UTF8STRING :Wikipedia
77:d=3 hl=2 l= 13 cons: SET
79:d=4 hl=2 l= 11 cons: SEQUENCE
81:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName
86:d=5 hl=2 l= 4 prim: UTF8STRING :none
92:d=3 hl=2 l= 24 cons: SET
94:d=4 hl=2 l= 22 cons: SEQUENCE
96:d=5 hl=2 l= 3 prim: OBJECT :commonName
101:d=5 hl=2 l= 15 prim: UTF8STRING :*.wikipedia.org
118:d=3 hl=2 l= 28 cons: SET
120:d=4 hl=2 l= 26 cons: SEQUENCE
122:d=5 hl=2 l= 9 prim: OBJECT :emailAddress
133:d=5 hl=2 l= 13 prim: IA5STRING :none@none.com
148:d=2 hl=4 l= 290 cons: SEQUENCE
152:d=3 hl=2 l= 13 cons: SEQUENCE
154:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption
165:d=4 hl=2 l= 0 prim: NULL
167:d=3 hl=4 l= 271 prim: BIT STRING
442:d=2 hl=2 l= 0 cons: cont [ 0 ]
444:d=1 hl=2 l= 13 cons: SEQUENCE
446:d=2 hl=2 l= 9 prim: OBJECT :md5WithRSAEncryption
457:d=2 hl=2 l= 0 prim: NULL
459:d=1 hl=4 l= 257 prim: BIT STRING
이것은 openssl asn1parse -in your_request -inform PEM -i 명령에 base64 인코딩을 제공하여 생성되었습니다. 여기서 PEM은 Privacy-Enhanced Mail을 나타내며 base64에서 ASN.1 고유 인코딩 규칙의 인코딩을 설명합니다.
https://en.wikipedia.org/wiki/Certificate_signing_request
---------
[안드로이드 개인프로젝트][HTTPS][6] 인증서 발급 관련 각종 파일 만들기
1. RSA 공개키 만들기
RSA는 1978년 로널드 라이베스트(Ron Rivest), 아디 샤미르(Adi Shamis), 레너드 애들먼(Leonard Adleman)의 연구에 의해 체계화되었으면 이들 3명의 이름 앞글자를 딴 것입니다 (출처:위키백과 https://ko.wikipedia.org/wiki/RSA_%EC%95%94%ED%98%B8)
openssl
openssl>genrsa 1024
openssl>genrsa 원하는 키의 크기 (2048 추천)
'안드로이드(Android) > 프로젝트' 카테고리의 다른 글
[안드로이드 프로젝트] 사이드 프로젝트 서버 이야기 (3) | 2024.10.13 |
---|---|
[안드로이드 프로젝트] 커스텀 갤러리 구현 (0) | 2023.11.15 |
[안드로이드 프로젝트] 서버 설정하기 (0) | 2022.07.26 |
[안드로이드 프로젝트] Compose 적용 (0) | 2022.03.24 |