NCryptoki Result Vs Java Result

5/21/2012 7:09:50 AM
Gravatar
Total Posts 5

NCryptoki Result Vs Java Result

I recently downloaded Ncryptoki version to Sign my programs. We already use java version for some client programs. But the Sign bytes generated in Java and ncryptoki are different from each other. I use my token supports SHA1_RSA_PKCS.

5/21/2012 11:44:20 AM
Gravatar
Total Posts 300
Ugo Chirico http://www.ugochirico.com

Re: NCryptoki Result Vs Java Result

Hi,

Several customers use both NCryptoki and Java version to make digital signature, me too on several projects, but nobody till now has reported us a problem like yours.

NCryptoki is a wrapper to the underlying PKCS#11 module and it forwards the request to the underlying functions, the same as any Java version does. The signature is computed by the underlying PKCS#11 module.
What Java version are you using?
Are you sure you call the Sign method with the same algo and the same buffer to sign?

 

5/21/2012 12:23:53 PM
Gravatar
Total Posts 5

Re: NCryptoki Result Vs Java Result

Please find the Java version and the .net version i used.

 

Java

 

import java.applet.Applet;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.security.*;
import java.security.cert.CertPath;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.lang.reflect.Constructor;

//import netscape.javascript.JSException;
//import netscape.javascript.JSObject;

 

//import javax.mail.internet.MimeUtility;

/**
 * Applet for digital signing documents with a smart card. The applet is intended to
 * be placed in a HTML document containing a single HTML form that is used for applet
 * input/output. The applet accepts several parameters - the name of the field in the
 * HTML form that contains the file name to be signed and the names of the fields in
 * the HTML form, where the certification chain and signature should be stored.
 *
 * If the signing process is sucecssfull, the signature and certification chain fields
 * in the HTML form are filled. Otherwise an error message explaining the failure
 * reason is shown.
 *
 * The applet asks the user to locate in his local file system the PKCS#11
 * implementation library that is part of software that come with the smart card
 * and the smart card reader. Usually this is a Windows .DLL file located in Windows
 * system32 directory or .so library (e.g. C:\windows\system32\pkcs201n.dll).
 *
 * The applet also asks the user to enter his PIN code for accessing the smart card.
 * If the smart card contains a certificate and a corresponding private key, the
 * signature of the file is calculated and is placed in the HTML form. In addition
 * to the calculated signature the certificate with its full certification chain is
 * extracted from the smart card and is placed in the HTML form too. The digital
 * signature is placed as Base64-encoded sequence of bytes. The certification chain
 * is placed as ASN.1 DER-encoded sequence of bytes, additionally encoded in Base64.
 * In case the smart card contains only one certificate without its full certification
 * chain, a chain consisting of this single certificate is extracted and stored in the
 * HTML form instead of a full certification chain.
 *
 * Digital singature algorithm used is SHA1withRSA. The length of the calculated
 * singature depends on the length of the private key on the smart card.
 *
 * The applet should be able to access the local machine's file system for reading and
 * writing. Reading the local file system is required for the applet to access the file
 * that should be signed. Writing the local file system is required for the applet to
 * save its settings in the user's home directory. Accessing the local file system is
 * not possible by default, but if the applet is digitally signed (with jarsigner), it
 * runs with no security restrictions and can do anything. This applet should be signed
 * in order to run.
 *
 * Java Plug-In version 1.5 or hihger is required for accessing the PKCS#11 smart card
 * functionality, so the applet will not run in any other Java runtime environment.
 *
 * This file is part of NakovDocumentSigner digital document
 * signing framework for Java-based Web applications:
 * http://www.nakov.com/documents-signing/
 *
 * Copyright (c) 2005 by Svetlin Nakov - http://www.nakov.com
 * All rights reserved. This code is freeware. It can be used
 * for any purpose as long as this copyright statement is not
 * removed or modified.
 */
public class SmartCardSignerApplet extends Applet {

    private static final String FILE_NAME_FIELD_PARAM = "fileNameField";
    private static final String CERT_CHAIN_FIELD_PARAM = "certificationChainField";
    private static final String SIGNATURE_FIELD_PARAM = "signatureField";
    private static final String SIGN_BUTTON_CAPTION_PARAM = "signButtonCaption";
    private static final String VERIFY_BUTTON_CAPTION_PARAM = "verifyButtonCaption";

    private static final String PKCS11_KEYSTORE_TYPE = "PKCS11";
    private static final String X509_CERTIFICATE_TYPE = "X.509";
    private static final String CERTIFICATION_CHAIN_ENCODING = "PkiPath";
    private static final String DIGITAL_SIGNATURE_ALGORITHM_NAME = "SHA1withRSA";
    private static final String SUN_PKCS11_PROVIDER_CLASS = "sun.security.pkcs11.SunPKCS11";

    private Button mSignButton;
    private Button mVerifyButton;

