SunPKCS11 - does anyone used it or *really* know how it works?

Hi guys,

I need to develop an app to access security devices (tokens, smartcards) and I know that Sun included on Tiger this SunPCKS11 provider to access those devices through PKCS#11 interface.

Well, I've read the "JavaTM PKCS#11 Reference Guide" and understood how it works and how to configure it, but I couldn't realize what is actually needed to gain access to some cryptographic hardware (libraries, .DLLs, .SOs, policy files, etc) using this provider.

In short, anyone who already used or knows something else about SunPKCS11 provider could give some light?

Thanks,

Henrique Viecili

[628 byte] By [viecilia] at [2007-10-1 20:11:39]
# 1
Does the Configuration section (2.2) of the doc help? http://java.sun.com/j2se/1.5.0/docs/guide/security/p11guide.htmlThe most important file is the native DLL from your token vendor which contains an implementation of the native PKCS#11 library that talks to your token.
charlie.laia at 2007-7-13 2:13:05 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 2

First of all, xcuse my english,

So You have to know that SunPKCS11 does not contain any cryptographic implementation, it is just a bridge between your Java application and the cryptographic token which one really do the cryptographic operation. This token is generally given with a sort of driver, a dynamic or native library .so, .dll whatever,

So you have to configure your SunPKCS11 to tell him to link with the native library which one link with the cryptographic token. If this token with his library are well designed formely to PKCS#11 standard, you would have a new Provider for your application.

just don't forget, thath SunPKCS11 is just a bridge to a library...

Hope it can help u...

by

nanass03a at 2007-7-13 2:13:05 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 3
Thank you all, but...In this case the DLL must be JNI compatible or the SunPCKS11 Provider adapts itself to make the native calls?Is there any cryptographic hardware (token or smartcard) vendor recommended or certified by Sun?
viecilia at 2007-7-13 2:13:05 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 4

I磛e coded the sample test class below using SunPKCS11 and BouncyCastle (CMS) to access the e-Token (Aladdin) and sign some data, but I got org.bouncycastle.cms.CMSException: key inappropriate for signature. when I was trying to sign data.

How can I get the appropriate key for signing?

public class AssinadorPKCS11 {

public static final String ETOKEN_CONFIG = "config/eToken.properties";

private static String _msgSolicitaPIN = "Por favor informe seu PIN (N鷐ero de Identifica玢o Pessoal)" +

" para acessar seus certificados no Token";

private static String _titSolicitaPIN = "Login - eToken";

private static String _msgSelecionaAlias = "Selecione uma identidade abaixo";

private static String _titSelecionaAlias = "Identidades";

protected Provider provider;

protected KeyStore keyStore;

protected String alias;

/** Creates a new instance of AssinadorPKCS11 */

public AssinadorPKCS11() throws PKCS11Exception {

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

provider = new sun.security.pkcs11.SunPKCS11(ETOKEN_CONFIG);

Security.addProvider(provider);

login();

}

public byte[] sign(byte[] dados) throws PKCS11Exception {

byte[] saida = new byte[0];

setAlias();

try {

Certificate cert = keyStore.getCertificate(alias);

PrivateKey key = (PrivateKey) keyStore.getKey(alias, null);

Certificate[] chain = keyStore.getCertificateChain(alias);

CertStore certStore = CertStore.getInstance("Collection",new CollectionCertStoreParameters(Arrays.asList(chain)));

CMSSignedDataGenerator sdatagen = new CMSSignedDataGenerator();

sdatagen.addSigner(key, (X509Certificate) cert, CMSSignedDataGenerator.DIGEST_SHA1);

sdatagen.addCertificatesAndCRLs(certStore);

CMSProcessable content = new CMSProcessableByteArray(dados);

CMSSignedData sdata = sdatagen.generate(content, true, "BC"); // <<< exception thrown here !!!

saida = sdata.getEncoded();

} catch (Exception e) {

e.printStackTrace();

throw new PKCS11Exception("Erro assinando dados",e);

}

return saida;

}

protected void setAlias() throws PKCS11Exception {

try {

Enumeration<String> aliases = keyStore.aliases();

String[] selection = Collections.list(aliases).toArray(new String[0]);

if (selection != null) {

if (selection.length > 1) {

JOptionPane pane = new JOptionPane();

pane.setSelectionValues(selection);

pane.setOptionType(JOptionPane.OK_OPTION);

do {

alias = pane.showInputDialog(null,_msgSelecionaAlias,_titSelecionaAlias,JOptionPane.QUESTION_MESSAGE);

} while (alias == null);

} else {

alias = selection[0];

}

} else {

throw new PKCS11Exception("N鉶 existem alias dispon韛eis no reposit髍io");

}

} catch (Exception e) {

e.printStackTrace();

throw new PKCS11Exception("N鉶 foi poss韛el obter alias",e);

}

}

private void login() throws PKCS11Exception {

char[] pin = getPIN();

try {

keyStore = KeyStore.getInstance("PKCS11");

keyStore.load(null, pin);

} catch (Exception e) {

e.printStackTrace();

throw new PKCS11Exception("N鉶 foi poss韛el logar",e);

}

}

private char[] getPIN() {

char[] saida = {' '};

// modo grafico

JOptionPane pane = new JOptionPane();

pane.setOptionType(JOptionPane.OK_OPTION);

String pin;

do {

pin = pane.showInputDialog(null,_msgSolicitaPIN,_titSolicitaPIN,JOptionPane.QUESTION_MESSAGE);

} while (pin == null);

saida = pin.toCharArray();

return saida;

}

}

