2013-08-13 1 views
3

OpenSSL과 TLS를 사용하여 SSH와 같은 신뢰 모델을 제공하려고합니다. 즉, 두 피어간에 각각 인증서가 저장되어있는 RSA 키 쌍이 있습니다. 또한 TLS 세션을 설정하기 전에 공개 키를 교환했습니다. 초기화 동료 동안TLS : RSA 키를 사용하여 자체 서명 한 인증서를 확인하는 방법

  • 는 메모리, 일시적 X509 인증서를 생성 : 난 아직도 의심이 그래서 일부에는 OpenSSL의 문서화되지 않은 기능을 사용하고이를 달성하기 위해, 여기에 방법이다. 여기에는 더미 CN 데이터, 발급자 및 만료되기 몇 년 전에 빠져 나갈 수있는 최소 더미 데이터가 포함되어 있습니다. 어쨌든 확인되지 않습니다. SSL 컨텍스트는 두 가지 방법으로 두 인증서를 교환하도록 설정됩니다.

  • 중요한 단계는 인증서가 호스트의 공개 키를 포함하고 개인 키를 사용하여 서명되어 있습니다 :

    EVP_PKEY *pkey = EVP_PKEY_new(); 
    EVP_PKEY_assign_RSA(pkey, PRIVKEY); 
    X509_set_pubkey(x509, pkey); 
    X509_sign(x509, pkey, EVP_sha384()); 
    
  • 이 인증서는 SSL_CTX에 할당 된 전체 애플리케이션 수명에 사용됩니다.

TLS 세션이 설정되었을 때 나는 대부분 인증 프로세스에 대해 걱정하고 있습니다. 나는 SSL_CTX_set_cert_verify_callback(always_true_func)를 사용하여 OpenSSL을 수행 한 모든 검증을 비활성화하고 같이 내 자신의 롤 해요 :

X509 *received_cert = SSL_get_peer_certificate(conn_info->ssl); 
EVP_PKEY *received_pubkey = X509_get_pubkey(received_cert); 
if (EVP_PKEY_type(received_pubkey->type) != EVP_PKEY_RSA) 
    error(); 
ret = X509_verify(received_cert, received_pubkey); 
if (ret <= 0) 
    error("trust_failed"); 

// Compare received public key with expected one 
RSA *expected_rsa_key = read_RSA_key_from_disk(); 
EVP_PKEY expected_pubkey = { 0 }; 
EVP_PKEY_assign_RSA(&expected_pubkey, expected_rsa_key); 
EVP_PKEY_cmp(received_pubkey, &expected_pubkey); 

if (ret == 1) 
    return true; // identity verified! 
else 
    return false; 

질문을 :에는 OpenSSL API의 적절한 사용인가? 특히 마지막 부분에 수신 된 키 확인과 관련된 보안 허점이 있습니까? 동일한 결과를 얻을 수있는 더 좋은 방법은 없을까요?

편집 : 대답 :은 TLS 핸드 쉐이크가 저장된 RSA 키와 일치하는 동안 자체 서명 된 인증서를 수신하는지 확인하려면 인증서의 서명, 즉 X509_verify에 대한 필요가 없습니다를 확인 할 필요가 없다. 수신 된 공개 키와 예상 된 키의 비교로 충분합니다.

이유입니다 (박사 스티븐 헨슨은 OpenSSL 프로젝트의 핵심 개발자를 인용) "은 RSA 암호 해독 작업 또는 RSA 서명 작업 중 하나가 서버에서 수행되는 암호 군에 따라. 핸드 쉐이크가 성공적를 을 완료 그래서 만약 인증서 "에있는 것과 동일한 키가 사용되었는지 확인할 수 있습니다.

답변

2

인증서는 공개 키와 추가 정보 (예 : 식별자 및 기타 특성)를 함께 바인딩합니다. 공개 키와 추가 정보 사이의 연관성을 인증서가 서명 한 사실입니다.

