我一直在研究 .NETSystem.Security.Cryptography
命名空间,特别是RSACryptoServiceProvider
类。它有两种用于签署数据的方法,SignHash()
并且VerifyHash()
我对此类和方法的使用有一些疑问。
1)实例化时,RSACryptoServiceProvider
创建一个密钥对,如下所示:
// 1 = RSA compatible. http://msdn.microsoft.com/en-us/library/1dh4wac4.aspx
CspParameters cspParams = new CspParameters( 1 );
cspParams.Flags = CspProviderFlags.NoFlags;
rsa = new RSACryptoServiceProvider( 2048, cspParams ); // rsa is a class member
rsa.PersistKeyInCsp = false;
然后可以使用以下代码将私钥和公钥保存到磁盘:
public void WriteKeys( FileInfo file, bool includePrivateKey )
{
using( FileStream fs = new FileStream( file.FullName, FileMode.Create, FileAccess.Write, FileShare.None ) ) {
string xml = rsa.ToXmlString( includePrivateKey );
byte[] b = Encoding.UTF8.GetBytes( xml );
string base64 = Convert.ToBase64String( b );
b = Encoding.UTF8.GetBytes( base64 );
fs.Write( b, 0, b.Length );
fs.Close();
}
}
问:有什么可以防止以后在客户端计算机上加载公钥(免除文件访问权限等),使用如下代码:
private void ReadKeyFromFile( FileInfo keyFile )
{
byte[] b = File.ReadAllBytes( keyFile.FullName );
string base64 = Encoding.UTF8.GetString( b );
byte[] b = Convert.FromBase64String( base64 );
string xml = Encoding.UTF8.GetString( b );
rsa.FromXmlString( xml );
}
问:如果指定 Csp 标志 CspProviderFlags.UseArchivableKey 而不是 CspProviderFlags.None,则文件加载失败(在 rsa.FromXmlString() 处)并出现 CryptographicException“指定的标志无效。”,为什么会这样?“Achivable”听起来就像我想要的一样,不是吗?
问:无论如何创建一个RSACryptoServiceProvider
而不创建一个新的密钥对(因为我将在不久之后加载一个现有的密钥)?
2)根据MSDN,这两种方法SignHash
可以VerifyHash
用来对一些任意数据进行哈希签名,使用私钥,然后使用公钥进行验证,以保证数据的有效性。
问:如果我将公钥与我的应用程序(嵌入资源或 base64 编码字符串等)一起分发以验证已使用我的私钥散列和签名的许可证密钥,我能确定没有其他人可以生成许可证密钥吗?应用程序认为有效(假设我将私钥保密)?毕竟,这就是公钥/私钥的用途,不是吗?
示例签名代码:
using( SHA1 sha = SHA1.Create() ) {
byte[] hash = sha.ComputeHash( data );
byte[] signature = rsa.SignHash( hash, CryptoConfig.MapNameToOID( "SHA1" ) );
}
提前致谢。