SunPKCS11 - alguém já usou ou sabe como funciona?

2 respostas
V

Olá pessoal,

preciso desenvolver uma aplicação para acessar dispositivos de segurança (token, smartcard) e vi que nesta ultima versao do Java 5 a Sun incluiu um provider que trata destes dispostivos através do padrão PKCS#11.
Já lí o JavaTM PKCS#11 Reference Guide, entendi como funciona e como configura, mas não consegui saber o que realmente é preciso pra poder acessar um hardware criptográfico (bibliotecas, .DLLs, .SOs, policy files, etc).

Em suma, alguém que já usou ou sabe algo a mais sobre o SunPKCS11 poderia me dar uma luz?

Obrigado!

2 Respostas

G

O provider SunPKCS11 precisa de uma API (DLL) que vem com o dispositivo a ser utilizado (token ou smartcard) para acessar o certificado digital. Você deve configurar o provider para utilizar esta API para conseguir ter acesso.

Estou precisando do JavaDoc da classe SunPKCS11, vc tem?

Att,
Guilherme

V

O javadoc eu não sei onde tem, mas o code-completion já me ajudou bastante!

Fiz essa classe teste ai embaixo, usando o SunPKCS11 e o BouncyCastle (CMS) para acessar um e-Token (Aladdin) e assinar dados, mas está ocorrendo um org.bouncycastle.cms.CMSException: key inappropriate for signature quando vou assinar os dados.

Alguém sabe como eu posso fazer pra obter uma chave apropriada?

public class AssinadorPKCS11 {
    
    public static final String ETOKEN_CONFIG = "config/eToken.properties";
    
    private static String _msgSolicitaPIN = "Por favor informe seu PIN (Número 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 lançada aqui !!!
            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ão existem alias disponíveis no repositório"); 
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new PKCS11Exception("Não foi possível 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ão foi possível 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;
    }
}

PS.: também estou discutindo este tópico no Fórum da SUN

Criado 3 de agosto de 2005
Ultima resposta 19 de ago. de 2005
Respostas 2
Participantes 2