Quoting a jsign bug report related How to validate authenticode for Javascript in C#.
I've played a bit with VBScript and JScript files, it looks like the hashing method is different from the PowerShell scripts. For PowerShell the content is converted to UTF-16LE before being hashed. For VB and JS it doesn't work, the hash generated differs from the one computed by signtool. I tried various encodings (UTF-8, UTF-16BE, UTF-32BE/LE, with or without byte order marks) but it still doesn't match.
How does one create the .vbs signature block without signtool.exe (and without any proprietary and/or Microsoft tools?)
Edit:
So far, I've observed the following:
By default, signtool.exe uses SHA-1 signatures. It can be forced to use SHA-256 signatures using /fd sha256
By default, JSign adds some additional properties to the signature which throw off an exact signature match.
For reference, this is what the end-product signature normally looks like when using signtool.exe.
'' SIG '' Begin signature block
'' SIG '' MIIM4AYJKoZIhvcNAQcCoIIM0TCCDM0CAQExCzAJBgUr
' ... (a bunch of bas64 data) ...
'' SIG '' cSu0HJyT7v9OctFKlKj7aCB6JHPrR0il9GFdoZrQFNuU
'' SIG '' End signature block
The purpose of this signature is to allow Windows to verify the publisher of the file. It's not a well-documented standard, but can be found in solutions like this.
Modern purposes may include running a .vbs file as a standalone script or as part of an application. Leveraging Windows' built-in validation mechanism adds a layer of trust to the script for environments that need it.
Quoting Chapter 28 of Don Jones' "Managing Windows with VBScript and WMI."
Running Only Signed Scripts
If you don't want to mess around with software restriction policies, you can also rely on WSH's own built-in form of security policy. This policy allows you to specify that only signed scripts will be run; unsigned scripts won't be. This is probably the easiest and most effective way to prevent most unauthorized scripts.
Digital signatures are common enough so that we shouldn't be limited by closed source utilities like signtool.exe.
Quoting Emmanuel Bourg, the author of JSign from the bug that inspired this question:
I got it, the script is indeed hashed in UTF-16LE, but the size of the unsigned file encoded as a 4 bytes little endian integer is added to the hash.
So, common hashing algorithms will work against hashable content (SHA-1, SHA-256), but in order to pass WinVerifyTrust, the additional 4 bytes need to be added to the hashed data.
Related
I have a theoretical question about PAdES. I want to know if it is possible to revoke a signature in PDF or remove it?
I don't know what exactly you technically mean by revoking a signature.
But it clearly is possible to remove a signature: An integrated PDF signature usually consists of a signature form field with a value that contains a CMS signature container.
You have the choice of either removing only that value or the whole field with the value.
The former option leaves an empty signature field, which can easily be used for a new signature with a visualization at the same location as your original signature (if it has any to start with).
The latter option removes your signature completely.
Two caveats, though:
If you don't merely want the signature not to appear anymore, make sure that
you don't save this edit as an incremental update - if it was done as an incremental update, the document version with your signature could easily be restored;
you don't merely remove the reference to the the value from the signature field but that you actually clear the value object - the signature value object might be referenced from other locations in the PDF, too, so if you don't clear it, its information might remain accessible inside the PDF.
If your PDF contains multiple signatures or document timestamps, and if the signature you want to remove is not the newest one, manipulating it will break at least all newer signatures / time stamps. This is due to the way multiple signatures are applied to PDFs:
As you can recognize in this sketch, the bytes signed by newer signatures contain all older signatures.
In such a situation, therefore, don't only implement "remove a single target signature" but instead "remove all signature starting at a single target signature".
For some more technical backgrounds on integrated PDF signatures cf. this answer and documents referenced from there.
With iText 5.5.4, if I choose to embed CRLs during the signature process, it breaks the PDF/A-2B conformance because of a String too long error :
Adobe Preflight http://img4.hostingpics.net/pics/234201so5.jpg
As you can see in the preflight from Adobe Acrobat Pro 11.0.09, the CRL is 67107 characters long whereas this specific PDF standard require that the maximum length for strings must not exceed 32767 bytes.
Is it a bug in Itext or is there a way to keep PDF/A-2B conformance in that case?
Is it a bug in Itext?
As you can see in the preflight from Adobe Acrobat Pro 11.0.09, the CRL is 67107 characters long whereas this specific PDF standard require that the maximum length for strings must not exceed 32767 bytes
Considering that the problem string is referenced as 1 0 obj/Contents seems to indicate that it actually is the string reserved for the CMS signature container, not the plain CRL.
Looking at the PDF/A specification (I only have part 3 at hands but the parts 2 and 3 should coincide here) there are two sections which seem to contradict each other:
A conforming file shall not contain any string longer than 32767 bytes.
(section 6.1.13 Implementation limits)
and
timestamping and revocation information should be included [in the PDF Signature (a DER-encoded PKCS#7 binary data object)] in order to improve the long-term non-repudiation properties of the signature.
(Annex B Requirements for digital signatures in PDF/A)
In your case following the latter recommendation breaks the former requirement because the PKCS#7 / CMS object is embedded as a string in the PDF.
But as we have a requirement against a recommendation, the recommendation need only be followed as long as the requirements are not violated. The specification even explicitly says so:
When generating signature appearances and any other PDF objects as part of the signing process, a
conforming reader shall ensure that it does not invalidate compliance with this part of ISO 19005
(section 6.4.3 Digital signatures)
Thus indeed, iText signing should fail during the signing process... if you have used the PDF/A aware API, that is. Unfortunately you have not provided your source code, so it is not clear whether or not you have used the PdfAStamper or merely the PdfStamper.
Or is there a way to keep PDF/A-2B conformance in that case?
You didn't supply your source code, so this can only be answered in a more general way.
First of all check whether the space reserved for the signature container is really required or whether there are many padding bytes. In the latter case fine tune the reservation code.
If that does not suffice, embedding the CRL into the signature container automatically results in a violation of PDF/A conformance and, therefore, is not allowed.
One option would then be to try to use OCSP responses instead of CRLs here. OCSP responses usually contain information for only one or at most very few certificates while CRLs can become quite big.
If the CA does not have OCSP servers, I don't see a true PDF/A-2'ish solution. You might want to try to embed validation related information in PAdES part 4 (ETSI TS 102 778-4) DSS (Document Security Store) structures instead of in the signature container. Plain PDF/A viewers most likely won't recognize, let alone use, the CRL there but more versatile viewers, e.g. current Adobe Reader versions, should.
Lets say you have some code in your app with a hard coded string.
If somevalue = "test123" Then
End If
Once the application is compiled, is it possible for someone to modify the .exe file and change 'test123' to something else? If so, would it only work if the string contained the same number of characters?
It's possible but not necessarily straightforward. For example, if your string is loaded in memory, someone could use a memory manager tool to modify the value of the string's address directly.
Alternatively, they could decompile your app, change the string, and recompile it to create a new assembly with the new string. However, whether this is likely to happen depends on your app and how important it is for that string to be changed.
You could use an obfuscator to make it a bit harder to do but, ultimately, a determined cracker would be able to do it. The question is whether that string is important enough to worry about and, if so, maybe consider an alternative approach such as using a web service to provide the string.
Strings hard-coded without any obfuscation techniques can easily be found inside compiled executables by openign them up in any HEX-editor. Once found, replacing the string is possible in 2 ways :
1. Easy way (*conditions apply)
If the following conditions apply in your case, this is a very quick-fire way of modifying the hard-coded strings in the executable binary.
length(new-string) <= length(old-string)
No logic in the code to check for executable modification using CRC.
This is a viable option ONLY if the new string is equal or shorter than the old string. Use a hex-editor to find occurrences of the old string and replace it with the new string. Pad an extra space with NULL i.e. 0x00
For example old-long-string in the binary
is modified to a shorter new-string and padded with null characters to the same length as the original string in the binary executable file
Note that such modifications to the executable files are detected by any code that verifies the checksum of the binary file against the pre-calculate checksum of the original binary executable file.
2. Harder way (applicable in almost all cases)
De-compiling the binary to native code opens up the possibility to modify any strings (and even code) and rebuild it to obtain the new binary executable.
There exist dozens of such de-compiler tools to decompile vb.net (Visual Studio.net, in general). An excellent detailed comparison of the most popular ones (ILspy, JustDecompile, DotPeek, .NET Reflector to name a few ) can be found here.
There do exist scenarios in which even the harder way will NOT be successful. This is the case when the original developer has used obfuscation techniques to prevent the strings from being detected and modified in the executable binary. One such obfuscation technique is storing encrypted strings.
Is it safe to replace some characters of a string resides in a DLL file using a Hex Editor? I'm not going to introduce new chars or remove any existing one, so the file size won't be changed. And what I am going to do is to replace some embedded SQL string which is written in lower-case, and make the chars of that string upper-case. Is it OK, or does it corrupt the DLL and make it unloadable? By the way, this DLL is not digitally signed with a code signing certificate.
unless the owner of the dll does some kind of validation of it, using a checksum for instance, it won't break anything.
(afaik most windows system dlls are watched somehow for modifications and windows will complain if you change them)
I am using PKCS#1 2.0 (OAEP) standard (signature with appendix), but there are some issues not clear to me.
What is the physical object that is beeing signed? I know it's hash function value and so on (I do know the algorithm), but is it calculated from the binary fform of the file, no matter what is the content?
What is the physical result of signing? A file containing the signed hash? Should this file be placed in a specified location? What is the format or extension of such thing?
If I have several files that I want to sign, should this operation be performed separately for each of them? Or should they be concatenated? Once again - what is the result of such operation (file?) ?
PKCS#1 is sometimes called 'raw RSA' and is a low-level cryptographic primitive: it doesn't work on files and doesn't produce files, it works on raw data: input is a number smaller than the public key and output is a number of the size of the public key (e.g. 1024 bit for RSA-1024).
If you want a signature file, you probably want to use PKCS#7/CMS format, as that's the most used signature format both for attached and detached signatures (even signatures in PDF files are usually PKCS#7 envelopes actually).
PS: I don't know much about OAEP, but from what I read it seems to be a padding scheme (something you do to data before the raw signature) so my argument should be still valid.