    /**
     * Initializes the applet - creates and initializes its graphical user interface.
     * Actually the applet consists of a single button, that fills its all surface. The
     * button's caption is taken from the applet parameter SIGN_BUTTON_CAPTION_PARAM.
     */
    public void init() {
String signButtonCaption = this.getParameter(SIGN_BUTTON_CAPTION_PARAM);
mSignButton = new Button("Sign");
mSignButton.setLocation(0, 0);
Dimension appletSize = this.getSize();
mSignButton.setSize(appletSize.width/2, appletSize.height);
//mSignButton.setSize(appletSize);
mSignButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
signSelectedFile();
}});
this.setLayout(null);
this.add(mSignButton);

// verify button

String verifyButtonCaption = this.getParameter(VERIFY_BUTTON_CAPTION_PARAM);
mVerifyButton = new Button("Verify");
// Dimension appletSize = this.getSize();
mVerifyButton.setLocation(appletSize.width/2+1, 0);
mVerifyButton.setSize(appletSize.width/2, appletSize.height);
mVerifyButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
verifySignature();
}});
this.setLayout(null);
this.add(mVerifyButton);


}

/**
* Signs the selected file. The file name comes from a field in the HTML document.
* The result consists of the calculated digital signature and certification chain,
* both placed in fields in the HTML document, encoded in Base64 format. The HTML
* document should contain only one HTML form. The name of the field, that contains
* the name of the file to be signed is obtained from FILE_NAME_FIELD_PARAM applet
* parameter. The names of the output fields for the signature and the
* certification chain are obtained from the parameters CERT_CHAIN_FIELD_PARAM
* and SIGNATURE_FIELD_PARAM. The user is asket to choose a PKCS#11 implementation
* library and a PIN code for accessing the smart card.
*/
private void signSelectedFile() {
try {
// Get the file name to be signed from the form in the HTML document
// JSObject browserWindow = JSObject.getWindow(this);
// JSObject mainForm = (JSObject) browserWindow.eval("document.forms[0]");
// String fileNameFieldName = this.getParameter(FILE_NAME_FIELD_PARAM);
// JSObject fileNameField = (JSObject) mainForm.getMember(fileNameFieldName);
// String fileName = (String) fileNameField.getMember("value");

// Perform the actual file signing
String texttosign = "test";
CertificationChainAndSignatureBase64 signingResult = signFile(texttosign);
if (signingResult != null) {
System.out.println(signingResult.mCertificationChain);
System.out.println(signingResult.mSignature);
// Document signed. Fill the certificate and signature fields
// String certChainFieldName = this.getParameter(CERT_CHAIN_FIELD_PARAM);
// JSObject certChainField = (JSObject) mainForm.getMember(certChainFieldName);
// certChainField.setMember("value", signingResult.mCertificationChain);
// String signatureFieldName = this.getParameter(SIGNATURE_FIELD_PARAM);
// JSObject signatureField = (JSObject) mainForm.getMember(signatureFieldName);
// signatureField.setMember("value", signingResult.mSignature);
} else {
// User canceled signing
}
}
catch (DocumentSignException dse) {
// Document signing failed. Display error message
String errorMessage = dse.getMessage();
JOptionPane.showMessageDialog(this, errorMessage);
}
catch (SecurityException se) {
se.printStackTrace();
JOptionPane.showMessageDialog(this,
"Unable to access the local file system.\n" +
"This applet should be started with full security permissions.\n" +
"Please accept to trust this applet when the Java Plug-In ask you.");
}
/*catch (JSException jse) {
jse.printStackTrace();
JOptionPane.showMessageDialog(this,
"Unable to access some of the fields of the\n" +
"HTML form. Please check the applet parameters.");
}*/
catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "Unexpected error: " + e.getMessage());
}
}

public static boolean verifySig(byte[] data, PublicKey key, byte[] sig) throws Exception {
Signature signer = Signature.getInstance("SHA1withRSA");
signer.initVerify(key);
signer.update(data);
return (signer.verify(sig));

}


