EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Signing MS office binary documents

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.
#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: MsgConnect
Cross-platform protocol-independent communication framework for building peer-to-peer and client-server applications and middleware components.

Reply

Statistics

Topic viewed 2638 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!