X.509 인증서가 서명되고 발급 된 이유는 CA가 공개 키와 인증서의 나머지 콘텐츠 (특히 해당 제목) 사이에 바인딩을 주장하기 때문입니다. 이것의 목적은 CA를 알고 있지만 인증서 발급 기관을 반드시 알지 못하는 당사자가 인증서의 내용이 참임을 확인하도록하는 것입니다. 특히 공개 키가 인증서의 주체에 속하는지 확인해야합니다.

인증 체계는 공개 키를 누가 소유했는지, 누가 무엇을 소유하고 있는지에 대한 사전 지식을 기반으로하며 공개 키 외에도 인증서 내용을 무시하므로 연관성을 확인하는 요점은 없습니다 공개 키와 나머지 인증서 사이의 값은 (자체 서명 여부와 상관없이) 참입니다.

받는 사람의 공개 키가 이미 알고있는 공개 키 중 하나와 일치하는지 확인해야합니다.

편집 : 사람이 (가 공공 ...의) 나에게 호스트의 공개 키를 보낼 수 있기 때문에

그러나 두 번째는, 실제로 자체 서명 인증서가 이 유효하게 체결되어 있는지 확인하는 것입니다.

누구나 호스트의 공개 키를 사용하여 인증서를 보낼 수 있지만 공개 키와 일치하는 개인 키가있는 엔티티 만 마스터 비밀을 협상 할 수 있습니다. 이 작업은 암호 모음에 따라 다르지만 개인 키가있는 서버 만 TLS 연결을 통해 수행 할 수 있습니다.

클라이언트는 최소한 서버 인증서의 공개 키에 대한 개인 키가있는 엔터티와 TLS 연결을 설정했음을 항상 알게됩니다 (해당 인증서가 속한 사람과 관계없이).

이것은 실제로 서버의 신원을 확인하는 데 사용되는 메커니즘 (전통적으로 PKI + 호스트 이름 확인)과 완전히 독립적입니다.

호스트의 공개 키를 알고있는 경우 (예 : 이미 알고있는 목록에서 인증서를 찾으십시오) 인증서 서명을 확인하는 것은 관련이 없습니다 (자신이 서명하지 않았거나 모르는 사람이 서명 한 것이 든) .

클라이언트 인증서도 마찬가지입니다. 인증서를 보낸 클라이언트가 보낸 클라이언트 인증서와 일치하는 개인 키를 사용하여 올바른 서명 (인증서 확인 메시지에서)을 보낼 수없는 경우 핸드 셰이크가 완료되지 않습니다.

+0

내 견해로는 두 가지를 확인해야합니다. 첫째, 인증서에 내가 아는 공개 키가 포함되어 있다는 것입니다. 그러나 두 번째는 실제로 누군가가 * 호스트의 공용 키 (public ...)를 보낼 수 있기 때문에 자체 서명 된 인증서가 유효하게 서명되었는지 확인하는 것입니다. EVP_PKEY_cmp() 및 2.X509_verify()를 사용하여이 두 가지 작업을 수행합니다. – jimis

+0

TLS 프로토콜, 특히 CertificateVerify 메시지의 팁을 내부적으로 살펴 주셔서 감사합니다. 나는 이것에 돌아 왔고 [wikipedia] (http://en.wikipedia.org/wiki/Transport_Layer_Security)에서 그것을 이해하려고 노력했다. "이 서명은 클라이언트의 인증서 공개 키를 사용하여 확인할 수 있으므로 클라이언트가 인증서의 개인 키에 액세스하여 인증서를 소유하고 있음을 서버가 알 수 있습니다."라는 CertificateVerify 메시지에 대해 다음과 같이 설명합니다. 하지만 OpenSSL에서 verify_callback을 덮어 씀으로써 모든 인증을 비활성화 했으므로 언제 sig를 확인 했습니까? – jimis

관련 문제