On 2010-10-16 06:25 PDT, Matej Kurpel wrote:
>   Hello,
> I am developing a PKCS#11 module to be used with Thunderbird. However, I 
> have trouble providing a valid signature for e-mails. The mechanism used 
> is CKM_RSA_PKCS and I have a 1024bit private key along with the 
> certificate, stored on the token. The signature is generated in a C# 
> .NET CF program running on the device, using this piece of code:
> 
> RSACryptoServiceProvider rsa = 
> PKCS11Library.TryLoadPK(Encoding.ASCII.GetString(keyPath, 0, 
> keyPath.Length), out keyRawData); // this returns a valid 
> RSACryptoServiceProvider instance
> signature = rsa.SignData(data, new SHA1CryptoServiceProvider()); //signs 
> the data we need
> 
> I am not sure about the second parameter of the rsa.SignData method - 
> the documentation says it is of type "object" and it's the mechanism to 
> be used to sign the data. I cannot think of any more appropriate object 
> to be passed there than SHA1CryptoServiceProvider.

This isn't really the place to come for advice about C# crypto ... but ...
the SignData method provides the wrong level of functionality for
CKM_RSA_PKCS.

The entire RSA signature creation process usually includes these steps:
  1) Choose a hash algorithm (e.g. SHA-something or MD5), get the OID
     string (number) value that identifies that algorithm, and use that
     algorithm to hash all the data to be signed.
  2) Construct an ASN.1 DER formatted buffer called a "DigestInfo" using
     that OID string and that hash value.
  3) Construct a PKCS#1 formatted buffer (either v 1.5 or v2.0) from
     that DER formatted buffer.
  4) Perform an RSA private key operation on that PKCS#1 formatted buffer.

In some applications, steps 2 and/or 3 are modified, and custom buffer
formats are used instead of the pure DigestInfo and/or PKCS#1 formats.

The CKM_RSA_PKCS mechanism you're attempting to implement does only
the last two of those steps.  It treats the input it is given as a
DigestInfo.  It then does the PKCS#1 formatting according to PKCS#1
version 1.5.  This gives its user the flexibility to implement the
normal DigestInfo buffer format, or any other custom format.

PKCS#1 Version 2.0 formatting is incompatible with CKM_RSA_PKCS.
PKCS#1 Version 2.0 formatting is done by another PKCS#11 mechanism, namely
CKM_RSA_PKCS_OAEP.

The SignData method you're trying to use does all the above steps.
It wants the input to step 1.  Since you're implementing CKM_RSA_PKCS,
the data you're given is the input to step 3, the output from step 2.
You can deconstruct it and obtain from it the output from step 1, but
you cannot go back to having the input to step 1, because the hash is
irreversible.  So, I think you cannot use SignData to implement CKM_RSA_PKCS.

C#'s RSACryptoServiceProvider class also features a SignHash method that
does the last three of those steps.  It expects to receive, as input, the
hash value and the OID string.  It constructs the DigestInfo and the
PKCS#1 buffer and does the RSA private key operation.  Whether it formats
the PKCS#1 buffer according PKCS#1 version 1.5 or version 2.0 is unknown
to me.  I couldn't find any reference to PKCS in MSDN's C# documentation.

-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to