private void verifySignature(){
try {
// Get the file name to be signed from the form in the HTML document
// JSObject browserWindow = JSObject.getWindow(this);
// JSObject mainForm = (JSObject) browserWindow.eval("document.forms[0]");
// String fileNameFieldName = this.getParameter(FILE_NAME_FIELD_PARAM);
// JSObject fileNameField = (JSObject) mainForm.getMember(fileNameFieldName);
// String fileName = (String) fileNameField.getMember("value");

// Document signed. Fill the certificate and signature fields
// String certChainFieldName = this.getParameter(CERT_CHAIN_FIELD_PARAM);
// JSObject certChainField = (JSObject) mainForm.getMember(certChainFieldName);
// String certText = (String) certChainField.getMember("value");

//certChainField.setMember("value", signingResult.mCertificationChain);
// String signatureFieldName = this.getParameter(SIGNATURE_FIELD_PARAM);
// JSObject signatureField = (JSObject) mainForm.getMember(signatureFieldName);
// String signatureText = (String) signatureField.getMember("value");
//signatureField.setMember("value", signingResult.mSignature);

//PKCS11LibraryFileAndPINCodeDialog pkcs11Dialog =
// new PKCS11LibraryFileAndPINCodeDialog();
//boolean dialogConfirmed;
//try {
// dialogConfirmed = pkcs11Dialog.run();
//} finally {
// pkcs11Dialog.dispose();
//}

//if (dialogConfirmed) {

String oldButtonLabel = mVerifyButton.getLabel();
mVerifyButton.setLabel("Working...");
mVerifyButton.setEnabled(false);
try {

//String pkcs11LibraryFileName = pkcs11Dialog.getLibraryFileName();
//String pkcs11LibraryFileName = "C:\\WINDOWS\\system32\\WatchData\\Egypt Trust CSP V1.0\\WDPKCS.dll";

//String winPath = System.getenv("windir");

//String pkcs11LibraryFileName = winPath + "\\system32\\EgyptTrust\\Egypt Trust CSP V1.0\\WDPKCS.dll";
//String pinCode = pkcs11Dialog.getSmartCardPINCode();

//KeyStore userKeyStore = loadKeyStoreFromSmartCard(pkcs11LibraryFileName, pinCode);

//Enumeration aliasesEnum = userKeyStore.aliases();
//String alias = (String)aliasesEnum.nextElement();
//PublicKey publicKey = (PublicKey) userKeyStore.getKey(alias, null);
//Certificate[] certificationChain = userKeyStore.getCertificateChain(alias);
//PublicKey publicKey = certificationChain[0].getPublicKey();


Certificate cert = null;

CertificateFactory cf = CertificateFactory.getInstance(X509_CERTIFICATE_TYPE);

cert = cf.generateCertificate(new ByteArrayInputStream(Base64Utils.base64Decode("MIIEhDCCA2ygAwIBAgIQX6SWkoV/Wo5jeyTwm5qxcDANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJFRzEUMBIGA1UEChMLRWd5cHQgVHJ1c3QxLDAqBgNVBAMTI0VneXB0IFRydXN0IE1TIERvbWFpbiBMb2dvbiBUZXN0IENBMB4XDTEwMDkwODAwMDAwMFoXDTExMDkwODIzNTk1OVowgeQxFDASBgNVBAoUC0VneXB0IFRydXN0MRAwDgYDVQQLFAdNU2xvZ29uMSUwIwYDVQQLFBxOYXRpb25hbCBJRCAtIDI2NjExMDUwMTAzOTMyMSAwHgYDVQQLFBdNdWJhc2hlciBOTyAtIDI3MjEwNTE0MDE0MDIGA1UECxQrUHVycG9zZSAtIERpcmVjdCBCcm9rZXIgZm9yIFNlY3VyaXRpZXMgdGVzdDEXMBUGA1UEAxMOQXNocmFmIFNvbGltYW4xIjAgBgkqhkiG9w0BCQEWE2FzaHJhZkBtdWJhc2hlci5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+Uoiy/L5E1hOeuQdzXLQVeEJbg4iuoPSmyy1HZJJI32AfFtZCdppU5LwreYJAtdUGxFXkwNyTmT+pBe9jjs0ClUdP4fZalH5a+J9u7MwdTgGWW0XXwkJRoy2qcoQE/BZfLxUUbbcueFt/l55YUj5hzBGq+K6SeFbY09a7wGRtHnYlUKZuaOhQzf+B3u3K2uknBDLdZpl+cQRkW7/thq6HGsow3zz4LOHP5SfYJlgpbQ9Fjgq98+NZqACEehQKJrNJ1c7LCNTr687Lyc4mTy4PR5yJ88Gzow6owpez80X49R0xBLzBpugzGq+yY+miloBNe2piSsTz4JkPGxl/hUhHAgMBAAGjgcMwgcAwCQYDVR0TBAIwADAeBgNVHREEFzAVgRNhc2hyYWZAbXViYXNoZXIubmV0MFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly9tcGtpY3JsLXBpbG90LmVneXB0dHJ1c3QuY29tL0VneXB0VHJ1c3RNU2xvZ29uL0xhdGVzdENSTC5jcmwwCwYDVR0PBAQDAgWgMB0GA1UdDgQWBBTdGtuvuhng5jB41dTLUgqNwLWXbjARBglghkgBhvhCAQEEBAMCB4AwDQYJKoZIhvcNAQEFBQADggEBAC7FtUWZRguM5eLN+snpN1QIS5eC9I40zTnaOaTt3Wuks+GuzoKpFLo0zDEMJMMDoHT4A25aCWi7CPxgiaDQR9nYEfcVW69m6ijD/wHgHHDZovKtzJxXk8WXfxnQU+lMl/NoDXqoBaJySrpYOG4HVs/FblmafdUO5AR6hCJx9nvToZ07RLw8vMRblthiyOOgAUdW270NFAlVDtC5F5j0mhaFp+/Q5hgEzOqj7o/YljpXTG4rFmB3Tx2EqE8lP9Y6ZVNVOXCCVOWxFTrnVRNVx2+1s7HzoX8GV0E+AINItnW4I2EuJBCom5bz0s1+rXZwLepnfv0vudRGl052waJSP1s=")));//certification text

PublicKey publicKey = cert.getPublicKey();

//JOptionPane.showMessageDialog(this,certText);

//Collection c = CertificateFactory
// .getInstance(X509_CERTIFICATE_TYPE)
// .generateCertificate(new ByteArrayInputStream(Base64Utils.base64Decode(certText)));

//Iterator i = c.iterator();
//while (i.hasNext()) {
// cert = (Certificate)i.next();
//}

//if(cert== null)
//{
// JOptionPane.showMessageDialog(this,certText);
//}

//PublicKey publicKey = cert.getPublicKey();

//PublicKey publicKey = certs.getPublicKey();//myCert.getPublicKey();

boolean IsValid = verifySig("test".getBytes(), publicKey, Base64Utils.base64Decode(
"kx02v6soJ2tZQR3+OwSchB/5iL3Q6ziOVlw/k2+NlHpEutNuwzJUpaXCGrhwqMcS3JzVnzG7ELx9eIgsIWxqAats+bqjrWtv0MpY3GgrxbaB6REwmshi4z9MRJG5lIADGZCJSpPqTsF3Bikf57KCQL/mYjrHtXFBpEO7leA/rDjdH1Ibh7lMbq4AhtXFf1aCr7QsmVFZpmfjnCcyi/r1usgaCC1RtGreNb1V9MthXescBk7iUbwgga6V9EAU5MfdNBRgGm5j38/CFc6qlP91tuMX2UAPWOQlUIoCEJ1tq7b6Lyas6TwH/Csx/3iq6yVKkgEC7dl+dY5EW1Nd23oj5Q=="));//signature text

if (IsValid) {
// show the confirmation box.
JOptionPane.showMessageDialog(this,"Signature is Valid");
} else {
// User canceled signing
JOptionPane.showMessageDialog(this,"Signature is not Valid");
}
}
finally {
mVerifyButton.setLabel(oldButtonLabel);
mVerifyButton.setEnabled(true);
}


//boolean IsValid = verifySig(fileName.getBytes(),,)

// Perform the actual file signing
//CertificationChainAndSignatureBase64 signingResult = signFile(fileName);

}
catch (DocumentSignException dse) {
// Document signing failed. Display error message
String errorMessage = dse.getMessage();
JOptionPane.showMessageDialog(this, errorMessage);
}
catch (SecurityException se) {
se.printStackTrace();
JOptionPane.showMessageDialog(this,
"Unable to access the local file system.\n" +
"This applet should be started with full security permissions.\n" +
"Please accept to trust this applet when the Java Plug-In ask you.");
}
/* catch (JSException jse) {
jse.printStackTrace();
JOptionPane.showMessageDialog(this,
"Unable to access some of the fields of the\n" +
"HTML form. Please check the applet parameters.");
}*/
catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "Unexpected error: " + e.getMessage());
}
}

