AesCryptoServiceProvider不是SymmetricAlgorithm的一部分?

时间:2010-04-30 18:52:02

标签: c# cryptography aescryptoserviceprovider

我有一个快速的小应用程序,可以逐步完成可能的对称加密方法。我用下面一行得到它们:

 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 个答案:

答案 0 :(得分:2)

SymmetricAlgorithm位于mscorlib.dll中,AesCryptoServiceProvider位于System.Core.dll中

通过获取基于SymmetricAlgorithm类型的程序集,您将获得不包含AesCryptoServiceProvider的mscorlib程序集。

您可能希望pinvoke CryptEnumProviders获取可用CSP列表,然后您可以使用CryptoConfig.CreateFromName(...)创建该CSP的实例。


你可以试试这样的东西,如果它的程序集加载到当前的AppDomain中,它会找到类型。

var types = AppDomain.CurrentDomain.GetAssemblies()
    .Select(
        a => a.GetTypes()
            .Where( t => typeof(SymmetricAlgorithm).IsAssignableFrom(t) )
    )

答案 1 :(得分:1)

我相信Type.IsSubclassOf仅在类型是指定类型的直接子类时进行检查。您是否尝试过使用Type.IsAssignableFrom

type => typeof(SymmetricAlgorithm).IsAssignableFrom(type)

答案 2 :(得分:1)

您确定加载了AesCryptoServiceProvider的程序集吗? Assembly.GetAssembly只会查看当前加载的程序集集合。

答案 3 :(得分:0)

您应该在Win32 API中轻松解释。有以下原生API:

CryptEnumProvidersCryptEnumProviderTypesCryptGetDefaultProvider

对于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_ENUMALGSPP_ENUMALGS_EX您可以检查此算法。你不要混淆,你可以在不同的提供程序(DLL)中有许多相同的算法实现。不同的提供商可以在不同的地方持有密钥(如智能卡),或者有一些主要工作,如RSA SChannel,但需要并实施其他一些算法。

每个算法都标识为ALG_ID aiAlgid; ALG_IDunsigned 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 crackers”GET_ALG_CLAS()轻松找到所有算法的类部分,并仅过滤ALG_CLASS_DATA_ENCRYPT