DanMatlin
DanMatlin

Reputation: 1252

Unsigned Data and Signed Data

I have to sign and send data to a server. Using Bouncy castle I have generated the CMSSignedData object. I am new to cryptography and as far as I understand I have to send the data which is signed as well as the signed data to the server. And I have to send this as a single file. I can get the data which was signed using

CMSProcessableByteArray cpby = (CMSProcessableByteArray) sigData.getSignedContent() ;
byte[] data = (byte[])cpby.getContent();

Here sigData is the CMSSignedData object

I presume that the code

byte[] signed = sigData.getEncoded() 

gets me the signed data in a byte array.

The question is what is the general method to create the file containing the data and the signed data. Do I just add the two byte arrays? Does the array signed[] contain the data as well? If so how do I retrieve data from the array signed[]. I am asking this because I will need to follow a similar procedure to retrieve the data and the signed data for the verification process of the response from the server.

Upvotes: 0

Views: 1107

Answers (2)

First of all you need to know in what exactly format the server expects the data to be sent. If you use PKCS#7/CMS, then you don't need to merge anything.

PKCS#7 supports wrapping and detached signatures. In first case you get the signed data and the signature in one block and you send this block to the server. If you create a detached signature, then you have the original data and a separate small signature block.

Normally detached signatures are used when the original data must remain readable (cause wrapping the data will make it not readable by intended readers, eg. if you sign the PDF file using PKCS#7, Acrobat won't be able to open it correctly). So I think you should send a signed data in a single block.

Upvotes: 0

Tom Leek
Tom Leek

Reputation: 856

The kind of "signature" you are using is based on CMS (previously known as "PKCS#7"). This is a standard format for encapsulating some data with encryption or signatures or both; this is recursive so you can nest several levels.

A CMS object is a ContentInfo structure defined by this piece of ASN.1:

  ContentInfo ::= SEQUENCE {
    contentType ContentType,
    content [0] EXPLICIT ANY DEFINED BY contentType }
       
  ContentType ::= OBJECT IDENTIFIER

When the object describes a signature, the contentType field contains the identifier for "signed data" and the content is a SignedData structure defined as:

  SignedData ::= SEQUENCE {
    version CMSVersion,
    digestAlgorithms DigestAlgorithmIdentifiers,
    encapContentInfo EncapsulatedContentInfo,
    certificates [0] IMPLICIT CertificateSet OPTIONAL,
    crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
    signerInfos SignerInfos }

The actual cryptographic signature is in the signerInfos object, while encapContentInfo may contain the data which is signed. That's the important point. The EncapsulatedContentInfo structure is:

  EncapsulatedContentInfo ::= SEQUENCE {
    eContentType ContentType,
    eContent [0] EXPLICIT OCTET STRING OPTIONAL }

See the "OPTIONAL" ? It means that the CMS object may or may not contain the data which is signed.

When the CMS object contains the data which is signed, then you end up with a single object, encoded as an array of bytes (that's the point of using ASN.1: all these objects can be encoded and decoded at will). On the other hand, if the CMS object does not contain the data which is signed, then this is a detached signature. Of course, verification of the signature cannot be performed without a copy of the data which is to be signed, so if the signature is "detached", then there must be some other way to convey the data itself to the verifier.

Detached signatures are popular in the context of cryptographically protected emails with S/MIME (S/MIME can be described as "CMS object in emails"), because the detached signature is then sent as an email attached file, leaving the email text contents untouched: thus, the contents of the email can still be read by software which is completely unaware of what S/MIME may be, and would be unable to extract the data from a CMS-with-data object.

In your case, you must produce whatever will be needed by the verifier to do its job. This ought to have been already defined, in the protocol you are currently implementing. Possibly, the protocol may tell you that the data which is to be signed is already available to the verifier through another channel; or it may tell you that you must use a non-detached CMS signed object.

If there is no clearly defined protocol, and you are making it as you go, then that's a recipe for disaster. I strongly hope this is not the case. Cryptography is difficult to use, mostly because there is no way to test whether you did it correctly or not.

Upvotes: 3

Related Questions