2. Using the
Implementation Class
The RSACryptoServiceProvider
and
DSACryptoServiceProvider classes both
define four
methods related to digital signatures . Table 1
summarizes the
methods.
Table
1. Algorithm implementation signature methods
Method
|
Description
|
---|
SignData
|
Creates a digital signature from the original document
|
SignHash
|
Creates a digital signature from a hash code
|
VerifyData
|
Verifies a digital signature against the original document
|
VerifyHash
|
Verifies a digital signature against a hash code
|
The SignData method creates a
signature
by
generating a hash code, formatting the hash code using PKCS #1,
and signing the result. The corresponding
VerifyData
method creates a PKCS #1-formatted hash
code and uses it to verify a signature.
For the RSA algorithm, the hash codes are generated using an instance
of System.Security.Cryptography.HashAlgorithm,
provided as an argument to the SignDataVerifyData methods For the DSA
algorithm, the
SHA-1 hashing algorithm is always used and
to generate the hash codes.
The following
statements demonstrate how to
use the
SignData method to create a
signature for a byte
array, and then verify the signature using the
VerifyData method:
# C#
// create the plaintext
byte[] x_plaintext = Encoding.Default.GetBytes("Programming .NET Security");
// create an instance of the DSA implementation class
DSACryptoServiceProvider x_dsa = new DSACryptoServiceProvider( );
// create a signature for the plaintext
byte[] x_dsa_signature = x_dsa.SignData(x_plaintext);
// verify the signature, using the plaintext
bool x_dsa_sig_valid = x_dsa.VerifyData(x_plaintext, x_dsa_signature);
// create an instance of the RSA implementation class
RSACryptoServiceProvider x_rsa = new RSACryptoServiceProvider( );
// create an instance of the SHA-1 hashing algorithm
HashAlgorithm x_sha1 = HashAlgorithm.Create("SHA1");
byte[] x_rsa_signature = x_rsa.SignData(x_plaintext, x_sha1);
// verify the signature, using the plaintext
bool x_rsa_sig_valid = x_rsa.VerifyData(x_plaintext, x_sha1, x_rsa_signature);
# Visual Basic .NET
' create the plaintext
Dim x_plaintext As Byte( ) = Encoding.Default.GetBytes("Programming .NET Security")
' create an instance of the DSA implementation class
Dim x_dsa As DSACryptoServiceProvider = New DSACryptoServiceProvider( )
' create a signature for the plaintext
Dim x_dsa_signature As Byte( ) = x_dsa.SignData(x_plaintext)
' verify the signature, using the plaintext
Dim x_dsa_sig_valid As Boolean = x_dsa.VerifyData(x_plaintext, x_dsa_signature)
' create an instance of the RSA implementation class
Dim x_rsa As RSACryptoServiceProvider = New RSACryptoServiceProvider( )
' create an instance of the SHA-1 hashing algorithm
Dim x_sha1 As HashAlgorithm = HashAlgorithm.Create("SHA1")
Dim x_rsa_signature As Byte( ) = x_rsa.SignData(x_plaintext, x_sha1)
' verify the signature, using the plaintext
Dim x_rsa_sig_valid As Boolean = x_rsa.VerifyData(x_plaintext, x_sha1, _
x_rsa_signature)
The principal advantage of the SignData method is
that the data to be signed can be read from a stream, which is useful
for signing documents (which would otherwise be read into system
memory). The following statements demonstrate how to use the
SignData method to create a DSA
signature by
reading data from a stream. For this example, assume that we wish to
sign a disk file called mydocument.txt:
# C#
// open the file as a stream
System.IO.FileStream x_stream
= new System.IO.FileStream("mydocument.txt", System.IO.FileMode.Open);
// create an instance of the DSA implementation class
DSACryptoServiceProvider x_dsa = new DSACryptoServiceProvider( );
// create a signature using the stream
byte[] x_dsa_signature = x_dsa.SignData(x_stream);
// close the stream
x_stream.Close( );
# Visual Basic .NET
' open the file as a stream
Dim x_stream As System.IO.FileStream _
= New System.IO.FileStream("mydocument.txt", System.IO.FileMode.Open)
' create an instance of the DSA implementation class
Dim x_dsa As DSACryptoServiceProvider = New DSACryptoServiceProvider( )
' create a signature using the stream
Dim x_dsa_signature As Byte( ) = x_dsa.SignData(x_stream)
' close the stream
x_stream.Close( )
The SignHash and VerifyHash
methods format and
sign a pre-existing hash code,
which is passed into the methods as an argument; the methods also
require a string argument representing the identifier of the hashing
algorithm that has been used to create the hash code (this is so the
correct PKCS #1 algorithm ID is included in the signature). The
static MapNameToOID method of the
CryptoConfig class returns the ID of a
hashing
algorithm, so that the following statements obtain the ID for the
SHA-1 algorithm:
# C#
string x_id = CryptoConfig.MapNameToOID("SHA1");
Console.WriteLine(x_id);
# Visual Basic .NET
Dim x_id As String = CryptoConfig.MapNameToOID("SHA1")
Console.WriteLine(x_id)
These statements
produce the following output, which is a decimal
representation of part of the ID that we listed in Table
16-1:
1.3.14.3.2.26
The following statements
demonstrate how to
create
and verify a signature using the SignHash and
VerifyHash methods and
the DSA algorithm. Notice
that the DSA implementation requires the ID of the hashing algorithm,
even though the DSA specification demands that SHA-1 is always used:
# C#
// create the plaintext
byte[] x_plaintext = Encoding.Default.GetBytes("Programming .NET Security");
// create a hash code for the plaintext, using the SHA-1 algorithm
byte[] x_hashcode = HashAlgorithm.Create("SHA1").ComputeHash(x_plaintext);
// create an instance of the DSA implementation class
DSACryptoServiceProvider x_dsa = new DSACryptoServiceProvider( );
// create a DSA signature using the hash code
byte[] x_signature = x_dsa.SignHash(x_hashcode, CryptoConfig.MapNameToOID("SHA1"));
// verify the signature
bool x_sig_valid = x_dsa.VerifyHash(x_hashcode, CryptoConfig.MapNameToOID("SHA1"),
x_signature);
# Visual Basic .NET
' create the plaintext
Dim x_plaintext As Byte( ) = Encoding.Default.GetBytes("Programming .NET Security")
' create a hash code for the plaintext, using the SHA-1 algorithm
Dim x_hashcode As Byte( ) = HashAlgorithm.Create("SHA1").ComputeHash(x_plaintext)
' create an instance of the DSA implementation class
Dim x_dsa As DSACryptoServiceProvider = New DSACryptoServiceProvider( )
' create a DSA signature using the hash code
Dim x_signature As Byte( ) = x_dsa.SignHash(x_hashcode, _
CryptoConfig.MapNameToOID("SHA1"))
' verify the signature
Dim x_sig_valid As Boolean = x_dsa.VerifyHash(x_hashcode, _
CryptoConfig.MapNameToOID("SHA1"), x_signature)