I am trying to TimeStamp a Digital Siganture (with a local TimeStamp certificate) in C# with BouncyCastle. My understanding about TimeStamp is that it is to sign the current time. Not sure if it should be current time + original signature content? Please help on this also.
My main confusion is if the generated TimeStamp be added to Singed/Unsigned attributes of original signature. OR it will be added as a CounterSignature?
Time stamp's goal is to prove that signature was created before a given time, so with time stamp you must sign the digital signature and the current time. Time stamp must be added to CMS signature as unsigned attribute. Besides SignatureTimeStampToken is a signature itself.
To add a time stamp to CMS you can use a Signature time-stamp attribute which has 1.2.840.113549.1.9.16.2.14 object identifier and has ASN.1 Type (the information below is all extracted from CMS and TSP RFCs)
SignatureTimeStampToken ::= TimeStampToken
TimeStampToken ::= ContentInfo
-- contentType is id-signedData ([CMS])
-- content is SignedData ([CMS])
SignedData ::= SEQUENCE {
version CMSVersion,
digestAlgorithms DigestAlgorithmIdentifiers,
encapContentInfo EncapsulatedContentInfo,
certificates [0] IMPLICIT CertificateSet OPTIONAL,
crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
signerInfos SignerInfos }
In TimeStampToken the fields of type EncapsulatedContentInfo of the SignedData construct have the following meanings:
eContentType is an object identifier that uniquely specifies the content type. For a time-stamp token it is defined as:
id-ct-TSTInfo OBJECT IDENTIFIER ::= { iso(1) member-body(2)
us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1) 4}
eContent is the content itself, carried as an octet string.The eContent SHALL be the DER-encoded value of TSTInfo.
The time-stamp token MUST NOT contain any signatures other than the signature of the TSA. The certificate identifier (ESSCertID) of the TSA certificate MUST be included as a signerInfo attribute inside a SigningCertificate attribute.
TSTInfo ::= SEQUENCE {
version INTEGER { v1(1) },
policy TSAPolicyId,
messageImprint MessageImprint,
-- MUST have the same value as the similar field in
-- TimeStampReq
serialNumber INTEGER,
-- Time-Stamping users MUST be ready to accommodate integers
-- up to 160 bits.
genTime GeneralizedTime,
accuracy Accuracy OPTIONAL,
ordering BOOLEAN DEFAULT FALSE,
nonce INTEGER OPTIONAL,
-- MUST be present if the similar field was present
-- in TimeStampReq. In that case it MUST have the same value.
tsa [0] GeneralName OPTIONAL,
extensions [1] IMPLICIT Extensions OPTIONAL }
Hope this helps,
Related
I was reading this article, there are two byte array, one for signed data and one for the original data.
byte[] originalData = ByteConverter.GetBytes(dataString);
byte[] signedData;
We sign the data, this part is ok but I can not understand to verification why should we use original data?
// Hash and sign the data.
signedData = HashAndSignBytes(originalData, Key);
// Verify the data and display the result to the
// console.
VerifySignedHash(originalData, signedData, Key);
As an example we sign a data in the server and send it to the client, Clients want to find I sent that data or not, why should I send original data until the client can verifying it?
There is some post who did it in the same way:
Signing and verifying signatures with RSA C#
C# Signing and verifying signatures with RSA. Encoding issue
When passing the signedData the other part doesn't know what the originalData is, just by that.
To verify, you need both the signedData and the [ originalData and public-key ].
The VerifySignedHash function in the code mentioned above, calls to RSACryptoServiceProvider.VerifyData.
From the docs:
Verifies that a digital signature is valid by determining the hash value in the signature using the provided public key and comparing it to the hash value of the provided data.
A cryptographic hash function hash(x) has certain desirable properties:
One-way: hash(x) gives you y. Given x, it is easy to compute y. But the reverse, given y, finding x may be very difficult or impossible.
Collisions: Since the size (in bits) of the input is much larger than the hash size (eg: we can compute SHA-256 of Gigabytes of data), multiple inputs can theoretically produce the same hash. Although this is theoretically the case, hash algorithms are designed to keep collisions to a minimum in practical settings.
Unpredictability: A small change in the input causes completely different hashes to be generated. This helps in detecting data tampering (eg: changing a payment from $100.00 to $10000)
These are some of the properties that make hashes suitable for cryptographic signatures and verification of those signatures.
why should we use original data for verification (paraphrased)
Sending the original data allows the recipient to recompute the hash independently and compare the hash signature value sent by the sender to ensure that the data received is the same as what the sender sent.
I'm working on a Outlook VSTO Addin that will plug-into the iManage FileSite AddIn, I'm currently trying to access the currently selected folders ID (Within the DMS) and I noticed that the CurrentFolder.EntryID property contains a very large Hexidecimal string, which when converted to UTF-16 looks like a malformed ObjectID for iManage. See below (Some info is redacted):
�"�j���'`�W�vp441!nrtdms:0:!session:REDACTED:!database:TEC:!page:440:??!nrtdms:0:!session:REDACTED:!database:TEC:!publicpagescontainer??!nrtdms:0:!session:REDACTED:!database:TEC:??!nrtdms:0:!session:REDACTED:!explorercontainer??!nrtdms:0:!session:REDACTED:??!nrtmsg:neighborhood:??!nrtmsg:root:
I have been working on some regex to separate the Folder ID from the rest of the string but I can't help but think there's a more stable method.
Anyone have any ideas?
The ENTRYID identifier structure is described in MSDN. The ENTRYID structure is used by message store and address book providers to construct unique identifiers for their objects.
Members
abFlags - Bitmask of flags that provide information that describes the object. Only the first byte of the flags, abFlags[0], may be set by the provider; the other three are reserved. These flags must not be set for permanent entry identifiers; they are only set for short-term entry identifiers. To clients, this structure is read-only. The following flags can be set in abFlags[0]:
MAPI_NOTRECIP - The entry identifier cannot be used as a recipient on a message.
MAPI_NOTRESERVED - Other users cannot access the entry identifier.
MAPI_NOW - The entry identifier cannot be used at other times.
MAPI_SHORTTERM - The entry identifier is short-term. All other values in this byte must be set unless other uses of the entry identifier are enabled.
MAPI_THISSESSION - The entry identifier cannot be used on other sessions.
ab - Indicates an array of binary data that is used by service providers. The client application cannot use this array.
You can convert the string to a binary data using the PropertyAccessor.StringToBinary method which converts a string specified by Value to an array of bytes. For more information on type conversion when using the PropertyAccessor object, see Best Practices for Getting and Setting Properties.
In addition to the answer by #Eugene Astafiev, the format of some entry ids is documented. It is fairly easy to parse the PST, Exchange, and GAL entry ids.
Take a look at the entry ids with MFCMAPI or OutlookSpy (I am its author). Here is what OutlookSpy shows for a message PR_ENTRYID in a cached Exchange store (click IMessage button, select the PR_ENTRYID property):
abFlags[0]: 00
abFlags[1]: 00
abFlags[2]: 00
abFlags[3]: 00
muid: 5E81754F003E1549B0659F2AEA92E7C2 ({4F75815E-3E00-4915-B065-9F2AEA92E7C2})
Type: 0x0007 (eitLTPrivateMessage)
FolderDatabaseGUID: C7CF2304C77BF64585E8892DD6FF7BAC ({0423CFC7-7BC7-45F6-85E8-892DD6FF7BAC})
FolderGlobalCounter: 0xCAA69A1A0000
Pad1: 0x0000
MessageDatabaseGUID: 4A7CE85ED1AB274C9E20AA3CBFA828B1 ({5EE87C4A-ABD1-4C27-9E20-AA3CBFA828B1})
MessageGlobalCounter: 0x70A650D90100
Pad2: 0x0000
When SignedXml.CheckSignature(AsymmetricAlgorithm key) returns true (or false), what exactly does this represent does this represent?
Does this mean that the Signature is valid; or that whatever Signature object you created matches when you tried to create the Signature again?
The SignedXml.CheckSignature(AsymmetricAlgorithm key) does three checks:
Checks that the hash of the SignedInfo in the signature is signed by the supplied key. This ensure that the data is from a sender with the corresponding public key.
Checks that the hash in the SignedInfo is correct. This ensures that the contents of the Signature block has not been tampered with.
Checks that the digest of all references are correct, after applying the listed transforms. This ensure that the data protected by the signature is not tampered with.
Note that you at this point has no idea what data is actually signed - it might be only parts of the document. Before trusting data, you also have to validate the signatures.
I'm using ITextSharp 5.1.1 to digitally sign a PDF with multiple signature fields. I have 4 signature fields: 3 approval signatures (users sign the document) and the 4th signature is the certification signature, which our system signs to indicate that the document is verified as correct and that no further modification can be made to the PDF.
If I add multiple approval signatures, a new revision is created for each signature and all the signatures are valid.
As soon as I then add the certification signature at the end of the signing process, it invalidates all the previous approval signatures.
Am I missing something here? Is there a different way to achieve the same effect as the certification signature without invalidating the approval signatures?
TIA
Your approach is to first add a number of approval signatures to a document and afterwards a certification signature.
This approach cannot work because it violates the PDF specification. As the question is from 2011, I quote from part 1, i.e. ISO 32000-1 published 2008, and not part 2, i.e. ISO 32000-2 published 2017; in essence both specifications agree on this issue, though.
A PDF document may contain the following standard types of signatures:
One or more approval signatures. [...]
At most one certification signature (PDF 1.5). [...] The signature dictionary shall contain a signature reference dictionary (see Table 253) that has a DocMDP transform method. See 12.8.2.2, “DocMDP” for information on how these signatures shall be created and validated.
At most two usage rights signatures. [...]
(ISO 32000-1 section 12.8 "Digital Signatures", subsection 12.8.1 "General")
The DocMDP transform method shall be used to detect modifications relative to a signature field that is signed by the author of a document (the person applying the first signature). A document can contain only one signature field that contains a DocMDP transform method; it shall be the first signed field in the document.
(ISO 32000-1 section 12.8.2.2 "DocMDP", subsection 12.8.2.2.1 "General")
Thus, it is no wonder that as soon as you then add the certification signature at the end of the signing process, it invalidates all the previous approval signatures, because adding a certification signature to an already signed document by definition makes the signature structure of the document invalid. (Ok, Adobe's error message in this case could more clearly point out the issue...)
You wonder is there a different way to achieve the same effect as the certification signature without invalidating the approval signatures?
According to raw ISO 32000-1 your options are limited. By means of a signature field lock dictionary (see section 12.7.4.5 "Signature Fields") and a FieldMDP transformation in your final signature you can lock existing form fields:
On behalf of a document author creating a document containing both form fields and signatures the following shall be supported by conforming writers:
The author specifies that form fields shall be filled in without invalidating the approval or certification signature. The P entry of the DocMDP transform parameters dictionary shall be set to either 2 or 3 (see Table 254).
The author can also specify that after a specific recipient has signed the document, any modifications to specific form fields shall invalidate that recipient’s signature. There shall be a separate signature field for each designated recipient, each having an associated signature field lock dictionary (see Table 233) specifying the form fields that shall be locked for that user.
When the recipient signs the field, the signature, signature reference, and transform parameters dictionaries shall be created. The Action and Fields entries in the transform parameters dictionary shall be copied from the corresponding fields in the signature field lock dictionary.
(ISO 32000-1 section 12.8.2.4 "FieldMDP")
But if your original certification signature allowed annotation changes or there is no certification signature to start with, you cannot dis-allow such annotation changes.
If, on the other hand, your PDF processors and viewers support ISO 32000-1 plus the Adobe Supplement with ExtensionLevel 3, an additional entry in the signature field lock dictionary is specified:
P number (Optional; ExtensionLevel 3) The access permissions granted for this document. Valid values follow:
1, no changes to the document are permitted; any change to the document invalidates the signature.
2, permitted changes are filling in forms, instantiating page templates, and signing; other changes invalidate the signature.
3, permitted changes are the same as for 2, as well as annotation creation, deletion, and modification; other changes invalidate the signature.
Default value: none; absence of this key results in no effect on signature validation rules.
If MDP permission is already in effect from an earlier incremental save section or the original part of the document, the number shall specify permissions less than or equal to the permissions already in effect based on signatures earlier in the document. That is, permissions can be denied but not added. If the number specifies greater permissions than an MDP value already in effect, the new number is ignored.
If the document does not have an author signature, the initial permissions in effect are those based on the number 3.
The new permission applies to any incremental changes to the document following the signature of which this key is part.
(Adobe Supplement to ISO 32000-1 ExtensionLevel 3 part I "Extensions to the PDF specification", section 8.6.3 "Field Types", subsection "Signature Fields")
This addition has been adopted by ISO 32000-2.
If you want to make use of these mechanisms using iText since version 5.3.0, have a look at the Digital Signatures for PDF Documents whitepaper by Bruno Lowagie, iText. Section 2.5.5 "Locking fields and documents after signing" illustrates how to use those mechanisms with iText.
What is a 'public key token' and how is it calculated in assembly strong names?
Regarding your question, "How is it calculated", it's an SHA1 hash.
From dot net blog:
Microsoft solves the "public key
bloat" problem by using a hash of the
strongly-named assembly's public key.
These hashes are referred to as public
key tokens, and are the low 8 bytes of
the SHA1 hash of the strongly-named
assembly's public key. SHA1 hashes are
160 bit (20 byte) hashes, and the top
12 bytes of the hash are simply
discarded in this algorithm.
You can get the PublicKeyToken from the VS Command Line by typing:
sn –T DLLName.dll
If you need to generate a public key token based on a full public key, this little static method works:
private static byte[] GetKeyTokenFromFullKey(byte[] fullKey)
{
SHA1CryptoServiceProvider csp = new SHA1CryptoServiceProvider();
byte[] hash = csp.ComputeHash(fullKey);
byte[] token = new byte[8];
for (int i = 0; i < 8; i++ )
token[i] = hash[hash.Length - (i+1)];
return token;
}
From ECMA-335:
This declaration is used to store the low 8 bytes of the SHA-1 hash of the originator’s
public key in the assembly reference, rather than the full public key.
An assembly reference can store either a full public key or an 8-byte “public key token.” Either can be used to
validate that the same private key used to sign the assembly at compile time also signed the assembly used at
runtime. Neither is required to be present, and while both can be stored, this is not useful.
[Rationale: The public key or public key token stored in an assembly reference is used to ensure that the
assembly being referenced and the assembly actually used at runtime were produced by an entity in possession
of the same private key, and can therefore be assumed to have been intended for the same purpose. While the
full public key is cryptographically safer, it requires more storage in the reference. The use of the public key
token reduces the space required to store the reference while only weakening the validation process slightly.
end rationale]
As for how the hash is calculated (I assume this may be what you're asking since the public key token is not "calculated"), from the same spec:
The CLI metadata allows the producer of an assembly to compute a cryptographic hash of that assembly (using
the SHA-1 hash function) and then to encrypt it using the RSA algorithm (see Partition I) and a public/private
key pair of the producer’s choosing. The results of this (an “SHA-1/RSA digital signature”) can then be stored
in the metadata (§25.3.3) along with the public part of the key pair required by the RSA algorithm. The
.publickey directive is used to specify the public key that was used to compute the signature. To calculate
the hash, the signature is zeroed, the hash calculated, and then the result is stored into the signature.
The Strong Name (SN) signing process uses standard hash and cipher algorithms for Strong name signing. An
SHA-1 hash over most of the PE file is generated. That hash value is RSA-signed with the SN private key. For
verification purposes the public key is stored into the PE file as well as the signed hash value.
Except for the following, all portions of the PE File are hashed:
• The Authenticode Signature entry: PE files can be authenticode signed. The authenticode
signature is contained in the 8-byte entry at offset 128 of the PE Header Data Directory
(“Certificate Table” in §25.2.3.3) and the contents of the PE File in the range specified by this
directory entry. [Note: In a conforming PE File, this entry shall be zero. end note]
• The Strong Name Blob: The 8-byte entry at offset 32 of the CLI Header (“StrongNameSignature”
in §25.3.3) and the contents of the hash data contained at this RVA in the PE File. If the 8-byte
entry is 0, there is no associated strong name signature.
• The PE Header Checksum: The 4-byte entry at offset 64 of the PE Header Windows NT-Specific
Fields (“File Checksum” in §25.2.3.2). [Note: In a conforming PE File, this entry shall be zero.
end note]
You can download the spec here for free: http://www.ecma-international.org/publications/standards/Ecma-335.htm
A public key token is used to identify the organization in a strongly named assembly. This information is added to the assembly metabase. I would assume Richard is correct about the technical way it is stored.
If you want to view the metabase of an assembly, use ILDASM. You can drill down into what is stored in the metabase in addition to seeing the IL.
It is the hash bytes of the key used to sign the assembly.
So rather than listing out hundreds of hex digits for the key, you have something simpler, but still with little risk of collisions.