/**
* Signs given local file. The certificate and private key to be used for signing
* come from the locally attached smart card. The user is requested to provide a
* PKCS#11 implementation library and the PIN code for accessing the smart card.
* @param aFileName the name of the file to be signed.
* @return the digital signature of the given file and the certification chain of
* the certificatie used for signing the file, both Base64-encoded or null if the
* signing process is canceled by the user.
* @throws DocumentSignException when a problem arised during the singing process
* (e.g. smart card access problem, invalid certificate, invalid PIN code, etc.)
*/
private CertificationChainAndSignatureBase64 signFile(String aFileName)
throws DocumentSignException {

// Load the file for signing
byte[] documentToSign = null;
try {
documentToSign = aFileName.getBytes();
//documentToSign = readFileInByteArray(aFileName);
} catch (Exception ioex) {
String errorMessage = "There is no text to be signed.";
throw new DocumentSignException(errorMessage, ioex);
}

// Show a dialog for choosing PKCS#11 implementation library and smart card PIN
PKCS11LibraryFileAndPINCodeDialog pkcs11Dialog =
new PKCS11LibraryFileAndPINCodeDialog();
boolean dialogConfirmed;
try {
dialogConfirmed = pkcs11Dialog.run();
} finally {
pkcs11Dialog.dispose();
}

if (dialogConfirmed) {
String oldButtonLabel = mSignButton.getLabel();
mSignButton.setLabel("Working...");
mSignButton.setEnabled(false);
try {
//String pkcs11LibraryFileName = pkcs11Dialog.getLibraryFileName();
//String pkcs11LibraryFileName = "C:\\WINDOWS\\system32\\WatchData\\Egypt Trust CSP V1.0\\WDPKCS.dll";

String winPath = System.getenv("windir");

String pkcs11LibraryFileName = "C:\\Program Files\\Softlock Smart Token Admin\\SLSTSDK.dll";
String pinCode = pkcs11Dialog.getSmartCardPINCode();

// Do the actual signing of the document with the smart card
CertificationChainAndSignatureBase64 signingResult =
signDocument(documentToSign, pkcs11LibraryFileName, pinCode);
return signingResult;
} finally {
mSignButton.setLabel(oldButtonLabel);
mSignButton.setEnabled(true);
}
}
else {
return null;
}
}

