2012-09-15 4 views
5

自己署名証明書を作成し、それをクライアントの信頼できるルートにインストールし、.pfx [サーバー側]を使用して証明書が正常に認証されていることを確認しました。誰でも偽の証明書を作成することは可能ですか?

しかし、ハッカーがクライアントと認証を偽造する方法はありますか?彼の偽の証明書とサーバーで?

例:認定を検証する

私のコード

private static bool OnCertificateValidation(
     object sender, 
     X509Certificate certificate, 
     X509Chain chain, 
     SslPolicyErrors sslPolicyErrors) 
    { 
     if (sslPolicyErrors == SslPolicyErrors.None) 
     { 
      if (CaVerify(chain) && ServerVerify(certificate)) return true; 
     } 
     return false; 
    } 

    public static bool CaVerify(X509Chain chain) 
    { 
     if (chain.ChainElements.Count > 0) 
     { 
      var certHash = chain.ChainElements[chain.ChainElements.Count - 1].Certificate.GetCertHash(); 
      if (certHash.Length == ApiCertHash.Length) 
      { 
       for (var idx = 0; idx < certHash.Length; idx++) 
       { 
        if (certHash[idx] == ApiCertHash[idx]) 
        { 
         return true; 
        } 
       } 
      } 
     } 
     return false; 
    } 

    public static bool ServerVerify(X509Certificate certificate) 
    { 
     var certHash = certificate.GetCertHash(); 

     if (certHash.Length == ApiCertHash.Length) 
     { 
      for (var idx = 0; idx < certHash.Length; idx++) 
      { 
       if (certHash[idx] == ApiCertHash[idx]) 
       { 
        return true; 
       } 
      } 

     } 
     return false; 
    } 

だからいくつかのいずれかが偽certification.pfxを作成し、彼の偽のサーバーに関連付け、彼の偽のサーバに私のクライアントを接続することができますか?

答えて

4

SSL証明書のCommon Name(CN)フィールドは、接続しようとしているホストのDNS名である必要があります。 「信頼済みルート証明機関」を「CNに記載されているDNS名の所有権を検証せずにCNで証明書を発行しない」と「信頼する」。

これを回避するには、認証局(CA)を手動で信頼済みリストに追加します。したがって、コンピュータは、サーバーから受信した証明書が証明書に記載されているどのようなCNでも使用できるように、個人CAを信頼します。

不正な証明書を発行したCAが「信頼されていない」ため、検証が失敗するため、攻撃者は「偽の」証明書を作成できません。


これは、コルペートプロキシがしばしば機能する方法です。 IT部門は、ワークステーションにCAをインストールします。 SSLリクエストを行うと、プロキシを経由して、応答が返ってくると、プロキシは "CN=*.google.com Signed by VeriSign"を傍受し、ワークステーションに "CN=*.google.com、Signed by XYZ Corperate Proxy"を送信します。 IT Trusted Root CAがあらかじめインストールされているため、ブラウザは不平を言っていません。

通常の店舗を使用していないブラウザを使用している場合、またはCAがインストールされていないブラウザを使用している場合は、コンピュータに「XYZ Coperate Proxyによる署名」の証明書が表示され、は、sslPolicyErrors引数にRemoteCertificateChainErrorsを返します。


CAのハッシュをチェックするコード例。

if (sslPolicyErrors == SslPolicyErrors.None) 
{ 
    var apiCertHash = new byte[] { 0x79, 0x04, 0x15, 0xC5, 0xC4, 0xF1, 0x6A, 0xA7, 0xC9, 0x12, 0xBB, 0x23, 0xED, 0x5A, 0x60, 0xA7, 0x92, 0xA8, 0xD5, 0x94 }; 
    if(chain.ChainElements.Count > 0) 
    { 
     //Not 100% if the root is first or last in the array. Don't have the program running to check. 
     var certHash = chain.ChainElements[chain.ChainElements.Count - 1].Certificate.GetCertHash(); 
     if (certHash.Length == apiCertHash.Length) 
     { 
      for (var idx = 0; idx < certHash.Length; idx++) 
      { 
       if (certHash[idx] == apiCertHash[idx]) 
       { 
        return true; 
       } 
      } 
     } 
    } 
} 
+0

はい彼ができる、*を使用するのに十分です。それは "中の主人公"ではないでしょう、攻撃者はエンドポイントを制御します、それについてあなたができることはあまりありません。あなたは証明書の指紋を入れることができますが、よりスマートな考え方は、CAの指紋を入れて、新しい証明書を発行することができます(接続するDNS名を変更する必要があるとします。新しい証明書が必要となり、そのために新しい証明書指紋が必要になります)。方法を示すための簡単なコードを追加します。 –

+0

Sslは私のクライアント/サーバをMITM攻撃から保護するだけで、クライアントのエンドポイントを制御することはできません。 –

+0

エンドポイントを保護することは不可能です。エンドユーザーが任意のコードを実行できる場合、あなたは失われてしまいます。攻撃者は自分のデバッガを添付して実行するだけで、実行中のプログラムで何でもできます。あなたはそれらを難しくすることができますが、あなたはそれを止めることはできません。 「停止する」唯一の方法は、エンドユーザーが必要なものを実行することを許可されていないことです。その例として、** unjailbroken ** iPhoneがあります。ユーザーはアプリストアからしかアプリを実行できません。そのストアにはデバッグツールがないため、エンドユーザーはそのプログラムを攻撃することはできません。しかし、もしジェイルブレイクしていれば、あなたはあなたが始まった場所です、それを止めることはできません。 –

1

あなたはあなたの自己署名証明書を使用しようとしている場合は、あなたが提示したコードを使用する必要があり、それ以外の場合は、*ただ唯一の彼のマシンに

private static bool OnCertificateValidation(
    object sender, 
    X509Certificate certificate, 
    X509Chain chain, 
    SslPolicyErrors sslPolicyErrors) 
{ 
    if (sslPolicyErrors == SslPolicyErrors.None) 
    { 
     return true; 

    } 
    return false; 
} 
関連する問題