I'm building an app that lets user digitally sign a PDF. I'm using plugPDF SDK. It has no built in support for generating byte range digest so I have to do it myself. PlugPDF generates the PDF content from which I generate signed hash in Terminal:
openssl dgst -hex -sha256 -sign privateKey.pem -out encrypted.out invoice.content
From this hash I generate the PKCS#7 object:
openssl cms -in encrypted.out -sign -signer signer.pem -outform der -out cert.p7b
Then I inject it into the PDF using the plugPDF SDK. When I open it in Adobe Acrobat the PDF is signed but the signature is invalid. It says: “The Document has been altered or corrupted since the Signature was applied.”
I assume the problem is wrong hash value but I have no idea how else to generate it.
Here's an example tutorial: https://plugpdf.com/how-to-sign-pdf-document-with-pki-certificate-on-ios/
The byte range digest for PDFs typically exclude the area of the PDF where the signature will be injected, so that the digest value should be the same before and after adding the signature. If they are not the same, then the assumption is that the file has been in some way modified since being signed.
It doesn't look like openssl's dgst command allows you to specify discontinuous byte ranges.
Related
We had to replace our signature pad by another product because product was discontinued and pens was very hard to find. We buy Topaz GemView Tablet Display
When customer sign on pad, our custom application watch folder for signed PDF and custom application print paper copy for our backyard staff and one for the customer if they want it
Our custom application use GhostScript to send PDF to specific printer.
Everything work fine with the old signature pad and GhostScript 9.16 on Windows 2012
With the Topaz pad, the PDF print, but there are no signature.
I have updated GhostScript to the latest version, 9.53.3, no signature
Here is a link to a sample signed PDF :
https://wetransfer.com/downloads/997a149ab09640d523397248ae6b161020210127144440/e5adad1b76799726522899389fe9415620210127144513/21e3e8
Here is the command line that I use to send PDF to the printer
gswin64c.exe -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -dNumCopies=1 -sPAPERSIZE=letter -sDEVICE=mswinpr2 -sOutputFile="\\spool\\\srv\ColorPaper" "Signed.Pdf"
If I remove all parameter, we can see signature on the screen
gswin64c.exe "Signed.Pdf"
Does GhostScript can print digital signature on paper ?
Thank you
Like chrisl say in it's comment, by changing parameter "-dPrinted" for "-dPrinted=false" solve this issue.
The signature field in the PDF are flagged as "not printable".
When using "-dPrinted=false", GhostScript print PDF like it appear on screen
I’m trying to Sign a XML document in iOS. I already created a digestValue and a SignatureValue using a pfx file, but I cannot generate the X509Certificate field inside KeyInfo field. I know I only need the pfx file to generate this, but how could I do it in iOS?
Thank you.
I got it.
I had to import OpenSSL lib to my project as a pod:
pod 'OpenSSL-Universal', '~> 1.0'
Then I created an Objective-C file to use the C functions of OpenSSL, and use the following functions to get the PEM value:
d2i_PKCS12: read certificate
PKCS12_parse: parse the certificate to X509 object.
PEM_write_bio_X509: parse the X509 data to a BIO object.
BIO_get_mem_ptr: parse the BIO data to a MEM data
Then I allocated a NSString using the mem->data, and there is the Certificate PEM value.
For more details about the functions, I followed this documentation:
https://www.openssl.org/docs/man1.0.2/crypto/
I am not sure if I am doing something wrong here but I've been stuck on this issue for quite some time. I am using the Ruby-saml gem (https://github.com/onelogin/ruby-saml) and I am not sure if my settings.certificate is valid. I used OpenSSL to generate the public/private key pair. Here is my public key:
$ cat cert.pem
-----BEGIN CERTIFICATE-----
MIIE3zCCA8egAwIBAgIJANtTrhsq7mkmMA0GCSqGSIb3DQEBBQUAMIGlMQswCQYD
VQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxDzANBgNVBAcTBkl0aGFjYTEbMBkG
A1UEChMSQ29ybmVsbCBVbml2ZXJzaXR5MQ4wDAYDVQQLEwVEeXNvbjEjMCEGA1UE
AxMaY3VtaW5vcnMuZHlzb24uY29ybmVsbC5lZHUxIDAeBgkqhkiG9w0BCQEWEW5t
YzUyQGNvcm5lbGwuZWR1MB4XDTE2MDQxMjE4MTUzOVoXDTI2MDQxMDE4MTUzOVow
gaUxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazEPMA0GA1UEBxMGSXRo
YWNhMRswGQYDVQQKExJDb3JuZWxsIFVuaXZlcnNpdHkxDjAMBgNVBAsTBUR5c29u
MSMwIQYDVQQDExpjdW1pbm9ycy5keXNvbi5jb3JuZWxsLmVkdTEgMB4GCSqGSIb3
DQEJARYRbm1jNTJAY29ybmVsbC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCnVjE8GIJe19Ba+361+c7ATDhBrzpGQoe+IDrDWw8B68HayaAvC8Pq
WdNQNQ3SfHOdb+Vv0eywxHG7wRVVrJ+f8fLqmHBHfthzRG1JnGhReUXb/+wfkUEw
DFZPEnEcj6rBcSbX5nsLVvupMXw43XB7ev/NX1SLsRU4trS25YMOozxjL+SfcKsW
IQPgqD3usIArwS6b3UQ+ftuVfmWqKEqoUq25tUXoAporFkJyVqXZqe4g/Q+WqbX4
cD9e1u7q8OlbSeVXUyPwRsNXzn1n+8tUbCc2k8+glEW5UJk7DY0AP95ry0ZcpfLr
kgaOTqvbkUWCaZH1FP04SYG5Csw/8IDtAgMBAAGjggEOMIIBCjAdBgNVHQ4EFgQU
q3ybbMNZOEXWgJ7/K0mSMx3VeTMwgdoGA1UdIwSB0jCBz4AUq3ybbMNZOEXWgJ7/
K0mSMx3VeTOhgaukgagwgaUxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9y
azEPMA0GA1UEBxMGSXRoYWNhMRswGQYDVQQKExJDb3JuZWxsIFVuaXZlcnNpdHkx
DjAMBgNVBAsTBUR5c29uMSMwIQYDVQQDExpjdW1pbm9ycy5keXNvbi5jb3JuZWxs
LmVkdTEgMB4GCSqGSIb3DQEJARYRbm1jNTJAY29ybmVsbC5lZHWCCQDbU64bKu5p
JjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBA8QEvcxLnjZURGb5/
a4JUVwU6noFdZpmI9FgBi7d3nKs+BNxL/1Het6Kk19T1kPlyDdG96asG6fbRH24G
cJOoDvVpx6lxMu85gFpJVv/vtDmnlpiBoDH+v2I7O4ENhve76B7Z5XtT5FsjEdy4
RAn1iczxq391vFNQJl0kCz2Khdv5CS3t6qNS42sPcRk9mjbnN0wz6jHxG5BfCVdk
dXxoLuJVLzT7/sbBkT2SLkwQkPiYitb3LFoNFu+Sk8y+L4cVaeoA5XoEjmIbtkgD
oLCrILf6t18C/R2AD0/huq2pFtxd/rng/yGMniTBc6aGDsv06RXo/5r7DsO0feXV
cRzc
-----END CERTIFICATE-----
In Rails I tried multiple different way to get this to work:
settings.certificate = "-----BEGIN CERTIFICATE-----
MIIE3zCCA8egAwIBAgIJANtTrhsq7mkmMA0GCSqGSIb3DQEBBQUAMIGlMQswCQYD
VQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxDzANBgNVBAcTBkl0aGFjYTEbMBkG
A1UEChMSQ29ybmVsbCBVbml2ZXJzaXR5MQ4wDAYDVQQLEwVEeXNvbjEjMCEGA1UE
AxMaY3VtaW5vcnMuZHlzb24uY29ybmVsbC5lZHUxIDAeBgkqhkiG9w0BCQEWEW5t
YzUyQGNvcm5lbGwuZWR1MB4XDTE2MDQxMjE4MTUzOVoXDTI2MDQxMDE4MTUzOVow
gaUxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazEPMA0GA1UEBxMGSXRo
YWNhMRswGQYDVQQKExJDb3JuZWxsIFVuaXZlcnNpdHkxDjAMBgNVBAsTBUR5c29u
MSMwIQYDVQQDExpjdW1pbm9ycy5keXNvbi5jb3JuZWxsLmVkdTEgMB4GCSqGSIb3
DQEJARYRbm1jNTJAY29ybmVsbC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQCnVjE8GIJe19Ba+361+c7ATDhBrzpGQoe+IDrDWw8B68HayaAvC8Pq
WdNQNQ3SfHOdb+Vv0eywxHG7wRVVrJ+f8fLqmHBHfthzRG1JnGhReUXb/+wfkUEw
DFZPEnEcj6rBcSbX5nsLVvupMXw43XB7ev/NX1SLsRU4trS25YMOozxjL+SfcKsW
IQPgqD3usIArwS6b3UQ+ftuVfmWqKEqoUq25tUXoAporFkJyVqXZqe4g/Q+WqbX4
cD9e1u7q8OlbSeVXUyPwRsNXzn1n+8tUbCc2k8+glEW5UJk7DY0AP95ry0ZcpfLr
kgaOTqvbkUWCaZH1FP04SYG5Csw/8IDtAgMBAAGjggEOMIIBCjAdBgNVHQ4EFgQU
q3ybbMNZOEXWgJ7/K0mSMx3VeTMwgdoGA1UdIwSB0jCBz4AUq3ybbMNZOEXWgJ7/
K0mSMx3VeTOhgaukgagwgaUxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9y
azEPMA0GA1UEBxMGSXRoYWNhMRswGQYDVQQKExJDb3JuZWxsIFVuaXZlcnNpdHkx
DjAMBgNVBAsTBUR5c29uMSMwIQYDVQQDExpjdW1pbm9ycy5keXNvbi5jb3JuZWxs
LmVkdTEgMB4GCSqGSIb3DQEJARYRbm1jNTJAY29ybmVsbC5lZHWCCQDbU64bKu5p
JjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBA8QEvcxLnjZURGb5/
a4JUVwU6noFdZpmI9FgBi7d3nKs+BNxL/1Het6Kk19T1kPlyDdG96asG6fbRH24G
cJOoDvVpx6lxMu85gFpJVv/vtDmnlpiBoDH+v2I7O4ENhve76B7Z5XtT5FsjEdy4
RAn1iczxq391vFNQJl0kCz2Khdv5CS3t6qNS42sPcRk9mjbnN0wz6jHxG5BfCVdk
dXxoLuJVLzT7/sbBkT2SLkwQkPiYitb3LFoNFu+Sk8y+L4cVaeoA5XoEjmIbtkgD
oLCrILf6t18C/R2AD0/huq2pFtxd/rng/yGMniTBc6aGDsv06RXo/5r7DsO0feXV
cRzc
-----END CERTIFICATE-----"
I've also tried to just have Rails read the cert.pem file directly:
settings.certificate = OpenSSL::X509::Certificate.new(File.read("#{Rails.root}/cert.pem")).to_s
The issue is (which I am not sure is an issue), my key is a long inline string in the XML file (metadata for the SP)
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>
MIIE3zCCA8egAwIBAgIJANtTrhsq7mkmMA0GCSqGSIb3DQEBBQUAMIGlMQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxDzANBgNVBAcTBkl0aGFjYTEbMBkGA1UEChMSQ29ybmVsbCBVbml2ZXJzaXR5MQ4wDAYDVQQLEwVEeXNvbjEjMCEGA1UEAxMaY3VtaW5vcnMuZHlzb24uY29ybmVsbC5lZHUxIDAeBgkqhkiG9w0BCQEWEW5tYzUyQGNvcm5lbGwuZWR1MB4XDTE2MDQxMjE4MTUzOVoXDTI2MDQxMDE4MTUzOVowgaUxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazEPMA0GA1UEBxMGSXRoYWNhMRswGQYDVQQKExJDb3JuZWxsIFVuaXZlcnNpdHkxDjAMBgNVBAsTBUR5c29uMSMwIQYDVQQDExpjdW1pbm9ycy5keXNvbi5jb3JuZWxsLmVkdTEgMB4GCSqGSIb3DQEJARYRbm1jNTJAY29ybmVsbC5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnVjE8GIJe19Ba+361+c7ATDhBrzpGQoe+IDrDWw8B68HayaAvC8PqWdNQNQ3SfHOdb+Vv0eywxHG7wRVVrJ+f8fLqmHBHfthzRG1JnGhReUXb/+wfkUEwDFZPEnEcj6rBcSbX5nsLVvupMXw43XB7ev/NX1SLsRU4trS25YMOozxjL+SfcKsWIQPgqD3usIArwS6b3UQ+ftuVfmWqKEqoUq25tUXoAporFkJyVqXZqe4g/Q+WqbX4cD9e1u7q8OlbSeVXUyPwRsNXzn1n+8tUbCc2k8+glEW5UJk7DY0AP95ry0ZcpfLrkgaOTqvbkUWCaZH1FP04SYG5Csw/8IDtAgMBAAGjggEOMIIBCjAdBgNVHQ4EFgQUq3ybbMNZOEXWgJ7/K0mSMx3VeTMwgdoGA1UdIwSB0jCBz4AUq3ybbMNZOEXWgJ7/K0mSMx3VeTOhgaukgagwgaUxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazEPMA0GA1UEBxMGSXRoYWNhMRswGQYDVQQKExJDb3JuZWxsIFVuaXZlcnNpdHkxDjAMBgNVBAsTBUR5c29uMSMwIQYDVQQDExpjdW1pbm9ycy5keXNvbi5jb3JuZWxsLmVkdTEgMB4GCSqGSIb3DQEJARYRbm1jNTJAY29ybmVsbC5lZHWCCQDbU64bKu5pJjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBA8QEvcxLnjZURGb5/a4JUVwU6noFdZpmI9FgBi7d3nKs+BNxL/1Het6Kk19T1kPlyDdG96asG6fbRH24GcJOoDvVpx6lxMu85gFpJVv/vtDmnlpiBoDH+v2I7O4ENhve76B7Z5XtT5FsjEdy4RAn1iczxq391vFNQJl0kCz2Khdv5CS3t6qNS42sPcRk9mjbnN0wz6jHxG5BfCVdkdXxoLuJVLzT7/sbBkT2SLkwQkPiYitb3LFoNFu+Sk8y+L4cVaeoA5XoEjmIbtkgDoLCrILf6t18C/R2AD0/huq2pFtxd/rng/yGMniTBc6aGDsv06RXo/5r7DsO0feXVcRzc
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
The IdP people said it was not valid when they tried to use it, he gave me an example of theirs and theirs was split across many lines unlike mine which is just a long string with no space:
https://shibidp.cit.cornell.edu/idp/shibboleth
Am I doing something wrong here? All I did was take the output from cat and pasted it to my SAML Settings.
looks like your X509 doesn't have any line breaks. That might be your problem.
I have a .pem cert that I'm reasonably sure I generated correctly, and it is not being accepted by OpenSSL when I paste it into a Rails 3.0.2 model. What I do is this:
open up the .pem file in Textmate
select all and copy
user.cert = <paste into model>; user.save
OpenSSL::PKey::RSA.new(user.cert)
This gives me the error:
Neither PUB key nor PRIV key::
To test, I just loaded in the file instead, no errors:
OpenSSL::PKey::RSA.new(File.read("/path/to/cert.pem"))
I thought maybe it would be some encoding error or newline issue, I had tried gsub'ing out the newlines to no avail.
It was a weird copy and paste artifact indeed. I File.read'd it into the model instead of copy paste and it worked fine...
Perhaps late, but this is the answer:
You can put a public key inline in Ruby with copy/paste, but keep in mind that what looks like formatting to you is white space in the line - you need to make sure that the resulting pem string has no spaces. I just copied and pasted from a PEM file into Ruby code, and it did not work until I removed the extra spaces that text mate or whatever added to the lines.
Hard to show here:
SQS_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs3VeTxEgLQLL11UN2G6c
oQsc0LbpoEs4VTmu0S4XU82N4h/25XX5k4t5oTJ0JGGSBP4/gzTwz15vS5mrlnsG
MISSINGLINES
rMV5ZCXToG0VCNPEHpZQnUHMCg/nF9jnk9i1ZZHv2dpYYG7GHMUPG3rtcTWJvZxI
3wIDAQAB
-----END PUBLIC KEY-----".force_encoding("us-ascii")
SQS_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs3VeTxEgLQLL11UN2G6c
oQsc0LbpoEs4VTmu0S4XU82N4h/25XX5k4t5oTJ0JGGSBP4/gzTwz15vS5mrlnsG
MISSINGLINES
rMV5ZCXToG0VCNPEHpZQnUHMCg/nF9jnk9i1ZZHv2dpYYG7GHMUPG3rtcTWJvZxI
3wIDAQAB
-----END PUBLIC KEY-----".force_encoding("us-ascii")
ie - NOT the second one - ruby adds spaces to the start of each line, and the RSA tools do not ignore spaces - they only seem to ignore line feeds.
I use the copy/pasted key as a fallback - in other words if an ENV is set I use that, otherwise use the pasted in public key.
--Tom
I have to digitally sign a string using the SHA-1 algorithm with RSA using PKCS#1 padding. I have downloaded Turbo Power Lockbox to use with the Delphi programming language.
In a previous question I have learned how to convert private key from PEM format to DER format (which if I understand correctly is ASN.1 format and is used with Lockbox).
I am getting a "division by zero" error in the following code on the SignString:
uses LbRSA,lbAsym,LbDSA;
procedure TForm1.Button1Click(sender: TObject);
var
mPrivateKey: TLbRSAKey;
mLbRSASSA : TLbRSASSA;
begin
mPrivateKey := TLbRSAKey.Create(aks1024);
mPrivateKey.LoadFromFile('C:\temp\myrsakey.der');
mLbRSASSA := TLbRSASSA.create(nil);
mLbRSASSA.HashMethod := hmSHA1;
mLbRSASSA.PrivateKey.Assign(mprivateKey);
mLbRSASSA.SignString('sign this message');
Here is how I generated c:\temp\myrsakey.der:
c:\openssl\bin\openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj "/C=US/ST=CA/L=Mountain View/CN=www.mycompany.com" -keyout myrsakey.pem -out c:\temp\myrsacert.pem
Use following to convert from PEM to DER:
c:\openssl\bin\openssl rsa -inform PEM -outform DER -in c:\temp\myrsakey.pem -out c:\temp\myrsakey.der
Any ideas why I am getting the division by zero error?
The private key you are generating with OpenSSL is in a different format to what Lockbox requires.
I haven't worked out what the required incantation is that you need for OpenSSL to generate a Lockbox compatible key (even if OpenSSL is able to) but judging by your previous question you already have a key/certificate so my first idea of using Lockbox to generate the key is probably no use:
mLbRSASSA := TLbRSASSA.create(nil);
mLbRSASSA.KeySize := aks1024;
mLbRSASSA.GenerateKeyPair;
mLbRSASSA.PrivateKey.StoreToFile(mykeyname);
However, perhaps a better suggestion is that you could avoid Lockbox altogether. I've stopped using Lockbox and now use the OpenSSL library/dll directly for signing etc using the work by Marco Ferrante:
http://www.disi.unige.it/person/FerranteM/delphiopenssl/
There are good examples on there and it all starts to make sense once you combine it with a reading of the OpenSSL docs.