For the sake of closure and perhaps saving someone else from running off on the
same wild goose chase in the future, I thought I would post an update here.
The issue was related to my own lack of understanding of the Luna SA HSM. The
setup instructions with the device included generation of a client certificate
that was then installed on the HSM. I took this to mean that the client
certificate that was generated as part of that process was in fact the
certificate I would be using for signing.
After speaking with SafeNet support, I discovered that the client certificate
referred to in the documentation was not for general use and was related to
establishing the secure trusted relationship between the HSM and my computer.
Once I realized this, I was able to generate a test self-signed certificate
using makecert and just specifying the correct parameters:
makecert -sk keyContainerName -sp "Luna Cryptographic Services for
Microsoft Windows" -sy 1, -r -n "CN=issuer" -ss my test.cer
Once this was done, I had a certificate in the "My" store that essentially
contained pointers to the keys stored on the HSM. I was then able to use the
example code to quickly have success in signing the PDF.
Another case of an early misunderstanding leading to over-thinking and
over-engineering (that in this case still didn't end up working). In reality,
this integration is pretty straight forward. I'm including the sample C# code
that I have working for signing a PDF using the Luna HSM below. Thanks to all
of you that responded.
Mike
static void SignPdf()
{
X509Store store = new X509Store(StoreName.My,
StoreLocation.CurrentUser);
store.Open(OpenFlags.MaxAllowed);
X509Certificate2 cert = null;
int i = 0;
while ((i < store.Certificates.Count) && (cert == null))
{
if (store.Certificates[i].Subject == "CN=name")
cert = store.Certificates[i];
else
i++;
}
Org.BouncyCastle.X509.X509CertificateParser cp = new
Org.BouncyCastle.X509.X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new
Org.BouncyCastle.X509.X509Certificate[]{ cp.ReadCertificate(cert.RawData) };
PdfReader reader = new PdfReader(@"C:\file.pdf");
PdfStamper stp = PdfStamper.CreateSignature(reader, new
FileStream("c:\\file_signed.pdf", FileMode.Create), '\0');
stp.FormFlattening = true;
PdfSignatureAppearance sap = stp.SignatureAppearance;
sap.SignDate = DateTime.Now;
sap.SetCrypto(null, chain, null, null);
sap.Reason = "PDF Signing";
sap.Location = "My Location";
sap.Acro6Layers = true;
sap.Render =
PdfSignatureAppearance.SignatureRender.NameAndDescription;
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKMS,
PdfName.ADBE_PKCS7_SHA1);
dic.Date = new PdfDate(sap.SignDate);
dic.Name = PdfPKCS7.GetSubjectFields(chain[0]).GetField("CN");
if (sap.Reason != null)
dic.Reason = sap.Reason;
if (sap.Location != null)
dic.Location = sap.Location;
sap.CryptoDictionary = dic;
int csize = 4000;
Hashtable exc = new Hashtable();
exc[PdfName.CONTENTS] = csize * 2 + 2;
sap.PreClose(exc);
HashAlgorithm sha = new SHA1CryptoServiceProvider();
Stream s = sap.RangeStream;
int read = 0;
byte[] buff = new byte[8192];
while ((read = s.Read(buff, 0, 8192)) > 0)
sha.TransformBlock(buff, 0, read, buff, 0);
sha.TransformFinalBlock(buff, 0, 0);
byte[] pk = SignMsg(sha.Hash, cert, false);
byte[] outc = new byte[csize];
Array.Copy(pk, 0, outc, 0, pk.Length);
PdfDictionary dic2 = new PdfDictionary();
dic2.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true));
sap.Close(dic2);
}
static public byte[] SignMsg(Byte[] msg, X509Certificate2 signerCert,
bool detached)
{
// Place message in a ContentInfo object.
// This is required to build a SignedCms object.
ContentInfo contentInfo = new ContentInfo(msg);
// Instantiate SignedCms object with the ContentInfo above.
// Has default SubjectIdentifierType IssuerAndSerialNumber.
SignedCms signedCms = new SignedCms(contentInfo, detached);
// Formulate a CmsSigner object for the signer.
CmsSigner cmsSigner = new CmsSigner(signerCert);
// Include the following line if the top certificate in the
// smartcard is not in the trusted list.
cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;
// Sign the CMS/PKCS #7 message. The second argument is
// needed to ask for the pin.
signedCms.ComputeSignature(cmsSigner, false);
// Encode the CMS/PKCS #7 message.
return signedCms.Encode();
}
-----Original Message-----
From: Mike Chynoweth [mailto:[email protected]]
Sent: Friday, September 24, 2010 8:22 AM
To: Post all your questions about iText here
Subject: Re: [iText-questions] Luna SA (HSM) Integration with iTextSharp
Not that I've been able to see - although it is always possible that I'm just
missing something.
I can gain indirect access to the device using CspParameters to reference the
Luna Cryptographic Service Provider. This essentially gives me a handle I can
use for signing/verifying etc. As an example, the following works fine:
CspParameters csp = new CspParameters(1, "Luna Cryptographic Services for
Microsoft Windows");
csp.KeyContainerName = "containerName";
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp))
{
string originalString = "test";
byte[] originalData = Encoding.UTF8.GetBytes(originalString);
byte[] signedData = rsa.SignData(originalData, new
SHA1CryptoServiceProvider());
bool isValid = rsa.VerifyData(originalData, new
SHA1CryptoServiceProvider(), signedData);
Debug.Assert(isValid);
}
I've tried to use the .NET CmsSigner overload that accepts CspParameters as an
overload (instead of passing a certificate reference):
static public byte[] SignContent(Byte[] content, CspParameters
cspParameters, bool detached)
{
ContentInfo contentInfo = new ContentInfo(content);
SignedCms signedCms = new SignedCms(contentInfo, detached);
CmsSigner cmsSigner = new CmsSigner(cspParameters);
signedCms.ComputeSignature(cmsSigner, false);
return signedCms.Encode();
}
But when I do, I run into a "Bad Key" exception:
Exception:
System.Security.Cryptography.CryptographicException
Message:
Bad Key.
Stack Trace:
at
System.Security.Cryptography.Pkcs.PkcsUtils.CreateDummyCertificate(CspParameters
parameters)
at
System.Security.Cryptography.Pkcs.CmsSigner..ctor(CspParameters parameters)
at ConsoleApplication5.Program.SignContent(Byte[] content,
CspParameters cspParameters, Boolean detached) in
C:\dev\ConsoleApplication5\Program.cs:line 193
at ConsoleApplication5.Program.Main(String[] args)
at System.AppDomain._nExecuteAssembly(Assembly assembly,
String[] args)
at
Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
This makes it seem like there is something unsupported in the way I'm trying to
call it. I've dug into the issue further by making the CAPI calls directly,
and I've narrowed the issue down to the point in the internal .NET
'CreateDummyCertificate' method where the call to the CAPI method
'CertCreateSelfSignCertificate' is made (which is where the 'Bad Key' exception
occurs).
Given that others have gotten this to work on Java, I know the device supports
this type of use-case, and I know it's not an issue with iText/iTextSharp. So
at this point, I'm just trying to figure out the missing pieces with how it
should be implemented in .NET.
Mike
-----Original Message-----
From: Paulo Soares [mailto:[email protected]]
Sent: Friday, September 24, 2010 7:28 AM
To: Post all your questions about iText here
Subject: Re: [iText-questions] Luna SA (HSM) Integration with iTextSharp
The example http://itextpdf.sourceforge.net/howtosign.html#signextitextsharp2
should be able to sign with anything present in the windows certificate store,
including smartcards. Doesn't the Luna also appear in the certificate store?
Paulo
-----Original Message-----
From: Mike Chynoweth [mailto:[email protected]]
Sent: Friday, September 24, 2010 12:18 PM
To: Post all your questions about iText here
Subject: Re: [iText-questions] Luna SA (HSM) Integration with iTextSharp
Thanks for the responses - I appreciate the help. I've been able to apply
local certificates without an issue, but the difficulty I've been having is
with how to fit the Luna SA (HSM) piece into the puzzle. I've seen some great
resources and examples out there for doing this in Java, but I haven't found
how to do this in C#.
I've done a lot of experimentation with the built-in .NET classes as well as
taking a more direct approach and working directly with CAPI, etc.
Unfortunately, I still seem to be missing something with how the whole process
should work in a .NET (C#) environment.
Any further guidance that can be offered would be greatly appreciated. Thanks.
Mike
-----Original Message-----
From: msinatl [mailto:[email protected]]
Sent: Thursday, September 23, 2010 1:16 PM
To: [email protected]
Subject: Re: [iText-questions] Luna SA (HSM) Integration with iTextSharp
Hi Mike,
Here is another example:
http://geekcredential.wordpress.com/2010/09/13/signing-a-pdf-with-itext-and-a-luna-hsm/
Thanks to Cristophe; I borrowed his solution for building the certificate chain.
--
View this message in context:
http://itext-general.2136553.n4.nabble.com/Luna-SA-HSM-Integration-with-iTextSharp-tp2552278p2552414.html
Sent from the iText - General mailing list archive at Nabble.com.
------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in U.S. and Canada $10
million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store
http://p.sf.net/sfu/nokia-dev2dev
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://www.itextpdf.com/book/ Check the site with examples
before you ask questions: http://www.1t3xt.info/examples/ You can also search
the keywords list: http://1t3xt.info/tutorials/keywords/
------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in U.S. and Canada $10
million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store
http://p.sf.net/sfu/nokia-dev2dev
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://www.itextpdf.com/book/ Check the site with examples
before you ask questions: http://www.1t3xt.info/examples/ You can also search
the keywords list: http://1t3xt.info/tutorials/keywords/
Aviso Legal:
Esta mensagem ? destinada exclusivamente ao destinat?rio. Pode conter
informa??o confidencial ou legalmente protegida. A incorrecta transmiss?o desta
mensagem n?o significa a perca de confidencialidade. Se esta mensagem for
recebida por engano, por favor envie-a de volta para o remetente e apague-a do
seu sistema de imediato. ? proibido a qualquer pessoa que n?o o destinat?rio de
usar, revelar ou distribuir qualquer parte desta mensagem.
Disclaimer:
This message is destined exclusively to the intended receiver. It may contain
confidential or legally protected information. The incorrect transmission of
this message does not mean the loss of its confidentiality. If this message is
received by mistake, please send it back to the sender and delete it from your
system immediately. It is forbidden to any person who is not the intended
receiver to use, distribute or copy any part of this message.
------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store
http://p.sf.net/sfu/nokia-dev2dev
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://www.itextpdf.com/book/
Check the site with examples before you ask questions:
http://www.1t3xt.info/examples/
You can also search the keywords list: http://1t3xt.info/tutorials/keywords/
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://www.itextpdf.com/book/
Check the site with examples before you ask questions:
http://www.1t3xt.info/examples/
You can also search the keywords list: http://1t3xt.info/tutorials/keywords/