private CertificationChainAndSignatureBase64 signDocument(
byte[] aDocumentToSign, String aPkcs11LibraryFileName, String aPinCode)
throws DocumentSignException {
if (aPkcs11LibraryFileName.length() == 0) {
String errorMessage = "It is mandatory to choose a PCKS#11 native " +
"implementation library for smart card (.dll or .so file)!";
throw new DocumentSignException(errorMessage);
}

// Load the keystore from the smart card using the specified PIN code
KeyStore userKeyStore = null;
try {
userKeyStore = loadKeyStoreFromSmartCard(aPkcs11LibraryFileName, aPinCode);
} catch (Exception ex) {
String errorMessage = "Can not read the keystore from the smart card.\n" +
"Possible reasons:\n" +
" - The smart card reader in not connected.\n" +
" - The smart card is not inserted.\n" +
" - The PKCS#11 implementation library is invalid.\n" +
" - The PIN for the smart card is incorrect.\n" +
"Problem details: " + ex.getMessage();
throw new DocumentSignException(errorMessage, ex);
}

// Get the private key and its certification chain from the keystore
PrivateKeyAndCertChain privateKeyAndCertChain = null;
try {
privateKeyAndCertChain =
getPrivateKeyAndCertChain(userKeyStore);
} catch (GeneralSecurityException gsex) {
String errorMessage = "Can not extract the private key and " +
"certificate from the smart card. Reason: " + gsex.getMessage();
throw new DocumentSignException(errorMessage, gsex);
}

// Check if the private key is available
PrivateKey privateKey = privateKeyAndCertChain.mPrivateKey;
if (privateKey == null) {
String errorMessage = "Can not find the private key on the smart card.";
throw new DocumentSignException(errorMessage);
}

// Check if X.509 certification chain is available
Certificate[] certChain = privateKeyAndCertChain.mCertificationChain;
if (certChain == null) {
String errorMessage = "Can not find the certificate on the smart card.";
throw new DocumentSignException(errorMessage);
}

// Create the result object
CertificationChainAndSignatureBase64 signingResult =
new CertificationChainAndSignatureBase64();

// Save X.509 certification chain in the result encoded in Base64
try {
signingResult.mCertificationChain = encodeX509CertChainToBase64(certChain);
}
catch (CertificateException cee) {
String errorMessage = "Invalid certificate on the smart card.";
throw new DocumentSignException(errorMessage);
}

// Calculate the digital signature of the file,
// encode it in Base64 and save it in the result
try {
byte[] digitalSignature = signDocument(aDocumentToSign, privateKey);
signingResult.mSignature = Base64Utils.base64Encode(digitalSignature);
} catch (GeneralSecurityException gsex) {
String errorMessage = "Text signing failed.\n" +
"Problem details: " + gsex.getMessage();
throw new DocumentSignException(errorMessage, gsex);
}

return signingResult;
}

/**
* Loads the keystore from the smart card using its PKCS#11 implementation
* library and the Sun PKCS#11 security provider. The PIN code for accessing
* the smart card is required.
*/
private KeyStore loadKeyStoreFromSmartCard(String aPKCS11LibraryFileName,
String aSmartCardPIN)
throws GeneralSecurityException, IOException {
// First configure the Sun PKCS#11 provider. It requires a stream (or file)
// containing the configuration parameters - "name" and "library".
/* String pkcs11ConfigSettings =
"name = SmartCard\n" + "library = " + aPKCS11LibraryFileName;
byte[] pkcs11ConfigBytes = pkcs11ConfigSettings.getBytes();*/
StringBuffer cardConfig=new StringBuffer();
// cardConfig.append ("slot=0 \n");
cardConfig.append ("name=SmartCard \n");

String winPath = System.getenv("windir");

String libPath = "library=C:\\Program Files\\Softlock Smart Token Admin\\SLSTSDK.dll \n";
//String libPath = "library="+ winPath + "\\system32\\WatchData\\Egypt Trust CSP V1.0\\WDPKCS.dll \n";

//cardConfig.append ("library=C:\\WINDOWS\\system32\\ngp11v211.dll \n");
//cardConfig.append("library=C:\\WINDOWS\\system32\\es1b3k.dll \n");
//cardConfig.append ("library=C:\\WINDOWS\\system32\\aetpkss1.dll \n"); //idependant
// cardConfig.append ("library=C:\\WINDOWS\\system32\\SLSTPKCS11.dll \n"); //--- softlock without finger;
// cardConfig.append ("library=C:\\WINDOWS\\system32\\WatchData\\Egypt Trust CSP V1.0\\WDPKCS.dll \n");
cardConfig.append (libPath);

// cardConfig.append ("library=C:\\Program Files\\Feitian\\ePass1000 SDK V4.2\\PKI\\Lib\\ep1pk111.dll \n");
ByteArrayInputStream confStream = new ByteArrayInputStream(cardConfig.toString().getBytes());

// Instantiate the provider dynamically with Java reflection
try {
Class sunPkcs11Class = Class.forName(SUN_PKCS11_PROVIDER_CLASS);
Constructor pkcs11Constr = sunPkcs11Class.getConstructor(java.io.InputStream.class);
Provider pkcs11Provider = (Provider) pkcs11Constr.newInstance(confStream);
Security.addProvider(pkcs11Provider);
} catch (Exception e) {
throw new KeyStoreException("Can initialize Sun PKCS#11 security " +
"provider. Reason: " + e.getCause().getMessage());
}

// Read the keystore form the smart card
char[] pin = aSmartCardPIN.toCharArray();
KeyStore keyStore = KeyStore.getInstance(PKCS11_KEYSTORE_TYPE);
keyStore.load(null, pin);
return keyStore;
}

