AesCryptoServiceProvider не является частью SymmetricAlgorithm? - PullRequest
0 голосов
/ 30 апреля 2010

У меня есть быстрое небольшое приложение, которое перебирает возможные методы симметричного шифрования. Я получаю их со следующей строкой:

 private static List<Type> GetAlgorithmTypes
    {
        get { return Assembly.GetAssembly(typeof(SymmetricAlgorithm)).GetTypes().Where( type => type.IsSubclassOf(typeof(SymmetricAlgorithm))).ToList(); }
    }

Как вы можете видеть, когда я запускаю это, AesCryptoServiceProvider не является членом этой группы, хотя он наследует от AES, который принадлежит SymmetricAlgorithm и отображается в моем списке. Это не будет большой проблемой, я могу вручную добавить провайдера в группу, если он у меня есть, но затем, если я попытаюсь получить этот тип по его имени:

Type t = Type.GetType("System.Security.Cryptography.AesCryptoServiceProvider");

Я получаю нулевой объект для AesCryptoServiceProvider, но не для других элементов в группе.

Это действительно странно, и мне интересно, есть ли у кого-нибудь идеи. Из-за этого мне нужно использовать tripleDES (поскольку все мои машины работают в соответствии с требованиями соответствия FIPS).

Спасибо за любую помощь!

Ответы [ 4 ]

2 голосов
/ 30 апреля 2010

SymmetricAlgorithm находится в mscorlib.dll, AesCryptoServiceProvider находится в System.Core.dll

Получая сборку на основе типа SymmetricAlgorithm, вы получаете сборку mscorlib, которая не содержит AesCryptoServiceProvider.

Возможно, вы захотите pinvoke CryptEnumProviders , чтобы получить список доступных CSP, затем вы можете использовать CryptoConfig.CreateFromName (...) для создания экземпляр этого CSP.


Вы можете попробовать что-то вроде этого, он найдет тип, если его сборка загружена в текущий домен приложений.

var types = AppDomain.CurrentDomain.GetAssemblies()
    .Select(
        a => a.GetTypes()
            .Where( t => typeof(SymmetricAlgorithm).IsAssignableFrom(t) )
    )
1 голос
/ 30 апреля 2010

Вы уверены, что сборка с AesCryptoServiceProvider загружена? Assembly.GetAssembly будет просматривать только загруженную коллекцию сборок.

1 голос
/ 30 апреля 2010

Я полагаю, Type.IsSubclassOf проверяет только, является ли тип прямым подклассом указанного типа. Вы пытались использовать Type.IsAssignableFrom вместо?

type => typeof(SymmetricAlgorithm).IsAssignableFrom(type)
0 голосов
/ 02 мая 2010

Что вы должны сделать, это легко объяснить в Win32 API. Есть следующие нативные API:

CryptEnumProviders, CryptEnumProviderTypes, CryptGetDefaultProvider

, которые не намного больше, чем HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider. Смотрите пример кода от http://msdn.microsoft.com/en-us/library/aa382359(VS.85).aspx.

Каждый провайдер реализует некоторые криптографические алгоритмы. Это уважение CryptGetProvParam (см. http://msdn.microsoft.com/en-us/library/aa380196(VS.85).aspx) и PP_ENUMALGS или PP_ENUMALGS_EX, вы можете изучить эти алгоритмы. Вас не смущает, что вы можете иметь много реализаций одних и тех же алгоритмов внутри разных провайдеров (DLL) Разные провайдеры могут хранить ключ в другом месте (например, смарт-карта) или выполнять какую-то основную работу, такую ​​как RSA SChannel, но им нужны и реализованы некоторые другие алгоритмы.

Каждый алгоритм идентифицируется как ALG_ID aiAlgid;, где ALG_ID равен unsigned int и состоит из трех частей, которые можно увидеть в wincrypt.h :

//
// Algorithm IDs and Flags
//

// ALG_ID crackers
#define GET_ALG_CLASS(x)                (x & (7 << 13))
#define GET_ALG_TYPE(x)                 (x & (15 << 9))
#define GET_ALG_SID(x)                  (x & (511))

// Algorithm classes
// certenrolld_begin -- ALG_CLASS_*
#define ALG_CLASS_ANY                   (0)
#define ALG_CLASS_SIGNATURE             (1 << 13)
#define ALG_CLASS_MSG_ENCRYPT           (2 << 13)
#define ALG_CLASS_DATA_ENCRYPT          (3 << 13)
#define ALG_CLASS_HASH                  (4 << 13)
#define ALG_CLASS_KEY_EXCHANGE          (5 << 13)
#define ALG_CLASS_ALL                   (7 << 13)
// certenrolld_end

// Algorithm types
#define ALG_TYPE_ANY                    (0)
#define ALG_TYPE_DSS                    (1 << 9)
#define ALG_TYPE_RSA                    (2 << 9)
#define ALG_TYPE_BLOCK                  (3 << 9)
#define ALG_TYPE_STREAM                 (4 << 9)
#define ALG_TYPE_DH                     (5 << 9)
#define ALG_TYPE_SECURECHANNEL          (6 << 9)

#define CALG_AES_256            (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES_256)

Я включил только один алгоритм шифрования. Так что вам интересны все алгоритмы с классом ALG_CLASS_DATA_ENCRYPT. Вы можете легко узнать из "ALG_ID взломщиков" GET_ALG_CLAS() классную часть всех алгоритмов и только фильтр ALG_CLASS_DATA_ENCRYPT.

...