Verif CAPICOM generated signature in Java



I have a simple text string whose digital signature has been generated
using the MS CAPICOM libraray.
I have exportted the vertificate also using the same library.
This certificate is loaded into java JCE (bouncy castle provider), BUT
the java code (singature object) is not verifying that the digital
signature (generated by CAPICOM).

Can someone please help me in this regard. Follwing is the example
code.

/* make sure to register capicom.dll using regsvr32 utility */

package com.cdc.pkisolution;



/* open source provider of calling win dlls from java */
import com.jacob.activeX.*;
import com.jacob.com.*;

import java.security.cert.X509Certificate;
import java.security.spec.X509EncodedKeySpec;
import java.security.cert.CertificateFactory;
import java.security.Security;
import java.security.Provider;
import java.security.Signature;
import java.io.ByteArrayInputStream;
import java.util.Date;




/* bouncy castle jce provider */
import org.bouncycastle.util.encoders.Base64;

import java.security.PublicKey;
import java.security.PrivateKey;

public class TestForDigitalSignature
{
public TestForDigitalSignature()
{

}

private void executeTest() throws Exception
{

/* test data */
String dataToplay = "Cent";



// try
// {
// dataToplay = new String(dataToplay.getBytes(), "UTF-16");
// }
// catch(Exception e)
// {
// e.printStackTrace();
// }

/* Componenets to use */
ActiveXComponent signedData = new
ActiveXComponent("CAPICOM.SignedData");
ActiveXComponent signedData4v = new
ActiveXComponent("CAPICOM.SignedData");
ActiveXComponent store = new ActiveXComponent("CAPICOM.Store");
ActiveXComponent signer = new ActiveXComponent("CAPICOM.Signer");
ActiveXComponent utils = new ActiveXComponent("CAPICOM.Utilities");


// certificate store should be opened first
Dispatch.call(store,
"Open",
new Integer(4), //smart card store
"My",
new Integer(0));

// data to sign should reside in the content property of signeddata
object
//Variant binData = Dispatch.call( utils,
"ByteArrayToBinaryString", new Variant( dataToplay.getBytes() ));
Dispatch.put(signedData,"Content",dataToplay);

// export the certificate in order to use it in java code
Variant gotTheCert = Dispatch.call(store,
"Export",
new Integer(1), // PKCS7 = 1
new Integer(0)); // BASE 64 =
0

// put the certificate in signer object -- FM said that no need to
do this as it asks for certificate to select
//Dispatch.call(certificate.getObject(), "Import", new
String(gotTheCert.toString()));
//Dispatch.put(signer, "Certificate", certificate);



//sign the data

Variant signatureVariant = Dispatch.call(signedData,
"Sign",
signer.getObject(),
new Boolean( true ), //
detach
new Integer(0));
String signedDataValue = signatureVariant.getString();
//signedDataValue = signedDataValue.replaceAll ( "\n", "" ).trim();


/* verification of data on windows */

Variant verifiedVariant = null;



try
{
Dispatch.put(signedData4v,"Content",dataToplay);

verifiedVariant = Dispatch.call(signedData,
"Verify",
signedDataValue,
new Boolean( true ),
new Variant(0)); //verify
signature only
System.out.println("Signature verified Successfull");
}
catch(Exception e)
{
System.out.println("Signature verification unsuccessfull" +
e.getMessage());
e.printStackTrace();
}






String certificateString = gotTheCert.getString();

/* Init provider */
Provider bc = new
org.bouncycastle.jce.provider.BouncyCastleProvider();
//Provider bc = new iaik.security.provider.IAIK();
Security.addProvider( bc );



byte[] decodedBar = Base64.decode( certificateString );

try
{
/* Load certificate into java objcts */
CertificateFactory cf = CertificateFactory.getInstance("X.509",
bc);
ByteArrayInputStream bis = new ByteArrayInputStream( decodedBar
);

X509Certificate cert =
(X509Certificate)cf.generateCertificate(bis);
PublicKey publicKey = cert.getPublicKey();




//
System.out.println("/******************************************************************/");

// System.out.println(cert.getSigAlgName());
// System.out.println(cert.getVersion());
// System.out.println(cert.getNotBefore());
// System.out.println(cert.getNotAfter());
// System.out.println(cert.getSerialNumber());
// System.out.println(cert.getSigAlgOID());
// System.out.println( publicKey.getAlgorithm() );
// System.out.println( publicKey.getFormat() );
// System.out.println( cert.getIssuerX500Principal().getName() );
//
System.out.println("/******************************************************************/");




// VERIFICATION cODE
Date currentDate = new Date();
cert.checkValidity( currentDate );


// Init signature objects
Signature signature =
Signature.getInstance("MD5WithRSAEncryption", bc);
//MD5WithRSAEncryption
signature.initVerify( publicKey );


//byte[] signedDataValueBar = reverseBytes (
signedDataValue.getBytes("UTF-8") );
byte[] signedDataValueBar = signedDataValue.getBytes("UTF-8");

signature.update( dataToplay.getBytes("UTF-8") );
boolean pass = signature.verify( signedDataValueBar );
System.out.println("PASS RESULT: " + pass);
}
catch(Exception e)
{
e.printStackTrace();
}



}



public String toBin(byte buffer[])
{
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buffer.length; i++)
{
String s = Integer.toBinaryString((int) buffer[i]);
if (s.length() == 1)
s = "0" + s;
sb.append(s);
}
return (sb.toString());
}

public static byte[] reverseBytes(byte b[])
{
byte [] ret = new byte[b.length];
for (int i=0; i<b.length; i++)
{
ret[i] = b[b.length-1-i];
}
return ret;
}

public static void main (String[] args)
{
TestForDigitalSignature t = new TestForDigitalSignature();
try
{
t.executeTest();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

.



Relevant Pages

  • Re: Unable to verify signature with Sun JSSE
    ... and what doesn't work in Java. ... all of the input data (the public key, the SHA-1 hashed data that was ... previously signed by my private key, and the signature) as raw bytes ... bytepublicKey = ...
    (comp.lang.java.security)
  • Re: Reply with attachment macro
    ... the Insert -> Signature menu. ... Sub ReplyWithTemplateFromOutlook() ... Dim objReply As Outlook.MailItem ... Dim strSignatureText As String ...
    (microsoft.public.outlook.program_vba)
  • Unable to verify signature with Sun JSSE
    ... In a nutshell I cannot get signature verification to work, ... and what doesn't work in Java. ... all of the input data (the public key, the SHA-1 hashed data that was ... bytepublicKey = ...
    (comp.lang.java.security)
  • Re: Windows application key from a vendor
    ... much private mainframe owners interested in illegal operations, ... One is a longish key that in itself contains the licence information, ... The other is a plain text licence of some sort, plus a signature or hash so ... string changes very little with small predictable changes in e.g. the date. ...
    (bit.listserv.ibm-main)
  • Re: Error when I try to open cdrom programmatically
    ... private static extern long mciSendString(string lpstrCommand, ... unless you expect a rediculously long string. ... In fact I would rather use a StringBuilder in the signature. ... in which case the returnstring is initialized as follows ...
    (microsoft.public.dotnet.framework.windowsforms)