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

2 に答える 2

4

SSL証明書のCommonName(CN)フィールドは、接続しようとしているホストのDNS名である必要があります。CNにリストされているDNS名の所有権を検証せずに、CNで証明書を発行しないことを「信頼している」「信頼されたルート証明書の承認者」です。

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

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


これは、適切なプロキシがよく機能する方法です。IT部門は、ワークステーションにCAをインストールします。SSL要求を行うと、プロキシを通過し、応答が返されると、プロキシは「CN=*.google.comSigned by VeriSign」をインターセプトし、「Signed CN=*.google.combyXYZCorperateProxy」をワークステーションに送信します。ITは信頼されたルートCAをプレインストールしているため、ブラウザは文句を言いません。

ただし、通常のストアを使用しないブラウザを使用する場合、またはCAがインストールされていない場合は、コンピュータに「Signed by XYZ Coperate Proxy」証明書が表示され、そのCAが誰であるかわからないため、証明書エラーが発生します。議論についてRemoteCertificateChainErrorssslPolicyErrors


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;
                }
            }
        }
    }
}
于 2012-09-15T23:07:03.770 に答える
1

自己署名証明書を使用する場合は、提示したコードを使用する必要があります。それ以外の場合は、使用するだけで十分です

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

    }
    return false;
}
于 2012-09-16T02:53:37.267 に答える