使用本地帐户访问证书密钥时,域帐户将被锁定

时间:2017-09-26 15:21:40

标签: c# certificate bouncycastle public-key

当我访问从使用BouncyCastle生成的对象初始化的X509Certificate2.PublicKey或X509Certificate2.PrivateKey时,我的域帐户被锁定(如果我多次执行)。如果我代表具有相同名称但密码不同的本地帐户运行程序,则会发生这种情况。这是代码:

using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System.IO;
using System.Security.Cryptography.X509Certificates;

namespace TestCertificateConversion
{
    class Program
    {
        static void Main(string[] args)
        {
            var certString = GetCertificateString();
            var textReader = new StringReader(certString);
            var pemReader = new PemReader(textReader);
            var bcCert = pemReader.ReadObject() as Org.BouncyCastle.X509.X509Certificate;
            var netCert = DotNetUtilities.ToX509Certificate(bcCert);
            var netCert2 = new X509Certificate2(netCert);
            var publicKey = netCert2.PublicKey; // this locks out domain account
        }

        private static string GetCertificateString()
        {
            return @"-----BEGIN CERTIFICATE-----
MIICvDCCAaSgAwIBAgIQANDHl0sFjYUG3j76dYTadzANBgkqhkiG9w0BAQsFADAQ
MQ4wDAYDVQQDDAVwYWNlbTAgFw0xNjAxMDExMjQ4MzdaGA8yMjAwMDEwMTIyNTg0
N1owEDEOMAwGA1UEAwwFcGFjZW0wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC5AKAkYnerRUmeAX0Z+aZsX39LXTVZiUd8U6waw7Hzd9E0YA50tHWizfEI
w7IBZwXS0aiXwHqJvrslc3NNs0grwu/iYQl+FGdudKmgXVE7Riu0uFAHo6eFr0dO
o0IP3LS+dPSWarXEBLbymaXRiPJDyHLefvslcSM9UQ2BHOe7dnHh9K1h+XMKTw3Z
/3szAyABBX9hsJU/mc9XjrMNXHJXALSxTfLIPzDrfh+aJtlopWpnb6vQcXwKksyk
4hyVUfw1klhglJgN0LgBGU7Ps3oxCbOqns7fB+tzkBV1E5Q97otgvMR14qLZgc8k
NQrdMl57GaWQJl6mAP1NR1gZt2f1AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ
KoZIhvcNAQELBQADggEBAAEz3vJOfqao9QXPWSz8YCjbWG1FeVG0NdYpd422dC2V
Vrzlo5zrkRv5XPhBOY3o81OhUe7iByiiM9suYfXLNxxd29TBGB5amO8Yv1ZX0hS/
zvVF6QS0+zZvOiujVhfHGiJxKypqgaigI6NM80ZDKPzsRPwFLIJiZYwQ7eQUlrpt
WGgFkZC23/mSOkY6VMmO5zugeMoiXRyFq33uWLlaAr+zJtRh1IPRmkA1lJv0bkC1
SslO0oSDoT2lcvZkQ5odFKX5i1z7T/wioQqG62i8nsDSz+iZOqUyDx7bL8fIEHog
qgwizgr2aAPLO/VQKU9pRTyRNFl/GL5bi7w8NN+rLxE=
-----END CERTIFICATE-----";
        }
    }
}

我不确定我做错了什么,是否有任何安全设置我可能需要更改以防止其锁定域帐户?

2 个答案:

答案 0 :(得分:0)

您是否可以检查并确认服务帐户是否采用此格式enter image description here

答案 1 :(得分:0)

我检查了.net源代码,发现了X509Certificate2.PublicKey中导致身份验证问题的原因。它是一个新的OID对象的创建:

.rename(columns={})

调用OID构造函数,并将lookupFriendlyName设置为' true',这将导致FindOidInfoWithFallback函数:

public PublicKey PublicKey {
    [SecuritySafeCritical]
    get {
        if (m_safeCertContext.IsInvalid)
            throw new CryptographicException(SR.GetString(SR.Cryptography_InvalidHandle), "m_safeCertContext");

        if (m_publicKey == null) {
            string friendlyName = this.GetKeyAlgorithm();
            byte[] parameters = this.GetKeyAlgorithmParameters();
            byte[] keyValue = this.GetPublicKey();
            Oid oid = new Oid(friendlyName, OidGroup.PublicKeyAlgorithm, true); // this line
            m_publicKey = new PublicKey(oid, new AsnEncodedData(oid, parameters), new AsnEncodedData(oid, keyValue));
        }

        return m_publicKey;
    }
}

第一个FindOidInfo返回null,然后使用OidGroup.All第二次调用它。最终导致cryptAPI调用:

// Try to find OID info within a specific group, and if that doesn't work fall back to all
// groups for compatibility with previous frameworks
internal static string FindOidInfoWithFallback(uint key, string value, OidGroup group)
{
    string info = FindOidInfo(key, value, group);

    // If we couldn't find it in the requested group, then try again in all groups
    if (info == null && group != OidGroup.All)
    {
        info = FindOidInfo(key, value, OidGroup.All);
    }

    return info;
}

来自documentation

  

CryptFindOIDInfo函数在活动中执行查找   目录,用于检索以下OID的友好名称   条件:

     
      
  • dwKeyType参数中的密钥类型设置为CRYPT_OID_INFO_OID_KEY或CRYPT_OID_INFO_NAME_KEY。
  •   
  • dwGroupId参数中未指定组标识符,或GroupID指的是EKU OID,策略OID或模板OID。
  •   

然后尝试使用本地用户帐户进行身份验证,结果我锁定了我的域帐户。从注释到代码,我看到第二个FindOidInfo调用是为了与旧框架的兼容性而添加的,我可能会删除它。不幸的是,改变代码并不容易,因为它在框架本身。我可能会尝试继承X509Certificate2对象并重写PublicKey和PrivateKey,但我不是很喜欢这个想法。