.NET RSA data signing, are my assumptions correct?

939 Views Asked by At

I've been digging into the .NET System.Security.Cryptography namespace, specifically the RSACryptoServiceProvider class. It has two methods using in signing data, SignHash() and VerifyHash() and I have a few questions regarding the usage of this class and methods.

1) When instantiated, RSACryptoServiceProvider creates a keypair, like so:

// 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;

Then the private and public keys can be saved to disk using the following code:

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();
    }
}

Q: Is there anything that can prevent the subsequent loading of the public key on a client computer at a later time (exempting file access rights etc.), using code such as this:

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 );
}

Q: If specifying Csp flag CspProviderFlags.UseArchivableKey instead of CspProviderFlags.None, the loading of the file fails (at rsa.FromXmlString()) with a CryptographicException "Invalid flags specified.", why is that? The 'Achivable' sound just like what is I want, no?

Q: Is there anyway of creating a RSACryptoServiceProvider without also creating a new keypair (as I will load an existing key shortly after) ?

2) According to MSDN, the two methods SignHash and VerifyHash can be used to sign a hash of some arbitrary data, using the private key, then be verified using the public key to ensure the validity of the data.

Q: What if I distribute the public key with my application (embedded resource or base64 encoded string etc.) to validate a license key that has been hashed and signed using my private key - can I be certain that no one else can generate license keys that are considered valid by the application (assuming I keep the private key private)? After all, that is what the public/private keys are for, are they not?

Example signing code:

using( SHA1 sha = SHA1.Create() ) {
    byte[] hash = sha.ComputeHash( data );
    byte[] signature = rsa.SignHash( hash, CryptoConfig.MapNameToOID( "SHA1" ) );
}

Thanks in advance.

0

There are 0 best solutions below