介绍
在{A},我向您展示了如何做一个挑战的回应使用的金雅拓。NET卡V2的RSA证书的认证。在这篇文章中,我会告诉你如何结合NET许可和这个令牌生成的能力。一些挑战字节的RSA签名。目前已经有很多文章在互联网上展示了如何使用。NET的发牌机制,所以我不会去的那部分细节,但集中使用智能卡,实现了强劲的发牌。这种技术是使用的大多数基于令牌牌产品。此金雅拓的产品,现在你可以写你自己的一个非常合理的价格,很容易比较,你将不得不做前一段时间。背景
请参考我上一篇文章中关于金雅拓智能卡,明白什么,我要在这里描述的,因为我们要使用它严重。扩展的身份验证服务支持。NET组件许可
在前面的文章,我写了一段简单的代码在卡RSA私钥的一些挑战,数据可以签署。这个签名是使用PKI令牌发牌机制的基础。要许可的应用程序或组件,将产生一个随机的数据,然后将它发送到智能卡,将使用它的私钥签署。然后卡服务返回的签名字节可以加密,许可的供应商将验证签名和授权要创建的组件。
我将添加到签名机制是一个授权令牌的组件的名称列表。请记住,您将在此令牌的一切就像是在一个虚拟的安全,不能与最强的攻击,甚至被打破。
令牌运行的代码和数据,用户无法访问,它不喜欢在硬盘上或到内存中,你可以尝试攻击。在银行智能卡使用的是类似的协议来访问代码。数据或命令,可以通过PIN码和保护你有三个试图猜测它的值可以是任何ASCII字符串。经过三次尝试,代码被封锁,几乎摧毁了该卡。您可以尝试花哨的硬件攻击,但再次,PKI卡具有强大的电子对抗措施,将阻止数据访问该芯片。这不是我在这里说的软件,但硬件自毁机制!在智能卡上有没有后门,一旦管理员密码被封锁...你可以扔掉卡,它是死了!
在一个金雅拓卡,行政PIN是20个字节,用于加密认证...你有5次尝试猜测它的价值,那么好的运气!
现在,我已经介绍了,我们要使用的硬件安全,让我们设计一个简单的组件在卡库许可证。这是一个简单列表中的数据将存储我们要授权令牌中的组件的类名。
这个简单的机制可以扩展到无穷大,如果你想控制的实例的数量,牌照的有效期,你心里有什么!智能卡LicensingService
在我以前的文章中,我演示了如何使用。NET卡的签署是一个挑战的数据,我也描述了一个简单的登录/密码库,这意味着,我们需要的砖已经存在。
类ItemRepository现在可以用来实现在卡所需的任何库。不支持。NET卡框架仿制药,所以它使用的基本元素对象。基于这个类,我实现一个简单LicenseRepository类,许可证组件来存储信息。
这个仓库存储LicenseInfo实例。可以扩展这个类,我们会以包含更多有用的信息授权的组件。{C}/// <summary>
/// This class implements a simple license repository
/// </summary>
class LicenseRepository : ItemRepository
{
private static LicenseRepository _instance = null;
public static LicenseRepository Instance
{
get
{
if (_instance == null)
{
_instance = new LicenseRepository();
}
return _instance;
}
}
/// <summary>
/// There must be only one LicenseRepository
/// </summary>
private LicenseRepository()
{
}
/// <summary>
/// Adds a LicenseInfo to the repository
/// </summary>
/// <param name="name">License name</param>
/// <param name="licenseInfo">LicenseInfo object</param>
/// <returns>true if added, false otherwise</returns>
public bool AddLicense(string name, LicenseInfo licenseInfo)
{
return AddItem(name, licenseInfo);
}
/// <summary>
/// Remove a license from the repository
/// </summary>
/// <param name="name">License name</param>
/// <returns>true if removed, false otherwise</returns>
public bool RemoveLicense(string name)
{
bool removed = false;
int index = FindItemIndex(name);
if (index != NOT_FOUND)
{
RemoveItem(index);
removed = true;
}
return removed;
}
/// <summary>
/// Gets a LicenseInfo by its name
/// </summary>
/// <param name="name">License name</param>
/// <returns>LicenseInfo object, null if not found</returns>
public LicenseInfo GetLicense(string name)
{
LicenseInfo licenseInfo = null;
int index = FindItemIndex(name);
if (index != NOT_FOUND)
{
licenseInfo = GetItem(index) as LicenseInfo;
}
return licenseInfo;
}
/// <summary>
/// Gets the names of the license installed in this token
/// </summary>
/// <returns></returns>
public string[] GetLicenseNameList()
{
return GetItemAlias();
}
}
在AuthenticationService卡生成,证书和方法可以用来得到的公共密钥。这种方法不能在这种情况下使用,因为该证书必须是授权的组件,可用于所有令牌相同。在这个演示中,在证书是静态的,是卡本身产生的,但它包含在代码中。这意味着服务的开发得到它的价值,实际上打击的发牌机制。
在今后的文章中,我将展示一个协议生成的私钥和主卡初始化授权卡,以便即使在应用程序开发人员不能得到证书的私钥。这样的机制是强制一个安全的环境如银行。它也可用于授权的应用程序或组件时,因为你的工作就是金钱!
该LicensingService提供了以下接口,可与卡远程使用。
使用LicensingService一个LicenseProviderpublic class LicensingService : MarshalByRefObject
{
#region Public PIN methods
/// <summary>
/// Verify the PIN
/// </summary>
/// <param name="pinValue">PIN value</param>
public void VerifyPIN(string pinValue);
/// <summary>
/// Invalidate PIN if it is already verified
/// </summary>
public void InvalidatePIN();
public bool IsPINBlocked;
public bool IsPINVerified;
public int TriesRemainingForPIN;
#endregion
#region Public interface for the service
/// <summary>
/// Install a component license
/// </summary>
/// <param name="componentName">Component name to license</param>
/// <param name="componentClassName">Component type name,
/// including name spaces</param>
/// <returns>true if installed, false otherwise</returns>
public bool InstallLicense(string componentName, string componentClassName);
/// <summary>
/// Gets the list of installed licenses
/// </summary>
/// <returns>Array of license name</returns>
public string[] GetInstalledLicenseNames();
/// <summary>
/// Gets the license info, Compoenent class name in our case
/// </summary>
/// <param name="name">License name</param>
/// <returns>Component class name</returns>
public string GetLicenseInfo(string name);
/// <summary>
/// Get the signature for a given component.
/// This is a simple implemetation.
///
/// Unfortunately the .NET remoting version of the .NET
/// card cannot return a class instance. So if more info
/// would have to be returned, you need to use [out] parameters
///
/// In this simple example we don't need
/// to return anything except the signature
/// </summary>
/// <param name="componentName">Component name</param>
/// <param name="encrChallenge">Encrypted challenge</param>
/// <returns>Encrypted signature for that component.
/// Null if the component is not registered</returns>
public byte[] GetLicenseSignature(string componentName, byte[] encrChallenge);
#endregion
}
现在,我们有一个令牌可以用来授权一个组件,我们需要连接点,它使用。NET的发牌机制。
。NET框架提供了一种机制来装饰类必须继承自Component半自动调用许可证核查。我的目标是没有详细描述这个机制,但只是为了使用它,这样你就可以得到更多的信息{A2的}。
您需要实行两班从System.ComponentModel命名空间:许可和LicenseProvider。
在每一类中,一些方法必须执行,但你可以创建自己的方法,以支持更复杂的许可功能。
许可类,只有一个方法和一个属性必须得到执行。下面是一个原始的ComponentLicense实施。{体C3}
必须执行第二类是的LicenseProvider本身。实施摘录下面给出SmartcardLicenseProvider。单一的方法实施,并负责验证和提供的许可证本身。{的C4}
的主要方法是GetComponentLicense()方法,验证令牌给定的组件。在一个更复杂的情况下,此方法将收集的信息令牌组件执照。在这个例子中,它只是要求一个给定组件/许可证名称认证。
一旦实现了这两个类,组件本身的许可是非常简单的。{C5的}
你只需要装饰类属性LicenseProvider要许可,并在构造函数中调用静态方法validate()方法的LicenseManager。它返回一个许可,您可以转换为自己的类型。演示应用程序
我创建示范运行的令牌只为组件LicensedComponent一个许可证。演示应用程序试图创建例如LicensedComponent和对UnlicensedComponent之一。{5233}
这段代码产生的结果如下:
{S0的}
实例LicensedComponent,可以创建,但构造UnlicensedComponent抛出一个LicenseException。简单的许可证管理中的应用
LicensingService有两个方面,呼吁许可证提供一个方法来验证许可证,并不需要核实的PIN,一组使用的方法以管理令牌中的许可证。这些方法,这当然不是组件为用户提供一个PIN保护。
{S}兴趣点
密码是域辉煌的数学家,但幸运的框架喜欢。NET为我们提供了实施这些复杂的算法,像我(谁是不是数学家!)人们可以使用和建设的东西。像IT工程师的加密理论的重要性或开发是什么,你可以用它设计来解决每天在您的工作生活中的日常问题。
RSA公钥是一个很好的例子。它被用于许多安全协议,在IT行业一样,例如,在WCF中的WS-*标准时,安全启用使用智能卡的使用证书,Windows日志,或者干脆签署您最喜爱的。NET程序集。你可以在互联网上找到了很多文学关于RSA PKI(公钥基础设施)。
使用PKI令牌是一个非常强大的发牌方法,但不幸的是,这是在这个过程中有一个主要弱点。NET平台本身。基本上,这是一个有点像银行金库门为您的木屋!没有人能够打破或打开门,但一只需要穿过墙壁,具有良好的电锯条目...随着。NET应用程序,电锯是这样反射的反编译器。几年前我就用它来修改和重新编译CardSpace的CTP的工作时,一些微软的工具。
我有一个神奇的解决方案,但可以使其很难突破:注册库是组件的一部分,你要许可混淆,并签署许可证核查的DLL
系统为您的公共接口使用私人的实施和混淆您的DLL
虽然模糊不隐藏的逻辑和框架方法调用,它将会是非常困难的,许多私有方法的重建难题调用私有方法时,你只需要他们的签名。
在我们的门和墙壁的比喻,你散发的代码是在墙上。如果有人能提取所有的砖块和重建的墙壁,没有门...强大的许可,将不会为任何目的!另一方面,如果当他们重建的墙壁砖不能被摆在正确的地方和被倒塌的墙壁,然后发牌可能是有用的。