/**
* @return private key and certification chain corresponding to it, extracted from
* given keystore. The keystore is considered to have only one entry that contains
* both certification chain and its corresponding private key. If the keystore has
* no entries, an exception is thrown.
*/
private PrivateKeyAndCertChain getPrivateKeyAndCertChain(
KeyStore aKeyStore)
throws GeneralSecurityException {
Enumeration aliasesEnum = aKeyStore.aliases();
if (aliasesEnum.hasMoreElements()) {
String alias = (String)aliasesEnum.nextElement();
Certificate[] certificationChain = aKeyStore.getCertificateChain(alias);
PrivateKey privateKey = (PrivateKey) aKeyStore.getKey(alias, null);
PrivateKeyAndCertChain result = new PrivateKeyAndCertChain();
result.mPrivateKey = privateKey;
result.mCertificationChain = certificationChain;
return result;
} else {
throw new KeyStoreException("The keystore is empty!");
}
}

/**
* @return Base64-encoded ASN.1 DER representation of given X.509 certification
* chain.
*/
private String encodeX509CertChainToBase64(Certificate[] aCertificationChain)
throws CertificateException {

Certificate cert = aCertificationChain[0];
byte[] certPathEncoded = cert.getEncoded();

//JOptionPane.showMessageDialog(this,aCertificationChain.length);

//List certList = Arrays.asList(aCertificationChain);
//CertificateFactory certFactory =
// CertificateFactory.getInstance(X509_CERTIFICATE_TYPE);

//CertPath certPath = certFactory.generateCertPath(certList);
//byte[] certPathEncoded = certPath.getEncoded(CERTIFICATION_CHAIN_ENCODING);
String base64encodedCertChain = Base64Utils.base64Encode(certPathEncoded);
return base64encodedCertChain;
}

/**
* Reads the specified file into a byte array.
*/
private byte[] readFileInByteArray(String aFileName)
throws IOException {
File file = new File(aFileName);
FileInputStream fileStream = new FileInputStream(file);
try {
int fileSize = (int) file.length();
byte[] data = new byte[fileSize];
int bytesRead = 0;
while (bytesRead < fileSize) {
bytesRead += fileStream.read(data, bytesRead, fileSize-bytesRead);
}
return data;
}
finally {
fileStream.close();
}
}

/**
* Signs given document with a given private key.
*/
private byte[] signDocument(byte[] aDocument, PrivateKey aPrivateKey)
throws GeneralSecurityException {
Signature signatureAlgorithm =
Signature.getInstance(DIGITAL_SIGNATURE_ALGORITHM_NAME);
signatureAlgorithm.initSign(aPrivateKey);
signatureAlgorithm.update(aDocument);
byte[] digitalSignature = signatureAlgorithm.sign();
return digitalSignature;
}

/**
* Data structure that holds a pair of private key and
* certification chain corresponding to this private key.
*/
static class PrivateKeyAndCertChain {
public PrivateKey mPrivateKey;
public Certificate[] mCertificationChain;
}

/**
* Data structure that holds a pair of Base64-encoded
* certification chain and digital signature.
*/
static class CertificationChainAndSignatureBase64 {
public String mCertificationChain = null;
public String mSignature = null;
}

/**
* Exception class used for document signing errors.
*/
static class DocumentSignException extends Exception {
public DocumentSignException(String aMessage) {
super(aMessage);
}

public DocumentSignException(String aMessage, Throwable aCause) {
super(aMessage, aCause);
}
}

}

 

 

 

 

 

 

 

 

     .net version         

