EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Signing MS office binary documents

Also by EldoS: MsgConnect
Cross-platform protocol-independent communication framework for building peer-to-peer and client-server applications and middleware components.
#19546
Posted: 03/21/2012 08:38:53
by NIkolai  (Basic support level)
Joined: 12/06/2011
Posts: 8

Hello Eldos team, I am using SecureBlackBox for java and I am trying to sign MS Word 2003 file. Here is my code:

InputStream is = new FileInputStream("D:\\newTestDoc.doc");
TElMemoryStream ms = new TElMemoryStream(is);
TElOfficeBinaryDocument officeDocument = new TElOfficeBinaryDocument();
SBOffice.Initialize();
SBOfficeSecurity.Initialize();
officeDocument.Open(ms);
TElOfficeBinaryCryptoAPISignatureHandler BinCryptoAPISigHandler = new TElOfficeBinaryCryptoAPISignatureHandler();
officeDocument.AddSignature(BinCryptoAPISigHandler, true); TElX509Certificate signerCertificate = new TElX509Certificate();
byte[] certTmp = getBytesFromCertFile();
if(certTmp != null){
int buffCertInfo = signerCertificate.LoadFromBufferPFX(certTmp, "password");
BinCryptoAPISigHandler.SetCertificate(signerCertificate);
BinCryptoAPISigHandler.SetSignTime(new Date());
BinCryptoAPISigHandler.Sign(); // HERE THE CODE THROWS EXCEPTION ("SecureBlackbox.Office.EElCompoundFileReadError: Failed to read data from mini stream
at SecureBlackbox.Office.TElCompoundFileVirtualStream.Init(SBCompoundFile.pas:2212)
at SecureBlackbox.Office.TElCompoundFileStreamEntry.GetVirtualStream(SBCompoundFile.pas:2695)
at SecureBlackbox.Office.TElCompoundFileStreamEntry.SBCompoundFile$$111GetVirtualStream$public(SBCompoundFile.pas)
at SecureBlackbox.Office.TElOfficeBinaryCryptoAPISignatureHandler.GenerateSignatureHash(SBOfficeSecurity.pas:6180)
at SecureBlackbox.Office.TElOfficeBinaryCryptoAPISignatureHandler.Sign(SBOfficeSecurity.pas:6362)......
").

getBytesFromCertFile() is :
byte[] bytesFromFile = null;
try {
bytesFromFile = FileUtils.getBytesFromFile(new File "D:\\cert.pfx"));
} catch (IOException e1) {
e1.printStackTrace();
}
return bytesFromFile;

I am using your certificate from the java package\Extra\cert.pfx. I sow the code from samples for C#, so most likely I am missing something. Should I look somewhere else? Thank you for your time.
#19549
Posted: 03/21/2012 10:39:54
by Vsevolod Ievgiienko (EldoS Corp.)

Thank you for contacting us.

I've just successfully checked OfficeBlackbox for Java using internal self-test. Your code seems to be correct. Could you please post the input file to the Helpdesk so we'll be able to reproduce the problem locally.
#19553
Posted: 03/22/2012 02:31:14
by NIkolai  (Basic support level)
Joined: 12/06/2011
Posts: 8

Thank you for your confirmation about the code. I found the problem! I was truing to sign an empty MS Word 2003 file. The code works just fine when I save some words in the file! May be this is the Exception you throw when someone try to sign an empty file!
#19555
Posted: 03/22/2012 05:21:02
by NIkolai  (Basic support level)
Joined: 12/06/2011
Posts: 8

Can I ask another question then? Do you have any examples about getting certificate from smartcard and then signing the MS Word file? I was looking at the forum and examples, but I could not find anything working in java.
#19567
Posted: 03/23/2012 03:12:42
by Vsevolod Ievgiienko (EldoS Corp.)

Currently Java edition doesn't support PKCS#11 that is used to access smartcards. Its implementation is planned for the 10the version of SecureBlackbox.

For now you can use Sun PKCS#11 provider (see http://docs.oracle.com/javase/1.5.0/d...uide.html). You can read a certificate using it, then serialize it to DER format and convert to our TElX509Certificate object using its LoadFromBuffer method.
#19576
Posted: 03/23/2012 05:00:05
by NIkolai  (Basic support level)
Joined: 12/06/2011
Posts: 8