viecilia at 2007-7-13 2:13:05 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 5

the DLL must simply conform to the standard PKCS#11 API. the SunPKCS11 Provider will make native calls to that standard API.

there are not "certified" tokens from Sun (at least not yet), but we have done testing against a couple of SW providers (NSS soft token and Solaris 10 soft token) as well as the Solaris hardware accelerator (SCA1000).

we have also done some hand testing against certain cards or tokens that we can get our hands on, including the ActiveCard and iButton. these tests are fairly random, however.developers have responded to us saying that they have gotten other tokens to work, but i don't have a list.

over time it may be possible for Sun to start certifying tokens, but that isn't done at the moment.

charlie.laia at 2007-7-13 2:13:05 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 6

Solved in this topic: http://forum.java.sun.com/thread.jspa?threadID=506442&start=10&tstart=0

Solution: Change the BouncyCastle ("BC") provider name by PKCS11 ("SunPKCS11-eToken") provider name!

-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

>> CMSSignedData sdata = sdatagen.generate(content, true, "SunPKCS11-opensc");

> No exception! So in your case it would be

> "SunPKCS11-eToken"

>

> Saida ?bom! :-)

Wow, that is it! worked!! Thank you very much joachimbj!

joachimbj, MUITO OBRIGADO MESMO!

Desde agosto eu estava parado nesse problema (tinha at?deixado de lado), que gra鏰s a tua perspic醕ia agora foi solucionado!!

Parab閚s e muito obrigado novamente!

ps.: Saida ?otimo :)

a-ha, u-hu... brasileiro ?foda!!! a-ha, u-hu...

viecilia at 2007-7-13 2:13:05 > top of Java-index,Security,Other Security APIs, Tools, and Issues...
# 7

Hi there,

I had also a problem using SunPKCS11 and BouncyCastle to sign an email and its attachments. The exception that occurred was:

org.bouncycastle.mail.smime.SMIMEException: key inappropriate for signature.

at org.bouncycastle.mail.smime.SMIMESignedGenerator.make(SMIMESignedGenerator.java:170)

at org.bouncycastle.mail.smime.SMIMESignedGenerator.generate(SMIMESignedGenerator.java:288)

While debugging I found out the underlying exception had the message:

java.security.InvalidKeyException: Private key must be instance of RSAPrivate(Crt)Key or have PKCS#8 encoding

After a lot of trial and error and reading, I read in an article (http://www.developer.com/java/other/article.php/10936_3587361_2):

"Some PKCS#11 native implementations require the provider to be unregistered after you've finished signing. Otherwise, an active session with the smart card can remain open and can cause all further signing attempts to fail."

So I added a single line of code to unregister my provider in between signing the attachments:

Security.removeProvider(myProvider.getName());

et voila, it worked!

Hope this might help you as it helped me, grtz

gummoa at 2007-7-13 2:13:05 > top of Java-index,Security,Other Security APIs, Tools, and Issues...