class Program
    {
        static void Main2(string[] args)
        {
            // Creates a Cryptoki object related to the specific PKCS#11 native library
Cryptoki cryptoki = new Cryptoki("SLSTSDK.dll");

cryptoki.Initialize();

// Prints all information relating to the native library
CryptokiInfo info = cryptoki.Info;
Console.WriteLine(info.Version);
Console.WriteLine(info.ManufacturerID);
Console.WriteLine(info.LibDescription);

// Reads the set of slots containing a token
SlotList slots = cryptoki.Slots;
if(slots.Count == 0)
{
Console.WriteLine("No slot available");
return;
}

// Gets the first slot available
Slot slot = slots[0];

// Prints all information relating to the slot
SlotInfo sinfo = slot.Info;
Console.WriteLine(sinfo.Description);
Console.WriteLine(sinfo.ManufacturerID);

if(!slot.IsTokenPresent)
{
Console.WriteLine("No token inserted in the slot: " + slots[0].Info.Description);
return;
}

// Gets the first token available
Token token = slot.Token;

// Prints all information relating to the token
TokenInfo tinfo = token.Info;
Console.WriteLine(tinfo.Label);
Console.WriteLine(tinfo.ManufacturerID);
Console.WriteLine(tinfo.Model);
Console.WriteLine(tinfo.SerialNumber);
Console.WriteLine(tinfo.HardwareVersion);

// Opens a read/write serial session
Session session =
token.OpenSession(Session.CKF_SERIAL_SESSION | Session.CKF_RW_SESSION,
null,
null);

// Executes the login passing the user PIN
int nRes = session.Login(Session.CKU_USER, "12345678");
if (nRes != 0)
{
Console.WriteLine("Wrong PIN");
return;
}

Console.WriteLine("Logged in:" + session.IsLoggedIn);

// Searchs for an RSA private key object
// Sets the template with its attributes
CryptokiCollection template = new CryptokiCollection();
template.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_PRIVATE_KEY));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_KEY_TYPE, Key.CKK_RSA));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, "Ugo's new Key"));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_TOKEN, true));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_PRIVATE, true));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_MODIFIABLE, true));

// Launchs the search specifying the template just created
CryptokiCollection objects = session.Objects.Find(template, 10);

foreach (Object obj in objects)
{
Console.WriteLine(((PrivateKey)obj).Label);
}

for (int i = 0; i < objects.Count; i++)
{
Console.WriteLine(((PrivateKey)objects[i]).Label);
}

RSAPrivateKey privateKey;
RSAPublicKey publicKey;

// If the private key is not found generates the key pair
if(objects.Count == 0)
{
CryptokiCollection templatePub = new CryptokiCollection();
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_PUBLIC_KEY));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_TOKEN, true));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_PRIVATE, true));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, "Ugo's new Key"));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_ID, "1"));
templatePub.Add(new ObjectAttribute(ObjectAttribute.CKA_MODULUS_BITS, 1024));

CryptokiCollection templatePri = new CryptokiCollection();
templatePri.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_PRIVATE_KEY));
templatePri.Add(new ObjectAttribute(ObjectAttribute.CKA_TOKEN, true));
templatePri.Add(new ObjectAttribute(ObjectAttribute.CKA_PRIVATE, true));
templatePri.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, "Ugo's new Key"));
templatePri.Add(new ObjectAttribute(ObjectAttribute.CKA_ID, "1"));

//Generate the key pair
Key[] keys = session.GenerateKeyPair(Mechanism.RSA_PKCS_KEY_PAIR_GEN, templatePub, templatePri);
privateKey = (RSAPrivateKey)keys[1];
publicKey = (RSAPublicKey)keys[0];

objects = session.Objects.Find(template, 1);
Console.WriteLine(publicKey.Label);

// prepares for the signature
string helloworld = "test";
//System.Text.UTF8Encoding
byte[] text = System.Text.Encoding.UTF8.GetBytes(helloworld);

// launches the digital signature operation with a RSA_PKCS mechanism
nRes = session.SignInit(Mechanism.SHA1_RSA_PKCS, privateKey);

// computes the signature
byte[] signature = session.Sign(text);

string aa = Convert.ToBase64String(signature);
Console.WriteLine("key is : " + aa);

// launches the digital signature verification with a RSA_PKCS mechanism
nRes = session.VerifyInit(Mechanism.SHA1_RSA_PKCS, publicKey);

// verifies the signature
nRes = session.Verify(text, signature);

// results if nRes == 0 means that the verification is OK
Console.Write("Verified " + (nRes == 0));
}
else //If the private key is found gets the corresponding public key
{
privateKey = (RSAPrivateKey)objects[objects.Count - 1];
Console.WriteLine(privateKey.Label);

// search for the related public key
template = new CryptokiCollection();
template.Add(new ObjectAttribute(ObjectAttribute.CKA_CLASS, CryptokiObject.CKO_PUBLIC_KEY));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_KEY_TYPE, Key.CKK_RSA));
template.Add(new ObjectAttribute(ObjectAttribute.CKA_LABEL, "Ugo's new Key"));