Thank you for your reply. I am have some expirience with java PKCS#11, but I am facing dificulties trying to generate your TElX509Certificate object. I would appritiate your help if you have some expirience with serialize it to DER format. My code is :

PrivateKey privateKey;
Provider pkcs11Provider = null;
ByteArrayInputStream configStream = null;
String pkcs11config = "";
KeyStore smartCardKeyStore = null;
byte[] pkcs11configBytes = null;
X509Certificate cert = null;
char[] pin = {'1', '1', '1', '1'};
try{
//Security.addProvider(new BouncyCastleProvider());
//String pkcs11config = "name = SmartCard\n" + "library = c:\\windows\\system32\\siecap11.dll";
pkcs11config = "name = SmartCard\n" + "library = c:\\windows\\system32\\cmp11.dll";
try{
pkcs11configBytes = pkcs11config.getBytes();
configStream = new ByteArrayInputStream(pkcs11configBytes);
pkcs11Provider = new sun.security.pkcs11.SunPKCS11(configStream);
Security.addProvider(pkcs11Provider);
smartCardKeyStore = KeyStore.getInstance("PKCS11");
smartCardKeyStore.load(null, pin);
}catch(Exception eCmp11){
pkcs11config = "name = SmartCard\n" + "library = c:\\windows\\system32\\siecap11.dll";
try{
pkcs11configBytes = pkcs11config.getBytes();
configStream = new ByteArrayInputStream(pkcs11configBytes);
pkcs11Provider = new sun.security.pkcs11.SunPKCS11(configStream);
Security.addProvider(pkcs11Provider);
smartCardKeyStore = KeyStore.getInstance("PKCS11");
smartCardKeyStore.load(null, pin);
}catch(Exception eSeicap11){

}
}
KeyStore keyStore = smartCardKeyStore;
Enumeration<String> aliasesEnum = keyStore.aliases();
while (aliasesEnum.hasMoreElements()) {
String alias = (Stri ng)aliasesEnum.nextElement();
cert = (X509Certificate) keyStore.getCertificate(alias);
privateKey = (PrivateKey) keyStore.getKey(alias, null);

signerCertificate.LoadFromBuffer(cert.getEncoded()); // convert to your TElX509Certificate
System.out.println("load from byte[] p12 ---<> " + signerCertificate.GetCanSign());

}

}catch(Exception io){
io.printStackTrace();
}
configStream.close();

As you can see, I have the cert(Public Key) and the Private Key wich are separated, but I am missing the step "serialize it to DER format ". The last step I think is :
signerCertificate.LoadFromBuffer(cert.getEncoded()); // convert to your TElX509Certificate
just before System.out.println. Can you help me with how to combine the two keys in one certificate and then create your TElX509Certificate object?
#19577
Posted: 03/23/2012 05:07:29
by Vsevolod Ievgiienko (EldoS Corp.)

cert.getEncoded() returns DER encoded certificate. So you code is correct but you should also add a call to signerCertificate.LoadKeyFromBufferAuto because the private key is stored in privateKey buffer separately.
#31618
Posted: 12/09/2014 04:41:32
by Vu Duong Phuong (Basic support level)
Joined: 12/09/2014
Posts: 1

Quote
Vsevolod Ievgiienko wrote:
cert.getEncoded() returns DER encoded certificate. So you code is correct but you should also add a call to signerCertificate.LoadKeyFromBufferAuto because the private key is stored in privateKey buffer separately.


Hi Vsevolod
As far as I know, PrivateKey object is obtained from SmartCard or any Security device through PKCS#11 is unextractable and this Object is just a handle. So how could it be loaded by LoadKeyFromBufferAuto function?
#31619
Posted: 12/09/2014 04:45:45
by Vsevolod Ievgiienko (EldoS Corp.)

Vu Duong Phuong, I wrote about a public part of a certificate that is usually exportable, but not about a private key.

P.S. I've re-read the topic and your remark is correct. My suggestion will work only for exportable private keys. Anyway tha latest version of SecureBlackbox for Java support PKCS#11, so you can read and use un-exportable certificates easy.
Also by EldoS: CallbackFilter
A component to monitor and control disk activity, track file and directory operations (create, read, write, rename etc.), alter file data, encrypt files, create virtual files.

Reply

Statistics

Topic viewed 2651 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!