This section steps through the signature process. This sample starts with the hash value used in the previous sample; that is, an MD5 hash of the "1134-kelp" string. This hash value is as follows:
0x00000000 73 40 e6 e2 74 b8 ea 39 s@..t..9
0x00000008 93 95 aa 29 d6 38 b5 2a ...).8.*
This example assumes that the application specified "Test Signature" as the description string. The first thing that the CSP does is to add this string to the hash object that is being signed. Of course, the description string is received by the CSP in Unicode format, as follows:
0x00000000 54 00 65 00 73 00 74 00 T.e.s.t.
0x00000008 20 00 53 00 69 00 67 00 .S.i.g.
0x00000010 6e 00 61 00 74 00 75 00 n.a.t.u.
0x00000018 72 00 65 00 r.e.
After the description string has been hashed in, the hash value is extracted:
0x00000000 a8 2b df c2 c9 f1 bb 62 .+.....b
0x00000008 38 78 d4 60 fa ce 5c 2a 8x.`..\*
The next step is building a PKCS signature block. This is always the same size as the public key's modulus (64 bytes) and contains the following fields:
Bytes | Description |
---|---|
16 | Hash of data to be signed. The size of this field will vary, depending on the hash algorithm used. As you can see from comparing the hex dump of the hash value earlier in this chapter and the hex dump of the following encryption block, the bytes in the hash value are reversed before they are placed in the encryption block. This is because Windows NT formats data in little endian format, and the encryption block must be built in big endian format. |
18 | ASN.1 encoded hash algorithm specifier. The size of this field will vary, depending on the hash algorithm used. Note that this data is also reversed. A description of ASN.1 is beyond the scope of this document, but a table of common ASN.1 strings is provided in the next section. For more information on ASN.1, see the PKCS documentation. |
1 | Zero value. |
27 | Padding data (0xff's). The size of this field is adjusted as necessary so that the signature block's overall length is correct. |
1 | The PKCS block type (0x01). |
1 | Zero value. |
You may notice that the order of this table is reversed from the diagram found in the PKCS documentation. This is because the signature block is built in big endian on a little endian computer.
Once the signature block has been built, it looks something like this:
0x00000000 2a 5c ce fa 60 d4 78 38 *\..`.x8
0x00000008 62 bb f1 c9 c2 df 2b a8 b.....+.
0x00000010 10 04 00 05 05 02 0d f7 ........
0x00000018 86 48 86 2a 08 06 0c 30 .H.*...0
0x00000020 20 30 00 ff ff ff ff ff 0......
0x00000028 ff ff ff ff ff ff ff ff ........
0x00000030 ff ff ff ff ff ff ff ff ........
0x00000038 ff ff ff ff ff ff 01 00 ........
The next step is to encrypt the block with the appropriate private key. In this example, the private key used is the one corresponding to the public key used in the previous section "Public Key Blobs." This results in a completed digital signature:
0x00000000 64 f6 46 3a 97 2e 83 38 d.F:...8
0x00000008 09 57 43 cb ca 41 59 0d .WC..AY.
0x00000010 03 35 d6 e4 36 6f 2c fc .5..6o,.
0x00000018 63 43 95 c4 fd e2 c4 ed cC......
0x00000020 06 da 9a 21 98 fc 0a 6e ...!...n
0x00000028 3f 1c ad 3a db 7c 83 2f ?..:.|./
0x00000030 14 d0 58 80 02 df dc 96 ..X.....
0x00000038 70 09 00 e3 5b bd 2b 45 p...[.+E