// Launchs the search specifying the template just created
objects = session.Objects.Find(template, 1);
publicKey = (RSAPublicKey)objects[0];
Console.WriteLine(publicKey.Label);

// prepares for the signature
string helloworld = "test";
//System.Text.UTF8Encoding
byte[] text = System.Text.Encoding.UTF8.GetBytes(helloworld);

//X509Certificate2 dd = new X509Certificate2(

// launches the digital signature operation with a RSA_PKCS mechanism
nRes = session.SignInit(Mechanism.SHA1_RSA_PKCS, privateKey);

// computes the signature
byte[] signature = session.Sign(text);

string aa = BitConverter.ToString(signature);

Console.WriteLine("");
Console.WriteLine("key is : " + aa);

// launches the digital signature verification with a RSA_PKCS mechanism
nRes = session.VerifyInit(Mechanism.SHA1_RSA_PKCS, publicKey);

// verifies the signature
nRes = session.Verify(text, signature);

// results if nRes == 0 means that the verification is OK
Console.Write("Verified " + (nRes == 0));
Console.ReadLine();
}

// Logouts and closes the session
session.Logout();
session.Close();
cryptoki.Finalize(IntPtr.Zero);
}
}

 

Please I appreciate your help as my knowledge

 is very li

mited in this area 

5/21/2012 12:35:35 PM
Gravatar
Total Posts 300
Ugo Chirico http://www.ugochirico.com

Re: NCryptoki Result Vs Java Result

You're confusing what NCryptoki Sign function gives you and what the signDocument function in your code returns to you.

signDocument in your code generates a PKCS#7 signature (search on google for PKCS#7 if you don't know this format) while the NCryptoki Sign function generate the pure signature. If you use SHA1_RSA_PKCS the Sign function generates the signature in PKCS#1 format that must be embedded in a PKCS#7 signature.

If you need PKCS#7 signature in your code you should use NDigitSign library that does the same as your code.

You can download NDigitSign with sample codes in the download section.

 

Let me know...

5/22/2012 8:56:06 AM
Gravatar
Total Posts 5

Re: NCryptoki Result Vs Java Result

But in Java applet they have clearly used PKCS#11

private static final String DIGITAL_SIGNATURE_ALGORITHM_NAME = "SHA1withRSA";
    private static final String SUN_PKCS11_PROVIDER_CLASS = "sun.security.pkcs11.SunPKCS11";

private static final String PKCS11_KEYSTORE_TYPE = "PKCS11";

PKCS11LibraryFileAndPINCodeDialog();

 

So they are clearly using PKCS11 encryption. Thats why im so confused. Can you please help me to  sort this out.

 

Thanks,

Viraj.

5/22/2012 7:56:34 PM
Gravatar
Total Posts 300
Ugo Chirico http://www.ugochirico.com

Re: NCryptoki Result Vs Java Result

Your Java code uses a PKCS#11 provider

 Provider pkcs11Provider = (Provider) pkcs11Constr.newInstance(confStream); 

and the signature is made by a Signature object using such provider.

The resulting signature is in PKCS#7 format with an embedded PKCS#1 signature performed by SHA1_RSA_PKCS.

To understand what I said read PKCS#7 and PKCS#1 specifications.

 

NCryptoki, like any other PKCS#11 modules, don't give signatures in PKCS#7  but in PKCS#1

 

5/23/2012 7:48:02 AM
Gravatar
Total Posts 5

Re: NCryptoki Result Vs Java Result

Hi,

 

Thank you very much for your kind cooperation. I red about the topics you suggested, but i couldn understand the difference in detailed level. can NCryptoki product give me the same result as that java code i provided there?

 

Thank you verymuch,

Viraj.

5/23/2012 9:33:19 AM
Gravatar
Total Posts 300
Ugo Chirico http://www.ugochirico.com

Re: NCryptoki Result Vs Java Result

Mainly the difference is that PKCS#7 includes a signature in PKCS#1 format.

To get the same signature  as in your code, i.e. in PKCS#7 format, you should use the library NDigitSign that you can find in the download section also with some sample codes.

5/23/2012 12:10:28 PM
Gravatar
Total Posts 5

Re: NCryptoki Result Vs Java Result

Hi,

 

I already used NDigitSign product and the sample is available for sign PDF document. But it also has this method call "Sign" which requires "ICertificateSelector" instance. I provided "SimpleCertificateSelector" and tried to run the program. unfortunately it gave me an error, ERROR_CERTIFICATE_NOT_FOUND -2147483544

What could be the issue here?

5/23/2012 12:14:00 PM
Gravatar
Total Posts 300
Ugo Chirico http://www.ugochirico.com

Re: NCryptoki Result Vs Java Result

That error means that on your token there isn't any certificate to be used in the signature.