uma aplicação para comunicação com dispositivos …20... · uma aplicação para comunicação...
TRANSCRIPT
UNIVERSIDADE FEDERAL DE SANTA CATARINADEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA
BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO
Paulo Henrique de Morais
Uma aplicação para comunicação com dispositivoscriptográficos
Trabalho de Conclusão de Curso submetido à Universidade Federal de Santa Cata-
rina como parte dos requisitos para a obtenção do grau de Bacharel em Ciência da
Computação.
André Bereza JúniorOrientador
Prof. Ricardo Felipe Custódio, Dr.Co-Orientador
Florianópolis, junho de 2012
Uma aplicação para comunicação com dispositivoscriptográficos
Paulo Henrique de Morais
Este Trabalho de Conclusão de Curso foi julgado adequado para a obtenção do título de
Bacharel em Ciência da Computação e aprovada em sua forma final pelo Departamento
de Informática e Estatística da Universidade Federal de Santa Catarina.
Prof. Vitório B. Mazzola, Dr.
Coordenador do Curso
Banca Examinadora
André Bereza Júnior
Prof. Ricardo Felipe Custódio, Dr.
Jeandré Monteiro Sutil
Roberto Gallo
3
“Sorte é aquilo que acontece quando a preparaçãoencontra a oportunidade.”
Elmer Letterman
4
Dedico este trabalho à minha família pelo apoio para eu
conseguir concluir mais uma etapa da minha vida.
Agradecimentos
Primeiramente, eu quero agradecer aos meus pais pela ajuda que recebi e
que me deram condições para eu fazer a minha graduação.
Agradeço ao professor Ricardo Felipe Custódio que realiza um trabalho
incrível no LabSEC e me deu a oportunidade para desenvolver este trabalho. Não
poderia deixar de mencionar também todos os integrantes do LabSEC, no qual me
ajudaram muito nas atividades em que eu trabalhei.
Aos meus amigos que foram fundamentais para que eu tivesse força e não
desanimasse durante o curso, muito obrigado.
Sumário
Lista de Figuras 11
Lista de Siglas 13
Resumo 14
Abstract 15
1 Introdução 1
1.1 Contextualização . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Objetivos Específicos . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Justificativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.5 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.6 Limitações do Trabalho . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 Fundamentos Criptográficos 4
2.1 Criptografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.1 As características das técnicas de criptografia . . . . . . . . . 5
2.1.2 Criptoanálise . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.3 Função de Hash . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.4 Criptografia Simétrica . . . . . . . . . . . . . . . . . . . . . 8
2.1.5 Criptografia Assimétrica . . . . . . . . . . . . . . . . . . . . 10
2.2 TLS/SSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
7
2.3 Dispositivos Criptográficos . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.1 Smart Cards . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.2 Hardware Security Module . . . . . . . . . . . . . . . . . . . 15
3 PKCS #11 17
3.1 Modelo Geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2 Visão lógica de um token . . . . . . . . . . . . . . . . . . . . . . . . 20
3.3 Usuários . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.4 Aplicação e seu uso da Cryptoki . . . . . . . . . . . . . . . . . . . . 22
3.5 Sessões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.5.1 Estados de sessão somente leitura . . . . . . . . . . . . . . . 23
3.5.2 Estados de Sessão Leitura/Escrita . . . . . . . . . . . . . . . 23
3.5.3 Acessos de objetos permitidos por sessões . . . . . . . . . . . 24
3.5.4 Identificador de sessão e identificador de objeto . . . . . . . . 25
3.5.5 Capacidades de sessões . . . . . . . . . . . . . . . . . . . . . 25
3.6 Uma visão geral das funções . . . . . . . . . . . . . . . . . . . . . . 26
3.6.1 Funções de propósito geral: . . . . . . . . . . . . . . . . . . 26
3.6.2 Funções para administração de slot e token: . . . . . . . . . . 26
3.6.3 Funções para administração de sessão: . . . . . . . . . . . . . 27
3.6.4 Funções para administração de objeto: . . . . . . . . . . . . . 27
3.6.5 Funções de cifrar: . . . . . . . . . . . . . . . . . . . . . . . . 28
3.6.6 Funções de decifrar: . . . . . . . . . . . . . . . . . . . . . . 28
3.6.7 Funções de resumo da mensagem: . . . . . . . . . . . . . . . 29
3.6.8 Funções de assinatura: . . . . . . . . . . . . . . . . . . . . . 29
3.6.9 Funções para verificação de assinatura: . . . . . . . . . . . . 29
3.6.10 Funções criptográficas com duplo propósito: . . . . . . . . . 30
3.6.11 Funções para administração de chave: . . . . . . . . . . . . . 30
3.6.12 Funções para geração de números aleatórios: . . . . . . . . . 30
3.6.13 Funções para administração de função paralela: . . . . . . . . 31
3.7 Vulnerabilidades na API PKCS #11 . . . . . . . . . . . . . . . . . . 31
8
3.8 IAIK PKCS#11 Wrapper . . . . . . . . . . . . . . . . . . . . . . . . 32
3.9 O Modelo da Camada do Sistema . . . . . . . . . . . . . . . . . . . 32
3.10 A API Java Orientado a Objetos para PKCS #11 . . . . . . . . . . . . 33
3.11 A API Java para PKCS#11 . . . . . . . . . . . . . . . . . . . . . . . 34
3.12 O Módulo Nativo do Wrapper . . . . . . . . . . . . . . . . . . . . . 34
3.13 Compatibilidade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4 Interface Gráfica PKCS #11 36
4.1 Tela Principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.2 Categoria de Informações . . . . . . . . . . . . . . . . . . . . . . . . 38
4.2.1 Informações da Cryptoki: . . . . . . . . . . . . . . . . . . . 39
4.2.2 Informações do Slot: . . . . . . . . . . . . . . . . . . . . . . 39
4.2.3 Informações do Token: . . . . . . . . . . . . . . . . . . . . . 40
4.2.4 Informações do Mecanismo: . . . . . . . . . . . . . . . . . . 41
4.3 Categoria de Administração do Token . . . . . . . . . . . . . . . . . 42
4.3.1 Inicialização do Token: . . . . . . . . . . . . . . . . . . . . . 42
4.3.2 Alterar PIN: . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.3.3 Inicializar o PIN do usuário normal . . . . . . . . . . . . . . 45
4.4 Categoria Administração de Chaves . . . . . . . . . . . . . . . . . . 46
4.4.1 Gerar chave secreta . . . . . . . . . . . . . . . . . . . . . . . 47
4.4.2 Gerar par de chaves pública/privada . . . . . . . . . . . . . . 48
4.5 Categoria Administração de Sessões . . . . . . . . . . . . . . . . . . 49
4.5.1 Informações da sessão . . . . . . . . . . . . . . . . . . . . . 51
4.5.2 Abrir sessão RO . . . . . . . . . . . . . . . . . . . . . . . . 51
4.5.3 Abrir sessão RW . . . . . . . . . . . . . . . . . . . . . . . . 51
4.5.4 Fechar sessão . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.5.5 Fechar todas as sessões . . . . . . . . . . . . . . . . . . . . . 52
4.5.6 Desconectar usuário . . . . . . . . . . . . . . . . . . . . . . 52
4.5.7 Conectar usuário . . . . . . . . . . . . . . . . . . . . . . . . 52
4.6 Categoria Administração de Objetos . . . . . . . . . . . . . . . . . . 53
9
4.6.1 Mostrar objetos do token . . . . . . . . . . . . . . . . . . . . 53
4.6.2 Mostrar objetos de sessão . . . . . . . . . . . . . . . . . . . 54
4.6.3 Mostrar informações do objeto . . . . . . . . . . . . . . . . . 54
4.6.4 Deletar objetos . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.6.5 Deletar todos os objetos . . . . . . . . . . . . . . . . . . . . 54
4.7 Categoria função de resumo . . . . . . . . . . . . . . . . . . . . . . 55
4.7.1 Função de hash . . . . . . . . . . . . . . . . . . . . . . . . . 56
4.8 Categoria importar certificado . . . . . . . . . . . . . . . . . . . . . 57
4.8.1 Importar certificado . . . . . . . . . . . . . . . . . . . . . . . 57
4.9 Categoria operações criptográficas . . . . . . . . . . . . . . . . . . . 58
4.9.1 Assinar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.9.2 Verificar assinatura . . . . . . . . . . . . . . . . . . . . . . . 61
4.9.3 Cifrar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.9.4 Decifrar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.10 Categoria alterar atributo . . . . . . . . . . . . . . . . . . . . . . . . 63
4.10.1 Alterar atributo . . . . . . . . . . . . . . . . . . . . . . . . . 63
5 Biblioteca LibCryptoDev 65
5.1 ListUsb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.2 CryptoDev . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
5.3 ModuleHandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.4 Token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.5 ReadOnlySession . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.6 ReadWriteSession . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
6 Análises de Resultados 75
6.1 Testes executados . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
6.1.1 GUICryptokiEasyAccess . . . . . . . . . . . . . . . . . . . . 76
6.1.2 LibCryptoDev . . . . . . . . . . . . . . . . . . . . . . . . . 77
10
7 Considerações Finais 78
7.1 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Referências 81
A Artigo 83
Lista de Figuras
2.1 Modelo simplificado da criptografia simétrica . . . . . . . . . . . . . 9
2.2 Criptografia Assimétrica . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3 Smart Card da Pronova [PRO 12] . . . . . . . . . . . . . . . . . . . . 14
2.4 O modelo ASI-HSM AHX2, fabricado no Brasil . . . . . . . . . . . . 16
3.1 Modelo Geral da Cryptoki [PKC 11] . . . . . . . . . . . . . . . . . . 19
3.2 Hierarquia de Objetos [PKC 11] . . . . . . . . . . . . . . . . . . . . 20
3.3 Estados de sessão somente leitura [PKC 11] . . . . . . . . . . . . . . 23
3.4 Estados de sessão Leitura/Escrita [PKC 11] . . . . . . . . . . . . . . 24
3.5 Tabela: Acesso para diferentes tipos de objetos por diferentes tipos de
sessões [PKC 11] . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.6 Modelo das camadas . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.1 Carregar módulo PKCS #11 . . . . . . . . . . . . . . . . . . . . . . 36
4.2 Selecionar Token . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.3 Tela Principal da GUICryptokiEasyAccess . . . . . . . . . . . . . . . 38
4.4 Informações gerais da Cryptoki . . . . . . . . . . . . . . . . . . . . . 39
4.5 Informações do Slot que contém o token acessado . . . . . . . . . . . 40
4.6 Informações do token acessado . . . . . . . . . . . . . . . . . . . . . 41
4.7 Informações de flags do Token . . . . . . . . . . . . . . . . . . . . . 42
4.8 Lista de algoritmos que podem ser usados no Token . . . . . . . . . . 43
4.9 Informações do algoritmo CKM_RSA_PKCS_KEY_PAIR_GEN . . . 44
4.10 Administração do Token . . . . . . . . . . . . . . . . . . . . . . . . 45
12
4.11 Inicialização do Token . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.12 Alterar PIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
4.13 Inicializar PIN do usuário normal . . . . . . . . . . . . . . . . . . . . 46
4.14 Administração de Chaves . . . . . . . . . . . . . . . . . . . . . . . . 47
4.15 Chave Secreta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.16 Par de chaves pública/privada . . . . . . . . . . . . . . . . . . . . . . 49
4.17 Administração de Sessões . . . . . . . . . . . . . . . . . . . . . . . . 50
4.18 Informações da Sessão . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.19 Administração de objetos . . . . . . . . . . . . . . . . . . . . . . . . 53
4.20 Informações de uma chave pública . . . . . . . . . . . . . . . . . . . 55
4.21 Informações de uma chave privada . . . . . . . . . . . . . . . . . . . 56
4.22 Informações de um certificado . . . . . . . . . . . . . . . . . . . . . 57
4.23 Informações de uma chave secreta . . . . . . . . . . . . . . . . . . . 58
4.24 Função de resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.25 Valor de hash para o arquivo engine_openhsmd.so . . . . . . . . . . . 59
4.26 Importar certificado . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.27 Operações criptográficas . . . . . . . . . . . . . . . . . . . . . . . . 60
4.28 Assinar um documento digital . . . . . . . . . . . . . . . . . . . . . 61
4.29 Verificar assinatura digital . . . . . . . . . . . . . . . . . . . . . . . 61
4.30 Cifrar um documento digital . . . . . . . . . . . . . . . . . . . . . . 62
4.31 Decifrar um documento digital . . . . . . . . . . . . . . . . . . . . . 63
4.32 Categoria definir atributo . . . . . . . . . . . . . . . . . . . . . . . . 64
5.1 Diagrama de classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Lista de Siglas
PKCS Public-Key Cryptography StandardsRSA Rivest-Shamir-AdlemanSSL Secure Socket LayerTLS Transport Layer SecurityAPI Application Programming InterfaceCryptoki Cryptographic Token InterfaceDES Data Encryption StandardHSM Hardware Security ModuleANSI American National Standards InstitutePKIX Public-Key Infrastructure X.509S/MIME Secure/Multipurpose Internet Mail ExtensionsUSB Universal Serial BusIAIK The Institute for Applied Information Processing and Communi-
cationsTCP Transmission Control ProtocolHTTP Hypertext Transfer ProtocolMAC Message Authentication CodePIN Personal Identification NumberSO Security OfficerJNI Java Native InterfaceDLL Dynamic-Link library
Resumo
A comunicação tanto entre aplicações quanto entre uma aplicação e um
dispositivo criptográfico é realizada através de uma API. Uma API desenvolvida como
uma interface entre aplicações e dispositivos criptográficos é a API PKCS #11.
É necessário existir uma aplicação que acesse qualquer dispositivo crip-
tográfico utilizando padrões propostos.
Este trabalho tem o intuito de utilizar a API PKCS #11 para comunicação
com os dispositivos criptográficos que implementam as funções dessa API. A aplicação
e a biblioteca poderão ser utilizadas com esse padrão para garantir a interoperabilidade
entre aplicações e dispositivos criptográficos.
Abstract
The communication as between applications as between an application and
a cryptographic device is performed through an API. An API developed as an interface
between applications and cryptographic devices is the PKCS #11 API.
It is necessary to have an application that accesses any cryptographic de-
vice using the proposed standards.
The goal of this final paper is to use the PKCS #11 API to communicate
with devices that implement cryptographic functions of this API. The application and
the library can be used with this standard to ensure interoperability between applica-
tions and cryptographic devices.
Capítulo 1
Introdução
Dispositivos criptográficos são utilizados em locais como: uma infraestru-
tura de chaves públicas, setor bancário. A utilização dos dispositivos nos diversos
setores deve ser padronizada para garantir a interoperabilidade das aplicações que são
desenvolvidas para se comunicar com esses dispositivos. Os dispositivos são impor-
tantes, pois armazenam material sensível e valioso para as instituições que o utilizam.
1.1 Contextualização
Fabricantes de dispositivos criptográficos criam dispositivos com suporte
a padrões em especial o PKCS #11 para acessar as funções criptográficas e também
várias aplicações são implementadas para acessá-los.
Para manter a interoperabilidade entre aplicações e dispositivos criptográ-
ficos é necessário que eles sigam a documentação do padrão utilizado. Desse modo,
podem ser desenvolvidas diversas aplicações e dispositivos criptográficos com imple-
mentações diferentes e com a mesma interface de utilização de funções, permitindo o
acesso da aplicação para qualquer dispositivo criptográfico.
2
1.2 Objetivo
Este trabalho tem como objetivo implementar uma aplicação e uma bib-
lioteca para utilizar funções do padrão PKCS #11. A aplicação e a biblioteca devem
ser compatíveis com qualquer dispositivo criptográfico que implementa as funções da
API PKCS #11.
1.3 Objetivos Específicos
Os objetivos específicos desse trabalho são disponibilizar:
• Uma aplicação open source que pode ser utilizada para acessar e executar funções
de um dispositivo criptográfico que implementa as funções da API PKCS #11;
• Uma biblioteca que permitirá o desenvolvimento de aplicações que façam uso de
dispositivos criptográficos, abstraindo os detalhes referentes à API PKCS #11.
1.4 Justificativa
O padrão PKCS #11 está cada vez sendo mais utilizado nos dispositivos
criptográficos, porém as aplicações desenvolvidas para se comunicarem com esses dis-
positivos disponibilizam um número pequeno das funções disponíveis dessa API.
A aplicação PKCS #11 é uma alternativa para que os usuários tenham a
possibilidade de acessar os dispositivos criptográficos com uma aplicação que ofereça
uma grande parte das funções definida na Cryptoki. Além disso, a aplicação pode ser
usada para testar e diagnosticar os dispositivos criptográficos e ser capaz de operar com
diferentes módulos PKCS #11.
Faltam aplicações que ofereçam estes suportes genéricos. A aplicação
PKCS #11 também pode ser usada como uma ferramenta para encontrar limitações,
problemas na implementação do padrão PKCS #11 dos dispositivos criptográficos
acessados.
3
A biblioteca permite que novas aplicações PKCS #11 sejam desenvolvidas.
Isso permite que o usuário tenha uma maior flexibilidade para escolher uma aplicação
e dessa forma ele não ficará preso a uma determinada aplicação. Ademais, ela evita
que os desenvolvedores tenham que se especializar em uma API de baixo nível, con-
centrando o conhecimento em nível de operações criptográficas.
1.5 Metodologia
É necessário verificar a existência de uma aplicação genérica open source
para acesso aos dispositivos criptográficos, por esse motivo foi feita uma pesquisa so-
bre as aplicações existentes que acessam dispositivos criptográficos utilizando o padrão
PKCS #11.
Foram analisadas bibliotecas customizadas que permitem o acesso das
funções PKCS #11 para serem usadas na aplicação a ser desenvolvida.
Para implementação da aplicação e biblioteca foi utilizada a linguagem de
programação java, devido a sua portabilidade.
Os dispositivos criptográficos utilizados como testes foram: smart cards, o
módulo PKCS #11 de um hardware criptográfico específico foi obtido por meio de seu
fabricante.
1.6 Limitações do Trabalho
Uma das limitações do trabalho está em não existir uma implementação
genérica de todas as funções PKCS #11. A aplicação desenvolvida utiliza o módulo
(implementação da API PKCS #11) específico do fabricante do dispositivo criptográ-
fico e somente pode executar as funções suportadas de cada implementação.
Os testes das funções PKCS #11 dependem dos módulos disponibilizados
pelos fabricantes. Se o fabricante não implementar algumas funções e/ou mecanismos
definido no padrão, estas funções não estarão disponíveis.
Capítulo 2
Fundamentos Criptográficos
A criptologia estuda temas que estão ligados à diversas áreas do conheci-
mento, dentro dos estudos que envolvem os conhecimentos computacionais e matemáti-
cos podemos encontrar assuntos que tratam sobre técnicas computacionais como ex-
emplos: garantir sigilo e/ou a autenticidade da informação. Os dois ramos princi-
pais da criptologia são a criptografia, que é o estudo do projeto das técnicas computa-
cionais relacionados a criptografia; e a criptoanálise, que trata das formas de reverter
essas técnicas, recuperar informações ou forjar informações que serão aceitas como
autênticas.[STA 08]
Desde os tempos remotos o homem desenvolve e utiliza técnicas que possi-
bilitam a troca de mensagens secretas. Essas mensagens podem ser facilmente interpre-
tadas e lidas pelo receptor autorizado, mas dificilmente por aqueles que a interceptam
sem autorização do remetente ou do destinatário.
Seja pelo seu teor passional, diplomático, comercial ou bélico, muitas men-
sagens precisavam ser mantidas em segredo. Em tempos de guerra, a troca de men-
sagens secretas é fundamental para o sucesso de uma empreitada. A Criptografia nem
sempre esteve ligada a tragédias. Nossas compras pela internet e as comunicações que
efetuamos com nossa conta bancária são protegidas pela Criptografia. [FAL 11]
5
2.1 Criptografia
A Criptografia é a ciência que estuda as formas de se escrever uma men-
sagem em código. Trata-se de um conjunto de técnicas que permitem tornar incom-
preensível uma mensagem originalmente escrita com clareza, de forma a permitir que
apenas o destinatário a decifre e compreenda. [And 05]
Outra definição para criptografia encontrada na literatura é: “A Criptografia
(do grego, kryptos = secreto) é a ciência - nos primórdios da humanidade era uma arte
- que se dedica ao desenvolvimento dos cifrários nomes que recebem as técnicas des-
tinadas a tornar secreta uma mensagem. Antes de terem sido criptografadas, as men-
sagens são denominadas de mensagem, texto claro, texto original. Aquelas tornadas
secretas pela criptografia são chamadas textos cifrados ou criptografados e ainda, men-
sagens cifradas ou criptografadas”. [FAL 11]
2.1.1 As características das técnicas de criptografia
As técnicas de criptografia utilizados pelos sistemas criptográficos são car-
acterizados em três dimensões independentes:
O tipo das operações usadas para transformar texto claro em texto cifrado.
Todos os algoritmos de criptografia são baseados em dois princípios gerais: substitu-
ição, em que cada elemento no texto claro (bit, letra, grupo de bits ou letras) é mapeado
em outro elemento, e transposição, em que os elementos no texto claro são reorgani-
zados. O requisito fundamental é que nenhuma informação seja perdida (ou seja, que
todas as operações sejam reversíveis). [STA 08]
O número de chaves usadas. Se tanto o emissor quanto o receptor uti-
lizarem a mesma chave, o sistema é considerado como criptografia simétrica, de chave
única, de chave secreta ou convencional. Se o emissor e o receptor usarem chaves
diferentes, o sistema é considerado de criptografia assimétrica, de duas chaves ou de
chave pública. [STA 08]
O modo como o texto claro é processado. Uma cifra de bloco processa a
6
entrada de um bloco de elementos de cada vez, produzindo um bloco de saída para cada
bloco de entrada. Uma cifra em fluxo processa os elementos da entrada continuamente,
produzindo a saída de um elemento de cada vez, enquanto prossegue. [STA 08]
2.1.2 Criptoanálise
Normalmente, o objetivo de atacar um sistema que utiliza um algoritmo
de criptografia é recuperar a chave em uso, em vez de simplesmente recuperar o texto
claro de um único texto cifrado. Existem duas técnicas gerais para o ataque a um
esquema de criptografia convencional:
• Criptoanálise: Os ataques criptoanalíticos contam com a natureza do algoritmo
e talvez mais algum conhecimento das características gerais do texto claro, ou
ainda alguns pares de amostra de texto claro e texto cifrado. Esse tipo de ataque
explora as características do algoritmo para tentar deduzir um texto claro especí-
fico ou deduzir a chave utilizada. [STA 08]
• Ataque por força bruta: O atacante experimenta cada chave possível em um
trecho do texto cifrado, até obter uma tradução inteligível para o texto claro. Na
média, metade de todas as chaves possíveis precisam ser experimentadas para se
obter sucesso.
As tabelas 2.1 e 2.2 mostram o tempo envolvido para diversos espaços de chaves.
Os resultados são mostrados para quatro tamanho de chave binária. O tamanho
de chave de 56 bits é usado com o algoritmo DES (Data Encryption Standard)
que como podemos ver não pode mais ser considerado computacionalmente se-
guro, e o tamanhos de chave de 168 bits é usado para triple DES. O tamanho de
chave mínimo especificado para AES (Advanced Encryption Standard) é de 128
bits.
Os resultados também são mostrados para os chamados códigos de substituição
que utilizam uma chave de 26 caracteres, em que todas as permutações possíveis
7
dos 26 caracteres servem como chaves. Para cada tamanho de chave, os resulta-
dos são mostrados considerando que é necessário 1 µs para realizar uma única
decifragem que é uma ordem de grandeza razoável para as máquinas de hoje. A
última coluna da tabela 2.2 considera os resultados para um sistema que pode
processar 1 milhão de chaves por microssegundo. [STA 08]
Tamanho da chave (bits) Número de chaves alternativas Tempo necessário para 1
decifragem/µs
32 232 = 4, 3X109 231µs = 35, 8 minutos
56 256 = 7, 2X1016 255µs = 1142 anos
128 2128 = 3, 4X1038 2127µs = 5, 4X1024 anos
168 2168 = 3, 7X1050 2167µs = 5, 9X1036 anos
26 caracteres (permutação) 26! = 4X1026 2X1026µs = 6, 4X1012 anos
Tabela 2.1: Tempo médio exigido para busca completa da chave fazendo 1 decifragem/µs
Tamanho da chave (bits) Número de chaves alternativas Tempo necessário para 106
decrifragem/µs
32 232 = 4, 3X109 2, 15 milissegundos
56 256 = 7, 2X1016 10, 01 horas
128 2128 = 3, 4X1038 5, 4X1018 anos
168 2168 = 3, 7X1050 5, 9X1030 anos
26 caracteres (permutação) 26! = 4X1026 6, 4X106 anos
Tabela 2.2: Tempo médio exigido para busca completa da chave fazendo 106
decrifragem/µs
Se qualquer tipo de ataque tiver sucesso na dedução da chave, o efeito
será catastrófico: todas as mensagens futuras e passadas, codificadas com essa chave,
estarão comprometidas. [STA 08]
2.1.3 Função de Hash
A finalidade de uma função de hash é produzir uma “impressão digital” de
um arquivo, mensagem ou outro bloco de dados. [STA 08]
Uma função de hash aceita uma mensagem de comprimento variável M
como entrada e produz uma saída de comprimento fixo, conhecida como código de
8
hash H(M). Um código de hash não usa uma chave, sendo uma função apenas da men-
sagem de entrada. O código de hash também é conhecido como síntese de mensagem
ou valor de hash. O código de hash é uma função de todos os bits da mensagem e
oferece uma capacidade de detecção de erro: uma mudança em qualquer bit ou bits na
mensagem resulta em uma mudança no código de hash. [STA 08]
Para uma função de hash H ser segura (isto é, cada mensagem o valor de
hash correspondente será único e mensagens distintas nunca terão o valor de resumo
igual), deve ter as seguintes propriedades:
1. Para qualquer valor h dado, é computacionalmente inviável encontrar x tal H(x)
= h. Isso às vezes é conhecido na literatura como resistência à primeira inversão
ou propriedade unidirecional. [STA 08]
2. Para qualquer bloco dado x, é computacionalmente inviável encontrar y diferente
de x tal que H(y) = H(x). Isso às vezes é conhecido como resistência à segunda
inversão ou resistência fraca a colisões. [STA 08]
3. É computacionalmente inviável encontrar qualquer par (x,y) tal que H(x) = H(y).
Isso às vezes é conhecido como resistência a colisões ou resistência forte a col-
isões. [STA 08]
Todas as funções de hash operam usando os seguintes princípios gerais. A
entrada (mensagem, arquivo, etc) é vista como uma sequência de blocos de n bits. A
entrada é processada um bloco de cada vez, em um padrão iterativo para produzir uma
função de hash de n bits. [STA 08]
2.1.4 Criptografia Simétrica
A criptografia simétrica é uma forma de criptossistema em que a cifragem
e a decifragem são realizadas usando a mesma chave. Ela também é conhecida como
criptografia convencional. [STA 08]
A criptografia simétrica transforma a mensagem ou dados originais, con-
hecida como texto claro em texto cifrado (Uma mensagem embaralhada: um fluxo de
9
dados aparentemente aleatório e, nesse formato, é ininteligível), usando uma chave
secreta e um algoritmo de cifragem.
Usando a mesma chave e um algoritmo de decifragem, o texto claro é
recuperado a partir do texto cifrado, conforme é ilustrado na figura 2.1. A chave é um
valor independente do texto claro e do algoritmo. O algoritmo produzirá uma saída
diferente, dependendo da chave específica sendo usada no momento. As substituições
e transformações exatas realizada pelo algoritmo dependem da chave. [STA 08]
Figura 2.1: Modelo simplificado da criptografia simétrica
Para uso seguro da criptografia convencional precisamos de um algoritmo
forte. No mínimo, um oponente que conheça o algoritmo e tenha acesso a um ou
mais textos cifrados seja incapaz de decifrar o texto cifrado ou descobrir a chave. Esse
requisito normalmente é indicado em uma forma mais forte: o oponente deverá ser
incapaz de decifrar o texto cifrado ou descobrir a chave mesmo que possua diversos
textos cifrados juntamentamente com o texto claro que produziu cada texto cifrado.
Outro requisito necessário é o emissor e receptor precisam ter cópias da
chave secreta de uma forma segura e precisam manter a chave protegida. Se alguém
puder descobrir a chave e souber o algoritmo, toda a comunicação usando essa chave
poderá ser lida. [STA 08]
10
2.1.5 Criptografia Assimétrica
A criptografia assimétrica é uma forma de criptossistema em que a cifragem
e a decifragem são realizadas usando diferentes chaves: uma chave pública e uma
chave privada. Ela também é conhecida como criptografia de chave pública. [STA 08]
O conceito de criptografia de chave pública evoluiu de uma tentativa de
atacar dois problemas mais difíceis associados à criptografia simétrica: o primeiro
problema é o da distribuição de chaves e o segundo é o das assinaturas digitais que
possibilitaram que a criptografia tornasse comum, não apenas nas situações militares,
mas para fins comerciais e particulares, e que as mensagens e documentos eletrônicos
tivessem um equivalente das assinaturas usadas nos documentos em papel. [STA 08]
Os algoritmos assimétricos contam com uma chave para cifragem e uma
chave diferente, porém relacionada, para a decifragem. Esses algoritmos têm a seguinte
característica importante: É computacionalmente inviável determinar a chave privada
dado apenas o conhecimento do algoritmo de cifragem e da chave pública. Além disso,
alguns algoritmos, como o RSA, também exibem a seguinte característica: Qualquer
uma das chaves relacionadas pode ser usada para cifragem, com a outra usada para a
decifragem. [STA 08]
A chave pública pode ser publicada para que todos tenham acesso a ela,
porém a chave privada de um usuário nunca deve der distribuída. Desde que a chave
privada de um usuário permaneça protegida e secreta, a comunicação que chega está
protegida. [STA 08]
A criptografia assimétrica pode ser usada para confidencialidade e auten-
ticação (assinatura digital), como é mostrado na figura 2.2. Uma assinatura digital
pode ser formada cifrando-se a mensagem inteira com a chave privada do emissor
ou cifrando-se um código de hash da mensagem com a chave privada do emissor. A
confidencialidade pode ser obtida pela cifragem adicional da mensagem inteira mais a
assinatura com a chave pública do receptor. [STA 08]
O criptossistema de chave pública mais utilizado é o RSA. A dificuldade
de atacar o RSA está na dificuldade de encontrar os fatores primos de um número
11
Figura 2.2: Criptografia Assimétrica
composto. [STA 08]
2.2 TLS/SSL
O TLS/SSL (Transport Layer Security e Secure Socket Layer) é projetado
para utilizar TCP (Transmission Control Protocol) para oferecer um serviço seguro
confiável de ponta a ponta. Ele não é um protocolo isolado, mas duas camadas de
protocolo. [STA 08]
O Protocolo de Registro (Record Protocol) TLS/SSL oferece serviços bási-
cos de segurança para vários protocolos de camada superior. Em particular, o Hyper-
text Transfer Protocol (HTTP), que oferece o serviço de transferência para interação
cliente/servidor Web, pode operar em cima do SSL. Três protocolos de camada supe-
rior são definidos como parte do TLS/SSL: o Protocolo de Estabelecimento de Sessão
(Handshake Protocol), o Protocolo de Mudança de Especificação de Cifra (Change
12
Cipher Spec Protocol) e o Protocolo de Alerta (Alert Protocol). Esses protocolos es-
pecíficos são usados no gerenciamento de trocas TLS/SSL. [STA 08]
O Protocolo de Registro TLS/SSL oferece dois serviços para conexões:
• Confidencialidade: O Protocolo de Estabelecimento de Sessão define uma chave
secreta compartilhada usada para criptografia convencional dos dados a serem
transportados pelo TLS/SSL. [STA 08]
• Integridade da mensagem: o Protocolo de Estabelecimento de Sessão também
define uma chave secreta compartilhada usada para formar um código de auten-
ticação de mensagem (MAC). [STA 08]
O Protocolo de Mudança de Especificação de Cifra é composto por uma
única mensagem que consiste em um único byte com o valor 1. A única finalidade
dessa mensagem é fazer com que o estado pendente seja copiado para o estado atual,
o que atualiza o conjunto de cifras a ser usado nessa conexão. [STA 08]
O Protocolo de Alerta é usado para transmitir alertas relacionados ao TLS/SSL
para as partes envolvidas. Assim como outras aplicações que usam TLS/SSL, as men-
sagens de alerta são compactadas e criptografadas, conforme especificado pelo estado
atual. [STA 08]
O Protocolo de Estabelecimento de Sessão permite que o servidor e o
cliente autentiquem um ao outro e negociem um algoritmo de criptografia e de MAC
e chaves criptográficas a serem usadas para proteger dados enviados em um registro
TLS/SSL. O Protocolo de Estabelecimento de Sessão é usado antes que quaisquer da-
dos de aplicação sejam transmitidos. [STA 08]
2.3 Dispositivos Criptográficos
Dispositivos criptográficos são dispositivos que armazenam informações
(chaves, dados e certificados) e executam funções criptográficas. Podem ser implemen-
tados como smart card, smart disk, PCMCIA card, HSM, USB tokens, ou utilizando
outra tecnologia incluindo somente software. [PKC 11]
13
Chaves criptográficas devem ser protegidas da exposição. Em aplicações
do mundo real, frequentemente elas são guardadas por dispositivos criptográficos que
utilizam sofisticadas medidas de segurança em hardware. [CAC 09]
Dispositivos criptográficos como hardware security module (HSM) são
uma parte importante da segurança de muitas infra-estruturas que usam criptografia.
Eles protegem chaves criptográficas em ambientes hostis usando medidas de proteção
contra interferência física.
Dispositivos criptográficos armazenam chaves e usam-as para executar funções
criptográficas, mas as chaves normalmente nunca deixam o perímetro de segurança es-
tabelecido pelo hardware criptográfico.
Estes dispositivos são usados porque eles podem ser controlados melhor
do que os usuários que executam operações sobre eles.
Dispositivos criptográficos existem em muitos ambientes atualmente, var-
iando de smart cards a Trusted Platform Module [GRO 12] (TPM - Módulo de plataforma
confiável em português) encontrado em muitos computadores pessoais. [CAC 09] Para
alta segurança HSMs são usados pelo setor financeiro como o cryptoprocessador 4764
da IBM. [IBM 12]
Um token criptográfico serve como um dispositivo auxiliar para uma apli-
cação rodando sobre um computador servidor. Ele executa várias funções criptográfi-
cas, tais como geração de chave, derivação de chave, cifragem, decifragem, assinatura,
verificação de assinatura e assim por diante.
Tokens também asseguram uma política de segurança sobre as chaves e
outros objetos criptográficos armazenados. Quando uma aplicação chama uma função
do token, a operação pode acessar entradas fornecidas pela aplicação, e também obje-
tos armanezados no dispositivo.
A aplicação nem sempre recebe todos os resultados da operação, como por
exemplo, quando uma chave é gerada e armazenada somente no dispositivo.
A política de segurança da interface do token define quais funções são
permitidas para quem. Tokens geralmente tem pelo menos dois níveis de segurança,
14
um para a aplicação, na qual tem privilégios restritos, e outra para o administrador que
pode acessar todas as chaves no token. [CAC 09]
2.3.1 Smart Cards
Um smart card (traduzido em português como cartão inteligente) é um
cartão plástico, do tamanho e forma de um cartão de crédito, com um chip de computa-
dor embutido, conforme mostra a figura 2.3. Uma antiga ideia, as primeiras patentes
foram registradas 20 anos atrás, mas limitações práticas fizeram os viáveis apenas
cinco ou mais anos atrás. Desde então eles têm sidos fabricados, principalmente na
Europa. Muitos países usam cartões inteligentes para pagar telefones. [SCH 96]
Figura 2.3: Smart Card da Pronova [PRO 12]
Um cartão inteligente contém um pequeno computador (geralmente um
micro-processador de 8-bit), RAM (aproximadamente um quarto de kilobyte), ROM
(aproximadamente 6 ou 8 kilobytes) e EPROM ou EEPROM (alguns kilobytes). Ger-
ação futura de smart cards, sem dúvida, terão mais capacidade, mas algumas limitações
físicas sobre os cartões inteligentes fizeram a expansão difícil. O cartão tem seu próprio
sistema operacional, programas, e dados. (O que não tem é energia, que vem quando o
cartão é conectado no leitor). E ele é seguro. Em um mundo onde você não pode con-
fiar no computador ou telefefone ou qualquer outra coisa de outra pessoa, você ainda
pode confiar em um cartão que você mantém na sua carteira. [SCH 96]
Smart cards podem ter diferentes protocolos criptográficos e algoritmos
programados para eles. Eles podem ser configurados como um porta-moedas eletrônico,
e serem capazes de gastar e receber dinheiro digital. Eles podem ser capazes de exe-
15
cutar protocolos de autenticação, ter suas próprias chaves criptográficas e assinar doc-
umentos, ou desbloquear aplicativos em um computador. [SCH 96]
Alguns cartões inteligentes são considerados invioláveis e muitas vezes por
esse motivo protegem a instituição que emite o cartão. Um banco não quer que uma
pessoa seja capaz de interferir e alterar seu cartão para conseguir mais dinheiro para si
própria. [SCH 96]
2.3.2 Hardware Security Module
Hardware Security Modules (traduzido como Módulos de Segurança Crip-
tográfico) são aplicados em soluções onde o controle de ciclo de vida de suas chaves
criptográficas é fundamental para seu funcionamento, como exemplo podemos citar
o ambiente de uma autoridade certificadora raiz, na qual utiliza o HSM para gestão
da sua chave privada. Por meio destes módulos chaves criptográficas são criadas, ar-
mazenadas, utilizadas e apagadas internamente, sem nunca ser vísivel ao mundo ex-
terno. [dS 08]
Os HSMs possuem mais capacidade de processamento que os smart cards,
servindo na sua maioria como aceleradores criptográficos, sendo capazes de gerenciar
o ciclo de várias chaves ao mesmo tempo. [dS 08]
Algumas aplicações, como servidores seguros de páginas Web, exigem
grande capacidade de processamento criptográfico, que pode ser alcançado com o em-
prego de um HSM que atua como um co-processador para operações criptográficas,
liberando unidade de processamento dos servidores para outras finalidades. [dS 08]
O Brasil é um dos países que domina a tecnologia de fabricação de HSM, o
ASI (Advanced Security Initiative)-HSM foi projetado e desenvolvido pelo GT ICPEDU
II (Grupo de Trabalho de Infra-estrutura de Chaves Públicas para Pesquisa e Ensino)
da Rede Nacional de Ensino e Pesquisa (RNP) [dEeP 12] juntamente com o LabSEC
e Kryptus [eSdI 12]. A segurança das chaves é garantida por proteções físicas e lóg-
icas no ASI-HSM. As chaves privadas desse hardware criptográfico são responsáveis
pela assinatura de certificados digitais de autoridades certificadoras, como exemplo
16
a Infra-estrutura de Chaves Públicas Brasileira (ICP-Brasil), autoridades de registro,
servidores web e qualquer outra aplicação que necessite guardar as chaves de forma
rígida. [dSeC 12] O ASI-HSM AHX2 é ilustrado em 2.4.
Figura 2.4: O modelo ASI-HSM AHX2, fabricado no Brasil
Capítulo 3
PKCS #11
O PKCS #11 é um dos padrões pertencentes à família dos Padrões de Crip-
tografia de Chave Pública (PKCS1), publicado pelo laboratório RSA que define uma
API (Application Programming Interface) independente de plataforma para disposi-
tivos criptográficos, tais como Hardware Security Modules (HSM), smart cards e to-
kens USB. Os conceitos explicados sobre o PKCS #11 foram baseados no [PKC 11].
Esta API, chamada também de Cryptoki (Cryptographic token interface)
foi desenvolvida para ser uma camada de abstração genérica para dispositivos crip-
tográficos. A API PKCS #11 define os mais comuns tipos de objetos criptográficos
usados (Chaves RSA, Certificados X.509, chaves DES/Triple DES, etc) e todas as
funções necessárias para utilizar, criar, modificar e deletar esses objetos.
Cryptoki foi concebido para ser uma interface entre aplicações e todos os
tipos de dispositivos criptográficos.
O principal objetivo da Cryptoki é ser uma interface de programação de
baixo nível que abstrai os detalhes dos dispositivos, e apresenta para a aplicação um
modelo comum do dispositivo criptográfico, chamado um “token criptográfico” (ou
simplesmente “token”), desse modo a aplicação não tem que mudar a interface para
um tipo diferente de dispositivo.
Outro objetivo é o compartilhamento de recursos. Como sistemas opera-
1Public-Key Cryptography Standards
18
cionais multi-tarefa tornou-se mais popular, um único dispositivo deveria ser compar-
tilhado entre mais do que uma aplicação. Além disso, uma aplicação deve ser capaz de
acessar mais do que um dispositivo em um dado momento.
Não é o objetivo da Cryptoki ser uma interface genérica para operações
criptográficas ou serviços de segurança, embora poderia construir tais operações e
serviços com as funções que a Cryptoki oferece. O intuito da Cryptoki é comple-
mentar e não competir com interfaces emergentes e em desenvolvimento como a In-
terface de programação da aplicação de serviços de segurança genérico (Generic Se-
curity Services Application Programming Interface), conforme definido em [IET 11b]
e [IET 11a] e API de Serviço criptográfico genérico (Generic Cryptographic Service
API) da X/Open.
3.1 Modelo Geral
O Modelo geral da Cryptoki é ilustrado na fugura 3.1. O modelo começa
com uma ou mais aplicações que precisam executar determinadas operações criptográ-
ficas, e termina com um ou mais dispositivos criptográficos, sobre os quais algumas ou
todas as operações são realmente executadas. Um usuário pode ou não estar associado
com uma aplicação.
Cryptoki fornece uma interface para um ou mais dispositivos criptográ-
ficos que estão ativos no sistema através de um número de “slots”. Cada slot, que
corresponde para um leitor físico ou outra interface do dispositivo, pode conter um to-
ken. Um token está tipicamente “presente no slot” quando um dispositivo criptográfico
está presente no leitor. Naturalmente, como a Cryptoki fornece uma visão lógica dos
slots e tokens, pode haver outras interpretações físicas. Pode acontecer que vários slots
compartilhem o mesmo leitor físico. O ponto é que um sistema tem um determinado
número de slots, e aplicações podem conectar com os tokens em qualquer um ou em
todos destes slots.
Cryptoki é própria para ser implementada como uma biblioteca de suporte
19
Figura 3.1: Modelo Geral da Cryptoki [PKC 11]
para funções na interface, e aplicações serão ligadas à biblioteca. Uma aplicação pode
ser ligada à Cryptoki diretamente ou ligada como uma biblioteca “compartilhada” (ou
biblioteca ligada dinamicamente).
Os tipos de dispositivos e capacidades suportadas dependerão da particu-
lar biblioteca Cryptoki. Este padrão específica somente a interface para a biblioteca,
não suas características. Em particular, nem todas bibliotecas suportarão todos os
mecanismos (algoritmos) definido nesta interface (uma vez que nem todos os tokens
são esperados para suportar todos os algoritmos), e bibliotecas provavelmente supor-
tarão somente um sub-conjunto de todos os tipos de dispositivos criptográficos que
estão disponíveis. (O melhor é previnir que as bibliotecas que serão desenvolvidas
suportem múltiplos tipos de token, e não apenas de um único fabricante). À medida
que aplicações são desenvolvidas para a interface Cryptoki, são esperados padrões de
biblioteca e “perfis” de token.
20
3.2 Visão lógica de um token
A visão lógica de um token é um dispositivo que armazena objetos e pode
executar funções criptográficas. Cryptoki define três classes de objetos: dado, certifi-
cado e chave. Um objeto dado é definido por uma aplicação. Um objeto certificado
armazena um certificado. Um objeto chave armazena uma chave criptográfica. A chave
pode ser um chave pública, uma chave privada, ou uma chave secreta, cada um desses
tipos de chaves tem subtipos para uso em algoritmos específicos. Esta visão é ilustrada
na figura 3.2:
Figura 3.2: Hierarquia de Objetos [PKC 11]
Objetos também são classificados de acordo com seu tempo de vida e visi-
bilidade. “Objetos do token” são visíveis para todas aplicações conectadas com o token
que têm suficiente permissão, e permanecem no token mesmo depois que as sessões
(conexões entre um aplicativo e um token) são fechadas e o token é removido de seu
slot. “Objetos de sessão” são temporários: sempre que uma sessão é fechada, todos
os objetos de sessão criados por meio da sessão que foi fechada são automaticamente
destruídos. Além disso, objetos de sessão são somente visíveis pela aplicação que os
criou.
Aplicações não precisam conectar com o token para mostrar “objetos públi-
cos”, no entanto, para mostrar “objetos privados” um usuário dever ser autenticado pelo
21
token através de um PIN ou algum outro método dependente do token (por exemplo,
um dispositivo biométrico).
Um token pode criar, manipular, procurar e destruir objetos. Ele pode
também executar funções criptográficas com objetos.
É importante distinguir entre a visão lógica de um token e a presente im-
plementação, porque nem todos os dispositivos criptográficos terão este conceito de
“objetos” ou serão capazes de executar todos os tipos de funções criptográficas. Muitos
dispositivos simplesmente estabelecerão locais de armazanamento para chaves de um
algoritmo fixo, e serão capazes de executar um limitado conjunto de operações.
O papel da Cryptoki é traduzir isso dentro da visão lógica, mapeando atrib-
utos para fixo armazenamento de elementos e assim por diante. Nem toda biblioteca
Cryptoki e token suportam todos os tipos de objeto. É esperado que padrão de “perfis”
seja desenvolvido, especificando um conjunto de algoritmos suportados.
3.3 Usuários
Esta versão da Cryptoki reconhece dois tipos de usuário do token. Um tipo
é o Security Officer (oficial de segurança). O outro tipo é o usuário normal. Somente
o usuário normal tem permissão para acessar os objetos privados do token, e estes
acessos são garantidos somente depois que o usuário normal se autentica. Alguns to-
kens podem também requerer que o usuário seja autenticado antes de qualquer função
criptográfica executado no token, se envolvem ou não objetos privados.
O papel do SO (Security Officer) é inicializar um token e definir o PIN
do usuário normal (ou de outra maneira definir por algum método fora do escopo da
Cryptoki, como o usuário normal pode ser autenticado), e possivelmente manipular
alguns objetos públicos. O usuário normal pode conectar com o token, somente depois
que o SO definir seu PIN.
22
3.4 Aplicação e seu uso da Cryptoki
Uma aplicação torna-se uma “aplicação Cryptoki” após executar a função
C_Initialize da Cryptoki, depois que esta chamada é feita, a aplicação pode executar
outras funções da Cryptoki. Quando a aplicação terminar o uso da Cryptoki, ela deve
executar a função C_Finalize para deixar de ser uma aplicação Cryptoki.
3.5 Sessões
Cryptoki requer que uma aplicação abre uma ou mais sessões com um
token para ganhar acesso para o objetos do token e funções. Uma sessão fornece uma
conexão lógica entre a aplicação e o token. Uma sessão pode ser read/write (R/W)
ou read only (R/O). Sessão read/write (R/W) e sessão read only (R/O) referem se
para acessar objetos do token, não para acessar objetos de sessão. Em ambos os tipos
de sessão, uma aplicação pode criar, ler, escrever e destruir objetos de sessão, e ler
objetos do token. Entretanto, somente sessão read/write (R/W) pode uma aplicação
criar, modificar e destruir objetos do token.
Depois de aberta uma sessão, uma aplicação tem acesso para os objetos
públicos do token. Todas as threads de uma dada aplicação tem acesso exatamente
para as mesmas sessões e os mesmos objetos de sessão. Para ganhar acesso a objetos
privados do token, o usuário normal deve conectar e ser autenticado.
Quando uma sessão é fechada, todos os objetos de sessão que foi criado
naquela sessão são destruídos. Isto é válido mesmo para os objetos de sessão que estão
“sendo usado” por outras sessões. Isto é, se uma única aplicação tem múltiplas sessões
abertas com um token, e ela usa uma delas para criar um objeto de sessão, então aquele
objeto de sessão é visível por meio de qualquer uma das sessões da aplicação. Porém,
logo que a sessão que foi usada para criar o objeto é fechada, esse objeto é destruído.
Cryptoki suporta várias sessões sobre vários tokens. Uma aplicação pode
ter uma ou mais sessões com um ou mais tokens. Em geral, um token pode ter várias
sessões com uma ou mais aplicações. Um particular token pode permitir que uma apli-
23
cação tenha somente um número limitado de sessões, ou somente um número limitado
de sessões leitura/escrita.
Uma sessão aberta pode estar em um de vários estados. O estado da sessão
determina permissão para acessar objetos e funções que podem ser executadas.
3.5.1 Estados de sessão somente leitura
Uma sessão somente leitura pode estar em um de dois estados, como ilustrado
na figura 3.3. Quando a sessão é inicialmente aberta, ela está no estado “Sessão pública
R/O” (se a aplicação não tem uma sessão aberta anterior que estava conectada) ou es-
tado “Funções de usuário R/O” (se a aplicação já tem uma sessão aberta que estava
conectada). Observe que na sessão SO o estado somente leitura (R/O) não existe.
Figura 3.3: Estados de sessão somente leitura [PKC 11]
3.5.2 Estados de Sessão Leitura/Escrita
Uma sessão leitura/escrita pode estar em um de três estados, como ilustrado
na figura 3.4. Quando a sessão é aberta, ela está no estado “Sessão Pública R/W” (se a
aplicação não tem uma sessão aberta anterior que estava conectada), o estado “Funções
do usuário R/W” (se a aplicação já tem uma sessão aberta que o usuário normal estava
conectado), ou o estado “Funções do SO R/W” (se a aplicação já tem uma sessão aberta
que o SO estava conectado).
24
Figura 3.4: Estados de sessão Leitura/Escrita [PKC 11]
3.5.3 Acessos de objetos permitidos por sessões
A seguinte tabela 3.5 resume os tipos de acesso que cada tipo de sessão tem
para cada tipo de objeto. Um dado tipo de sessão tem acesso somente leitura, acesso
leitura/escrita, ou nenhum acesso para um dado tipo de objeto.
Observe que criar ou deletar um objeto requer acesso leitura/escrita para
ele, isto é, sessão “Funções do usuário R/O” não podem criar ou deletar um objeto de
token.
Figura 3.5: Tabela: Acesso para diferentes tipos de objetos por diferentes tipos de sessões
[PKC 11]
25
Conforme já explicado, o acesso para um dado objeto de sessão que é
mostrado na tabela é limitado para sessões pertencentes à aplicação que possui este
objeto(isto é, que criou este objeto).
3.5.4 Identificador de sessão e identificador de objeto
Um identificador de sessão é um valor atribuído pela Cryptoki para identi-
ficar uma sessão. É muito semelhante a um identificador de arquivo, e é especificado
para as operações para indicar sobre qual sessão a função vai ser executada.
Todas threads de uma aplicação tem acesso igual para todos identificadores
de sessão. Isto é, qualquer coisa que pode ser realizado com um determinado identi-
ficador por uma thread pode também ser realizado com o mesmo identificador por
qualquer outra thread da mesma aplicação.
3.5.5 Capacidades de sessões
Em termos muito gerais, existem três tipos de operações que uma sessão
aberta pode ser usada para executar: operações administrativas (por exemplo, fazer
login), operações de administração de objeto (por exemplo, criar ou destruir um ob-
jeto do token) e operações criptográficas (por exemplo, calcular uma mensagem de
resumo). Operações Criptográficas algumas vezes requer mais do que uma chamada
para a API Cryptoki para serem concluídas. Em geral, uma única sessão pode execu-
tar somente uma operação por vez, por esta razão, pode ser desejável para uma única
aplicação abrir várias sessões com um único token. Por razões de eficiência, no en-
tanto, uma única sessão em alguns tokens pode executar o seguinte par de operações
ao mesmo tempo: resumir e cifrar mensagem; decifrar e resumir mensagem; assinar e
cifrar; e decifrar e verificar assinaturas.
Uma conseqüência do fato que uma única sessão pode, em geral, execu-
tar somente uma operação por vez é que uma aplicação nunca deve fazer diversas
chamadas de funções para Cryptoki que usa uma sessão em comum. Se múltiplas
26
threads de uma aplicação tenta usar uma sessão em comum concorrentemente desta
forma, Cryptoki não define o que acontece.
Isto significa que se várias threads de uma aplicação precisam fazer o uso
da Cryptoki para acessar um particular token, é apropriado para cada thread ter sua
própria sessão com o token, a menos que a aplicação pode assegurar por algum outro
meio (isto é por algum mecanismo de bloqueio) que nenhuma das sessões estão sendo
usadas por várias threads ao mesmo tempo. Isto é verdadeiro independente se ou não
a biblioteca Cryptoki foi inicializada de modo que permita acesso seguro para várias
threads. Mesmo se é seguro acessar a biblioteca por diversas threads ao mesmo tempo,
ainda não é necessariamente seguro usar uma particular sessão com múltiplas threads
ao mesmo tempo.
3.6 Uma visão geral das funções
A API Cryptoki consiste de um número de funções, abrangendo adminis-
tração de slot e token e administração de objeto, assim como funções criptográficas.
Estas funções são apresentadas a seguir:
3.6.1 Funções de propósito geral:
• C_Initialize: inicializa a Cryptoki.
• C_Finalize: limpa os recursos associadas a Cryptoki.
• C_GetInfo: obtém informações gerais sobre a Cryptoki.
• C_GetFunctionList: obtém os pontos de entrada das funções Cryptoki.
3.6.2 Funções para administração de slot e token:
• C_GetSlotList: obtém uma lista de slots no sistema.
• C_GetSlotInfo: obtém informações sobre um particular slot.
27
• C_GetTokenInfo: obtém informações sobre um particular token.
• C_WaitForSlotEvent: aguarda um evento do slot (inserção do token, remoção,
etc) para ocorrer.
• C_GetMechanismList: obtém uma lista dos algoritmos suportados pelo token.
• C_GetMechanismInfo: obtém informações sobre um particular algoritmo.
• C_InitToken: inicializa um token.
• C_InitPIN: inicializa o PIN do usuário normal.
• C_SetPIN: define o PIN do usuário atual.
3.6.3 Funções para administração de sessão:
• C_OpenSession: abre uma conexão entre uma aplicação e um particular token.
• C_CloseSession: fecha uma sessão.
• C_CloseAllSessions: fecha todas as sessões com um token.
• C_GetSessionInfo: obtém informações sobre a sessão.
• C_GetOperationState: obtém o estado das operações criptográficas de uma sessão.
• C_SetOperationState: define o estado das operações criptográficas de uma sessão.
• C_Login: conecta no token.
• C_Logout: desconecta do token.
3.6.4 Funções para administração de objeto:
• C_CreateObject: cria um objeto.
• C_CopyObject: cria uma cópia de um objeto.
28
• C_DestroyObject: destrói um objeto.
• C_GetObjectSize: obtém o tamanho de um objeto em bytes.
• C_GetAttributeValue: obtém o valor de atributo de um objeto.
• C_SetAttributeValue: modifica o valor de atributo de um objeto.
• C_FindObjectsInit: inicializa uma operação de busca de objeto.
• C_FindObjects: continua uma operação de busca de objeto.
• C_FindObjectsFinal: finaliza uma operação de busca de objeto.
3.6.5 Funções de cifrar:
• C_EncryptInit: inicializa uma operação de cifrar.
• C_Encrypt: cifra uma única parte dos dados.
• C_EncryptUpdate: continua uma operação de cifrar.
• C_EncryptFinal: finaliza uma operação de cifrar.
3.6.6 Funções de decifrar:
• C_DecryptInit: inicializa uma operação de decifrar.
• C_Decrypt: decifra uma única parte dos dados cifrados.
• C_DecryptUpdate: continua uma operação de decifrar.
• C_DecryptFinal: finaliza um operação de decifrar.
29
3.6.7 Funções de resumo da mensagem:
• C_DigestInit: inicializa uma operação de resumo de mensagem.
• C_Digest: resume uma única parte dos dados.
• C_DigestUpdate: continua uma operação de resumo.
• C_DigestKey: resume uma chave.
• C_DigestFinal: finaliza uma operação de resumo.
3.6.8 Funções de assinatura:
• C_SignInit: inicializa uma operação de assinatura.
• C_Sign: assina uma única parte dos dados.
• C_SignUpdate: continua uma operação de assinatura.
• C_SignFinal: finaliza uma operação de assinatura.
• C_SignRecoverInit: inicializa uma operação de assinatura, onde os dados podem
ser recuperados da assinatura.
• C_SignRecover: assina uma única parte dos dados, onde os dados podem ser
recuperados da assinatura.
3.6.9 Funções para verificação de assinatura:
• C_VerifyInit: inicializa uma operação de verificação.
• C_Verify: verifica uma assinatura de uma única parte dos dados.
• C_VerifyUpdate: continua uma operação de verificação.
• C_VerifyFinal: finaliza uma operação de verificação.
30
• C_VerifyRecoverInit: inicializa uma operação de verificação, onde os dados são
recuperados da assinatura.
• C_VerifyRecover: verifica uma assinatura de uma única parte dos dados, onde
os dados são recuperados da assinatura.
3.6.10 Funções criptográficas com duplo propósito:
• C_DigestEncryptUpdate: continua simultaneamente uma operação de resumir e
cifrar.
• C_DecryptDigestUpdate: continua simultaneamente uma operação de decifrar e
resumir.
• C_SignEncryptUpdate: continua simultaneamente uma operação de assinar e
cifrar.
• C_DecryptVerifyUpdate: continua simultaneamente uma operação de decifrar e
verificar.
3.6.11 Funções para administração de chave:
• C_GenerateKey: gera uma chave secreta.
• C_GenerateKeyPair: gera um par de chaves público/privada.
• C_WrapKey: cifra uma chave.
• C_UnwrapKey: decifra uma chave.
• C_DeriveKey: deriva uma chave de uma chave base.
3.6.12 Funções para geração de números aleatórios:
• C_SeedRandom: associa uma semente para o gerador de números aleatórios.
• C_GenerateRandom: gera dados aleatórios.
31
3.6.13 Funções para administração de função paralela:
• C_GetFunctionStatus: função que sempre retorna CKR_FUNCTION_NOT_PARALLEL.
• C_CancelFunction : função que sempre retorna CKR_FUNCTION_NOT_PARALLEL.
O foco deste trabalho não é tratar das vulnerabilidades da API PKCS #
11, porém na próxima seção serão mencionadas algumas fraquezas de segurança que
existem no uso dessa API.
3.7 Vulnerabilidades na API PKCS #11
Em [CLU 03] foi analisada a segurança do padrão PKCS #11 como uma
interface para dispositivo criptográfico. Neste artigo foi mostrado que o PKCS #11 é
vulnerável a uma série de ataques conhecidos e novos em sua API e apresenta uma
série de pontos fracos no modelo que levantam questões quanto à sua adequação para
este papel. Também são propostas algumas soluções para os problemas tratados.
Algumas vulnerabilidades citadas em [CLU 03] são:
Ataques envolvendo chave simétrica:
• Key Conjuring.
• Key Binding.
• Key Separation.
• Weaker Key/Algorithm.
• Reduced Key Space.
• Parallel Search.
• Related Key Attack.
Ataques envolvendo chave pública:
32
• Weaker Key/Algorithm.
• Private Key Modification.
• Small Public Exponent with No Padding.
• Trojan Public Key.
• Trojan Wrapped Key.
• Key Separation.
3.8 IAIK PKCS#11 Wrapper
Esta é uma biblioteca para acessar módulos PKCS #11 da linguagem de
programação Java. O Wrapper usa a Interface Nativa do Java (Java Native Interface)
para acessar os módulos PKCS #11 de um cartão inteligente (smart card) ou de outro
dispositivo criptográfico como um HSM (hardware security modules).
Pessoas na IBM tiveram a idéia de implementar o wrapper antes. Seu
wrapper [IBM 11] também funciona muito bem, mas sua implementação não pode ser
usada para fins comerciais ou redistribuí-lo para qualquer outro propósito.
As informações sobre o wrapper PKCS #11 desenvolvido pelo IAIK2 foram
retiradas de [IAI 11].
3.9 O Modelo da Camada do Sistema
A figura 3.6 mostra o modelo das camadas desta biblioteca. Esta biblioteca
consiste da API Wrapper Java orientado a objetos para PKCS #11, a API Wrapper Java
sem orientação a objetos para PKCS #11 e o Módulo Nativo do Wrapper, que estão
representados pelas camadas verdes respectivamente.
2Institute for Applied Information Processing and Communication of the Graz University of Tech-
nology
33
A camada mais baixa, o módulo PKCS #11 de um dispositivo criptográfico
é o módulo PKCS #11 que o fabricante do dispositivo criptográfico fornece. Este é
normalmente uma DLL (Dynamic-link library) ou uma biblioteca compartilhada.
Como as setas mostram na figura, a camada mais alta depende do Wrapper
Java para PKCS #11, mas não vice-versa. Isto significa que pode ser usado o Wrap-
per Java para PKCS #11 diretamente e construir uma aplicação sobre ele sem usar a
camada OO (Orientado a Objetos). Dessa maneira, pode ser útil para criar aplicações
menores, porque muitas classes dos pacotes iaik.pkcs.pkcs11, iaik.pkcs.pkcs11.objects
e iaik.pkcs.pkcs11.parameters não são necessárias. Somente as classes de exceções são
necessárias do pacote iaik.pkcs.pkcs11.
Figura 3.6: Modelo das camadas
3.10 A API Java Orientado a Objetos para PKCS #11
A API Java Orientado a Objetos encontra-se nos pacotes iaik.pkcs.pkcs11,
iaik.pkcs.pkcs11.objects e iaik.pkcs.pkcs11.parameters. Ela fornece um mapeamento
do padrão PKCS #11 v2.20 para um conjunto de classes e interfaces. Um modelo
hierárquico de objeto apresentado no padrão PKCS #11 pode ser encontrado no pa-
cote iaik.pkcs.pkcs11.objects. O pacote iaik.pkcs.pkcs11.parameters fornece classes
para objetos que atuam como parâmetros para algoritmos que requerem argumentos
específicos. Esta camada construída sobre a API Java para PKCS #11 como também
implementado pelo Wrapper Java para PKCS #11.
34
3.11 A API Java para PKCS#11
A API Wrapper sem Orientação a Objetos para PKCS #11 é um conjunto
de classes Java e interfaces que reflete a API PKCS #11. Ela é uma realização direta
das estruturas de dados como definido no PKCS #11.
Para cada estrutura no arquivo de cabeçalho (header file) do PKCS #11, há
uma correspondente classe no pacote iaik.pkcs.pkcs11.wrapper. Observe, que não é
uma abordagem orientado a objetos neste nível. É apenas um mapeamento direto das
estruturas de dados para Java. Todas as adoções da API PKCS #11, incluindo wrapping
dentro de uma abordagem orientado a objetos, aparece na API Wrapper Java Orientado
a Objetos para PKCS #11.
A interface PKCS11 no pacote iaik.pkcs.pkcs11.wrapper é a interface para
um módulo PKCS #11 e fornece acesso para as funções definidas no PKCS #11.
Todos os nomes de classes, estruturas de dados e métodos são os mesmos
que os correspondentes no padrão PKCS #11.
O PKCS11Connector instancia um objeto que implementa a interface PKCS
#11. O Objeto retornado tem acesso para o módulo PKCS #11 do dispositivo crip-
tográfico, ele é a contrapartida para o CK_C_GetFuntionList retornada pela função
C_GetFuntionList no PKCS #11. A classe Module na camada orientado a objetos
fornece as respectivas funcionalidades.
3.12 O Módulo Nativo do Wrapper
O módulo nativo do wrapper é responsável para interpretação das estru-
turas de dados Java, na qual a API Java para PKCS #11 define, para estruturas de
dados nativos PKCS #11 e vice-versa.
Este módulo do sistema não inclue qualquer lógica adicional, ele somente
fornece um mapeamento direto da API Java para PKCS #11 para o módulo PKCS #11
do dispositivo criptográfico.
Esta camada é necessária, porque a JNI (Java Native Interface) requer as
35
funções nativas para ter uma assinatura especial que é definido pela própria JNI. PKCS
#11 e JNI não são compatíveis, e esta é a razão pela qual esta camada é necessária.
Na forma compilada, este módulo é uma nativa DLL (Dynamic-link library) ou uma
biblioteca compartilhada.
3.13 Compatibilidade
Esta implementação deve ser compatível com todos os Java2 (e também
JDK 1.1.8) e JNI 1.1. Ele baseia-se sobre a versão 2.20 do PKCS #11, mas deve
também funcionar para qualquer driver 2.x. O código nativo está escrito em C e pode
ser compilado sobre diferentes plataformas como: Windows e Unix.
Capítulo 4
Interface Gráfica PKCS #11
Neste capítulo será mostrada a interface gráfica que foi desenvolvida uti-
lizando a linguagem de programação java, esta aplicação foi nomeada como GUICryp-
tokiEasyAccess que é uma abreviação para graphical user interface for cryptoki easy
access.
Apesar da GUICryptokiEasyAccess ser projetada para o usuário que tem
conhecimento dos conceitos básicos da documentação PKCS #11, uma pessoa que não
tenha conhecimento desse padrão poderá utilizar muitas funcionalidades desta inter-
face, devido a sua usabilidade, na qual permite que muitas operações sejam intuitivas
para o usuário executá-las.
Ao executar a GUICryptokiEasyAccess, é pedido para o usuário inserir o
caminho do módulo PKCS #11, como mostra a figura 4.1.
Figura 4.1: Carregar módulo PKCS #11
Após o campo módulo ser preenchido e o botão carregar ser clicado, se
tiver mais do que um dispositivo criptográfico conectado no computador, uma janela
37
será exibida para que o usuário selecione um token para ser acessado, o token será
identificado pelo seu label, conforme é mostrada na imagem 4.2, após o usuário ter
escolhido o token, o botão inicializar deve ser acionado para que a tela principal da
interface gráfica PKCS #11 seja mostrada. Caso tenha somente um dispositivo crip-
tográfico, a tela principal da GUICryptokiEasyAccess é exibida direta.
Figura 4.2: Selecionar Token
4.1 Tela Principal
A tela principal da GUICryptokiEasyAccess consiste de uma barra de menu
na parte superior com as opções: Token e Help, no lado esquerdo são mostradas as
seguintes categorias:
• Informations.
• Token Management.
• Key Management.
• Session Management.
• Object Management.
• Digest Function.
• Certificate Import.
• Operations.
38
• Set Attribute.
Cada categoria tem suas respectivas funções para serem acessadas pelo
usuário, essas funções serão explicadas nas próximas sessões deste capítulo.
Na região central da tela são exibidas as operações da categoria escolhida,
por padrão quando a tela principal é visualizada pela primeira vez, mostra na região
central os serviços da categoria de informações, a figura 4.3 mostra a tela principal da
interface gráfica.
Figura 4.3: Tela Principal da GUICryptokiEasyAccess
4.2 Categoria de Informações
Nesse painel, o usuário poderá ver as informações sobre a Cryptoki, Slot,
Token e Mechanism, para exibi-las precisa selecionar a opção desejada e clicar no
39
botão Mostrar, após feito isso, serão mostradas as informações específicas do item
escolhido.
4.2.1 Informações da Cryptoki:
Nas informações da Cryptoki, pode-se saber o número da versão da in-
terface Cryptoki, o identificador do fabricante da biblioteca Cryptoki, a descrição da
biblioteca e o número da versão da biblioteca Cryptoki, como mostra a figura 4.4.
Figura 4.4: Informações gerais da Cryptoki
4.2.2 Informações do Slot:
Quando é escolhida essa opção, são mostradas as informações do slot
(leitor lógico) que contém o token que o usuário acessou. O resultado dessa operação
é ilustrado abaixo em 4.5.
40
Figura 4.5: Informações do Slot que contém o token acessado
4.2.3 Informações do Token:
Nas informações do Token, pode-se conhecer o label que foi definido
quando foi feito a sua inicialização, o identificador do fabricante do dispositivo, mod-
elo, número serial do dispositivo, quantidade de sessões abertas e entre outras infor-
mações que são definadas na documentação PKCS #11. A figura 4.6 mostra um exem-
plo de atributos e seus valores de um token específico.
Ao descer a barra de rolagem vertical visualizada na figura acima, o usuário
consegue ver as demais informações disponíveis do token e também um botão de in-
formações de flags que ao ser clicado abre uma janela que contém as respectivas infor-
mações de flags do token, indicando as capacidades e estados do dispositivo criptográ-
fico, exibidos na figura 4.7. Essas informações são muito relevantes, pois permitem por
exemplo saber se o usuário tem uma última tentativa para fazer a autenticação através
41
Figura 4.6: Informações do token acessado
do PIN, caso não tenha, se for digitado o PIN errado, seu PIN será bloqueado.
4.2.4 Informações do Mecanismo:
Ao executar essa função, é mostrada uma lista dos algoritmos suportados
pelo token. Um mecanismo especifica precisamente como um certo processo crip-
tográfico é para ser executado, ou seja, define um conjunto de instruções que são real-
izadas em uma determinada ordem. Dificilmente um token suporta todos os algoritmos
definidos na Cryptoki, sendo assim, somente um subconjunto dos mecanismos é su-
portado pelo dispositivo criptográfico, como mostrado em 4.8 :
Para ver as informações de um mecanismo específico, precisa selecionar
o algoritmo e depois clicar no botão conseguir informações, caso nenhum algoritmo
seja selecionado, o usuário é informado para selecionar um algoritmo. Ao executar
42
Figura 4.7: Informações de flags do Token
corretamente os passos mencionados anteriormente, é mostrado uma janela que contém
as informações do algoritmo escolhido, o exemplo abaixo (4.9) mostra as informações
do mecanismo CKM_RSA_PKCS_KEY_PAIR_GEN :
4.3 Categoria de Administração do Token
As funcionalidades dessa categoria são: inicialização do Token, alterar PIN
e inicializar o PIN do usuário normal como ilustrado em 4.10, o oficial de segurança
utiliza essa sessão para cumprir seu papel que é inicializar o token e definir o PIN do
usuário normal, poderia se dizer que essas são as primeiras funções executadas em um
dispositivo criptográfico.
4.3.1 Inicialização do Token:
Na inicialização do token, todos os objetos que podem ser destruídos são
destruídos e o usuário normal só poderá se autenticar depois que o oficial de segurança
43
Figura 4.8: Lista de algoritmos que podem ser usados no Token
(Security Officer) definir seu PIN.
Para inicializar um token é preciso digitar todos os campos mostrados para
essa funcionalidade, caso um ou mais campos não forem preenchidos, será informado
para o usuário que todos os campos devem ser definidos, os atributos necessários são
o label que serve como uma identificação para o token e o PIN do oficial de segurança,
também é preciso que o PIN de confirmação tenha o valor igual do campo PIN digitado
anteriormente, se não estiver, uma mensagem avisará que o PIN de confirmação não
combina com o primeiro valor do PIN digitado. Após todos os valores dos campos es-
tiverem corretos e em seguida ser clicado no botão Inicializar, o token será inicializado
e uma mensagem de sucesso para essa operação é mostrado para o usuário. A imagem
4.11 é um exemplo,na qual, todos os campos estão preenchidos corretamente.
Um dispositivo criptográfico não pode ser inicializado se a Cryptoki de-
tecta que a aplicação tem uma sessão aberta com ele, quando a função inicializar token
44
Figura 4.9: Informações do algoritmo CKM_RSA_PKCS_KEY_PAIR_GEN
é executada sob tais circunstâncias, a operação falha e retorna o erro da Cryptoki:
CKR_SESSION_EXISTS.
4.3.2 Alterar PIN:
Para alterar o PIN é preciso selecionar o usuário que terá o PIN modificado,
isto é, escolher o usuário normal ou o oficial de segurança, por padrão é selecionado
o usuário normal, o próximo passo é digitar o antigo PIN, depois digitar o novo PIN e
em seguida confirmar o valor do PIN digitado anteriormente, conforme mostra a figura
4.12 com os campos preenchidos corretamente, o último passo é clicar no botão Al-
terar, caso ocorra nenhum erro, é retornado uma mensagem de sucesso dessa operação
para o usuário.
45
Figura 4.10: Administração do Token
Figura 4.11: Inicialização do Token
4.3.3 Inicializar o PIN do usuário normal
O oficial de segurança deve digitar seu PIN, em seguida inserir o PIN do
usuário normal e depois digitar novamente o PIN do usuário, após serem fornecidas
todas as informações necessárias e ter clicado no botão Inicializar, é mostrado uma
mensagem de sucesso informando o usuário, caso a execução desse serviço não falhar.
46
Figura 4.12: Alterar PIN
O painel de inicializar o PIN do usuário com os campos preenchidos é ilustrado em
4.13.
Figura 4.13: Inicializar PIN do usuário normal
4.4 Categoria Administração de Chaves
Nesta categoria, como mostra a figura 4.14, é possível criar os tipos de
objetos:
• Chave Secreta.
• Par de chaves pública/privada.
As chaves criadas podem ser usadas para realizar operações criptográfi-
cas,como exemplo, o usuário pode usar sua chave privada para assinar um documento
digital.
47
Figura 4.14: Administração de Chaves
4.4.1 Gerar chave secreta
Para gerar uma chave secreta, os atributos necessários dependem do algo-
ritmo escolhido, para os algoritmos:
• CKM_GENERIC_SECRET_KEY_GEN.
• CKM_RC2_ECB.
• CKM_RC2_CBC.
• CKM_RC2_KEY_GEN.
O usuário precisa fornecer os dados para os campos: tamanho (em bytes)
e nome da chave, e se ele quiser armazenar a chave secreta no token, deve marcar a
checkbox (in Token) e digitar o seu PIN, caso não seja marcado a opção para armazenar
48
no token, a chave criada será um objeto de sessão. No caso do mecanismo selecionado
for um desses:
• CKM_DES3_KEY_GEN.
• CKM_DES3_ECB.
• CKM_DES3_CBC
• CKM_DES3_CBC_PAD
• CKM_DES3_MAC_GENERAL
• CKM_DES3_MAC
O campo necessário é o nome da chave, e se desejar qua a chave seja um
objeto do token, é preciso marcar a opção armazenar e digitar o PIN. A figura , mostra
os atributos necessários para o algoritmo selecionado CKM_DES3_KEY_GEN.
Figura 4.15: Chave Secreta
4.4.2 Gerar par de chaves pública/privada
Na primeira versão, A GUICryptokiEasyAccess tem disponível o mecan-
ismo CKM_RSA_PKCS_KEY_PAIR_GEN para geração do par de chaves, o usuário
precisa definir os valores para os atributos: tamanho (em bits), nome da chave, caso
49
queira que o par de chaves pública/privada sejam objetos do token, deve marcar as
duas checkboxes na opção armazenar e em seguida digitar o PIN como mostrado em
4.16, se o usuário quiser somente armazenar uma das chaves, basta marcar a checkbox
da chave que ele quer armazenar e depois também tem que digitar seu PIN, como na
condição anterior, se o par de chaves pública/privada são objetos de sessão, então so-
mente os dois primeiros campos devem ser preenchidos. O valor do expoente da chave
pública gerada é 65537, conforme o padrão mencionado na documentação PKCS #11.
Figura 4.16: Par de chaves pública/privada
A execução da função gerar par de chaves, nunca cria apenas uma chave e
retorna, uma chamada pode falhar, e dessa forma nenhuma chave será gerada, ou em
caso de sucesso, criar uma combinação de par de chaves pública/privada.
4.5 Categoria Administração de Sessões
Todas operações relacionadas com sessão estão nessa categoria, suas fun-
cionalidades são:
• Conseguir informações.
• Abrir sessão RW.
50
• Abrir sessão RO.
• Fechar sessão.
• Fechar todas sessões.
• Conectar e desconectar usuário normal.
• Conectar e desconectar oficial de segurança.
A imagem relacionada a administração de sessões é mostrada abaixo em
4.17:
Figura 4.17: Administração de Sessões
Um token tem um número limitado de sessões que podem ser abertas con-
forme o padrão PKCS #11, na aplicação GUICryptokiEasyAccess o número de sessões
abertas se limita a dois, ou seja, pode abrir uma sessão RW e uma sessão RO somente,
51
quando um tipo de sessão já está aberta e o usuário tenta abrir essa sessão, é mostrada
a mensagem que a sessão já existe.
4.5.1 Informações da sessão
Para conseguir informações de uma sessão, é preciso selecionar o identifi-
cador da sessão na combobox sessão atual e clicar no botão Informações, em seguida
uma janela contendo as informações da sessão será exibida como mostra a figura 4.18.
Figura 4.18: Informações da Sessão
4.5.2 Abrir sessão RO
Para abrir uma sessão RO, somente precisa clicar no botão abrir Sessão RO,
caso essa sessão já esteja aberta, uma mensagem informando que a sessão já existe será
mostrada, caso contrário, é mostrado para o usuário uma mensagem de sucesso para
essa operação.
4.5.3 Abrir sessão RW
Similarmente como foi explicado para a funcionalidade abrir Sessão RO,
a única diferença é o botão abrir Sessão RW que deve ser clicado.
52
4.5.4 Fechar sessão
Para fechar uma sessão, basta selecionar uma determinada sessão na com-
bobox sessão atual e clicar no botão fechar, se não existir sessão, uma mensagem vai
ser mostrada informando sobre isso, senão uma mensagem de sucesso vai ser retornada
para o usuário.
4.5.5 Fechar todas as sessões
Quando as sessões RO e RW estiverem abertas, para fechar as duas sessões
simultaneamente, o usuário precisa clicar no botão fechar todas as sessões, uma men-
sagem de sucesso informando-o será exibida se a execução dessa operação não tiver
falha. Caso não existir sessões abertas, será mostrada uma mensagem informando o
usuário.
4.5.6 Desconectar usuário
Para desconectar o usuário normal ou o oficial de segurança, basta clicar no
botão desconectar, na Cryptoki quando uma sessão RO ou RW volta para o estado de
sessão pública, todas as sessões abertas com o token também voltam para esse estado.
4.5.7 Conectar usuário
Para conectar uma sessão RO ou RW, é preciso selecionar o usuário: usuário
normal ou oficial de segurança (Security Officer) e inserir seu respectivo PIN, por úl-
timo clicar no botão conectar. Uma observação importante é que não existe o estado
de sessão RO para o oficial de segurança, na tentiva de conectar o oficial de segurança
por meio de uma sessão RO, o erro CKR_SESSION_READ_ONLY_EXISTS será
mostrado para o usuário. Lembrando que ao conectar o estado de sessão do usuário,
todas as sessões abertas também vão mudar para esse estado, conforme definido na
documentação PKCS #11.
53
4.6 Categoria Administração de Objetos
Nesta categoria, o usuário pode procurar, conseguir informações e deletar
objetos do token ou de sessão do tipo: chave pública, chave privada, certificado e
chave secreta. A imagem 4.19 refere esta sessão. Lembrando que a sessão deve estar
no estado que permita o acesso para o tipo de objeto que o usuário deseja encontrar,
por exemplo, para objetos do tipo privado, a sessão deve estar no estado de usuário
para poder acessá-los, caso contrário, não terá acesso, somente depois que o usuário se
conectar é que a sessão vai poder acessar os objetos privados.
Figura 4.19: Administração de objetos
4.6.1 Mostrar objetos do token
Para procurar os objetos do token, o usuário tem que selecionar o tipo de
objeto, o tipo de sessão (sessão RO ou sessão RW) e clicar no botão conseguir objetos
54
do token, após disso, os objetos encontrados serão mostrados na tabela de objetos, caso
não existir os objetos do tipo especificado, uma mensagem será exibida informando o
usuário sobre isso.
4.6.2 Mostrar objetos de sessão
De forma similar ao explicado anteriormente, as diferenças existentes são:
se o usuário não selecionar o tipo de sessão, a sessão aberta vai ser RO e o botão
conseguir objetos de sessão é que deve ser clicado.
4.6.3 Mostrar informações do objeto
Para ver as informações de um objeto é preciso selecionar um objeto em
sua correspondente tabela e clicar no botão conseguir informações, em seguida uma
janela com as informações do objeto escolhido será mostrada para o usuário.
Em 4.20 , mostra as informações de uma chave pública.
A figura 4.21, exibe as informações de uma chave privada.
A imagem 4.22, mostra as informações de um certificado.
As informações de uma chave secreta é mostrada em 4.23:
4.6.4 Deletar objetos
Para deletar o objeto desejado tem que selecioná-lo em sua respectiva
tabela e depois clicar no botão Deletar.
4.6.5 Deletar todos os objetos
Para deletar todos os objetos, basta clicar no botão deletar todos os objetos.
55
Figura 4.20: Informações de uma chave pública
4.7 Categoria função de resumo
Na categoria função de resumo, pode-se tirar o hash de um arquivo, os
algoritmos de hash disponíveis são:
• CKM_MD2.
• CKM_MD5.
• CKM_SHA1.
• CKM_SHA256.
• CKM_SHA384.
56
Figura 4.21: Informações de uma chave privada
• CKM_SHA512.
• CKM_RIPEMD128
• CKM_RIPEMD160
• CKM_FASTHASH
A figura 4.24 mostra o painel de função de resumo.
4.7.1 Função de hash
Para tirar o hash é necessário selecionar o mecanismo desejado, inserir
o caminho absoluto de um determinado arquivo e depois clicar no botão conseguir
resumo. O valor do hash do arquivo escolhido é mostrado no campo valor de resumo,
conforme é mostrado em 4.25.
57
Figura 4.22: Informações de um certificado
4.8 Categoria importar certificado
Nesta sessão, o usuário pode importar um certificado no padrão X509, o
objeto importado pode ser do token ou de sessão, conforme será explicado adiante.
4.8.1 Importar certificado
Para importar um certificado, o usuário precisa inserir o caminho absoluto
do certificado e caso queira armazenar no token, a opção armazenar deve ser marcada,
senão será importado como objeto sessão, por último, o botão importar deve ser cli-
cado, como mostra a figura 4.26. Se nenhuma falha ocorrer,uma mensagem de sucesso
para essa operação será exibida.
58
Figura 4.23: Informações de uma chave secreta
4.9 Categoria operações criptográficas
Esta categoria é responsável para oferecer as seguintes operações crip-
tográficas:
• Assinar.
• Verificar assinatura.
• Cifrar.
• Decifrar.
Os tipos de chaves que podem ser usadas são: pública, privada e secreta.
A imagem 4.27 mostra essa sessão.
59
Figura 4.24: Função de resumo
Figura 4.25: Valor de hash para o arquivo engine_openhsmd.so
4.9.1 Assinar
Para assinar um documento digital é preciso selecionar a opção chaves pri-
vadas e depois clicar no botão procurar, o próximo passo é selecionar a chave privada
que será usada para fazer a assinatura, depois escolher o algoritmo de assinatura de-
sejado, em seguida escolher assinatura como operação criptográfica, um exemplo é
60
Figura 4.26: Importar certificado
Figura 4.27: Operações criptográficas
mostrado em 4.28. O passo seguinte é clicar no botão executar, em seguida o usuário
poderá selecionar o arquivo por meio de uma janela JfileChooser, se nenhum erro
ocorrer, uma mensagem de sucesso será mostrada para o usuário informando-o onde
foi gravado o arquivo assinado.
61
Figura 4.28: Assinar um documento digital
4.9.2 Verificar assinatura
Para vericar se uma assinatura é válida, precisa selecionar a opção chaves
públicas e depois clicar no botão procurar, o proximo passo é escolher a chave pública
que será usada para fazer a verificação, o passo seguinte é escolher o algoritmo, e
em seguida selecionar a operação criptográfica verificação como ilustrado em 4.29,
depois que os valores dos campos estiverem definidos, então o usuário deve clicar
no botão executar, em seguida será informado para o usuário que o próximo passo
será selecionar o arquivo que foi usado para ser assinado e uma janela JFileChooser é
exibida, após o arquivo original for selecionado, uma mensagem informará o usuário
que o último passo é selecionar o arquivo assinado através também de uma janela
JFileChooser, após destas instruções serem executadas, uma mensagem de sucesso
informando que a assinatura é válida é mostrada para o usuário, caso contrário, uma
mensagem de erro é exibida.
Figura 4.29: Verificar assinatura digital
62
4.9.3 Cifrar
Para cifrar um arquivo, o usuário tem que selecionar o tipo de chave que
deseja usar para fazer a cifragem e depois clicar no botão procurar, o próximo passo
é selecionar uma chave específica, em seguida escolhar o algoritmo RSA_PKCS, o
passo seguinte é selecionar cifragem no campo operação criptográfica, como mostra a
figura 4.30, em seguida clicar no botão executar, logo após, será pedido para selecionar
o arquivo que será cifrado através de uma janela JFileChooser, após o arquivo ser
escolhido,se nenhuma falha ocorrer uma mensagem de sucesso informando o local
onde o arquivo foi gravado é mostrada para o usuário.
Figura 4.30: Cifrar um documento digital
4.9.4 Decifrar
Para decifrar um arquivo, o processo é parecido com os passos explica-
dos anteriormente para função cifrar, as diferenças são: o usuário deve selecionar de-
cifragem como operação criptográfica como ilustrado em 4.31, e após o botão executar
ser clicado, será pedido para o usuário selecionar o arquivo cifrado, após escolhido o
arquivo, no caso de operação realizada com sucesso, uma mensagem é exibida infor-
mando onde o arquivo decifrado foi armazenado.
63
Figura 4.31: Decifrar um documento digital
4.10 Categoria alterar atributo
Na última categoria, o usuário pode modificar o valor de um atributo es-
pecífico de objetos como: chave pública, chave privada ou chave secreta. Os atributos
disponíveis para a primeira versão da interface GUICryptokiEasyAccess são:
• CKA_SIGN.
• CKA_ENCRYPT.
• CKA_DECRYPT.
• CKA_VERIFY.
A categoria alterar atributo é mostrada na figura 4.32.
4.10.1 Alterar atributo
Para alterar o valor de um atributo pertencente a um determinado objeto
tem que selecionar o tipo de objeto e clicar no botão procurar, em seguida selecionar
uma chave, o próximo passo é escolher qual atributo do objeto vai ser mudado, depois
no campo valor do atributo escolher o seu valor. Por último, clicar no botão definir
atributo, se nenhum erro ocorrer, uma mensagem de sucesso será mostrada para essa
operação.
64
Figura 4.32: Categoria definir atributo
Capítulo 5
Biblioteca LibCryptoDev
A LibCryptoDev foi desenvolvida com o objetivo de ser uma biblioteca
para ser usada por desenvolvedores de software que utilizam a linguagem de progra-
mação Java. A sua estrutura foi construída para facilitar o desenvolvimento de uma
aplicação que se comunica com o dispositivo criptográfico através da API PKCS #11.
O intuito dessa estrutura é também permitir que programadores que não tenham con-
hecimento do padrão PKCS #11 possam criar aplicações PKCS #11 por meio desta
biblioteca. [LAB 12]
As principais classes da LibCryptoDev são:
• ListUsb.
• CryptoDev.
• ModuleHandler.
• Token.
• ReadOnlySession.
• ReadWriteSession.
As funcionalidades essenciais de cada classe mencionada acima serão mostradas
nas próximas sessões deste capítulo.
O diagrama de classes da LibCryptoDev pode ser visto na figura 5.1.
66
5.1 ListUsb
Na interface GUICryptokiEasyAccess é preciso que o módulo PKCS #11
do dispositivo criptográfico seja informado para que aplicação consiga reconhecer os
dispositivos conectados compatíveis com esse módulo. A classe ListUsb foi imple-
mentada para reconhecer ”automaticamente” os tokens presentes sem a necessidade
do desenvolvedor ter que informar o módulo PKCS #11 diretamente, este processo é
feito utilizando o arquivo criado supported-devices.xml que contém os módulos reg-
istrados e permite que os dispositivos criptográficos, no qual usam um dos módulos
cadastrados sejam reconhecidos.
O método principal dessa classe é:
• setSupportedDevicesFile(File supportedDevices): Esta função define quais
dispositivos podem ser acessados de acordo com os módulos cadastrados. O
parâmetro supportedDevices é o arquivo de configuração criado: supported-
devices.xml, se não ocorrer erro este método não tem retorno, caso contrário,
retorna uma exceção.
Para a primeira versão da biblioteca, os módulos registrados no arquivo
supported-devices.xml são:
• libaetpkss.so.
• libepsng_p11.so.
Os correspondentes dispositivos criptográficos reconhecidos pelo módulo
libaetpkss.so são:
• Smart card da Starkos spk 2.3 ou 2.4 FIPS TESTE.
• Smart card da Morpho YPS ID-62.
• Smart card da Morpho J-ID MARK 64.
67
Para o módulo libepsng_p11.so, o smart card reconhecido é da Pronova
Token.
O programador, caso precisar pode adicionar no arquivo supported-devices.xml
novos módulos para poder acessar dispositivos criptográficos de fabricantes diferentes.
5.2 CryptoDev
A classe CryptoDev possui as funcionalidades PKCS #11 que o desen-
volvedor vai utilizar para construir sua aplicação. Vários métodos de outras classes
serão chamados indiretamente pelo objeto que representa a instância dessa classe.
Uma grande vantagem que essa classe oferece é que o desenvolvedor não
precisa se preocupar com os estados de sessão RO/RW para chamar uma determinada
função, para cada método da API PKCS #11, a CryptoDev se encarrega de definir o
estado de sessão que é preciso para acessar uma determinada função ou objeto.
As funcionalidades principais são:
• getTokenLabels(): consegue os labels dos dispositivos criptográficos conecta-
dos, se a operação foi realizada com sucesso retorna uma lista de labels dos
tokens, senão retorna uma exceção.
• storeCertificate(Certificate certificate): armazena um certificado X509 no to-
ken somente se o dispositivo tiver o correspondente par de chaves pública/privada.
O parâmetro certificate é o certificado que será gravado. Se ocorrer falha retorna
uma exceção, caso contrário, não tem retorno.
• setActualToken(String tokenLabel): define o atual dispositivo criptográfico
que a aplicação se comunicará. O parâmetro tokenLabel é o label que identifica
o token. Não tem retorno se a função foi executada com sucesso, mas retorna
uma exceção se acontecer um erro.
• setLoginCallback(CallbackHandler loginCallback): define o pin do usuário
para poder acessar uma função ou objeto que precisa ter o estado de sessão
68
conectado com o usuário. O parâmetro loginCallback é o pin do usuário. Esta
função não tem retorno.
• actualTokenLabel(): consegue o label do token, na qual identifica o dispositivo
que a aplicação está atualmente se comunicando. Retorna o label do token, se
houver falha retorna uma exceção.
• sign(String privateKeyLabel, InputStream data, SignatureAlgorithm algo-
rithm): assina com a chave privada correspondente do label enviado o hash dos
dados passados. Os parâmetros privateKeyLabel, data e algorithm são: o label
da chave privada, os dados que será tirado o valor de resumo para ser assinado
e o algoritmo de hash desejado para conseguir o resumo dos dados, respecti-
vamente. Se a operação foi realizada com sucesso retorna um array de bytes
representando o valor de assinatura, senão retorna uma exceção.
• generateKeyPair(String keyPairLabel, int keyLength, KeyPairGenerationAl-
gorithm keyPairGenerationAlgorithm): gera o par de chaves pública/privada
no token. Os parâmetros keyPairLabel, keyLength e keyPairGenerationAlgo-
rithm são respectivamente: o label que será definido para as chaves pública/privada,
o tamanho em bits da chave e o algoritmo desejado para a geração do par de
chaves. Esse método não tem retorno se for executado sem erro, porém uma
exceção é retornada em caso de falha.
• getKeyLabels(): consegue os labels das chaves públicas armazenadas no token.
Retorna uma lista de labels se não tiver erro na execução da operação, caso
contrário, retorna uma exceção.
• getPublicKey(String keyLabel): consegue a chave pública correspondente ao
label enviado. O parâmetro keyLabel é o label que identifica a chave pública. Se
a operação for executada com sucesso retorna um objeto chave pública, senão
retorna uma exceção.
• getCertificateLabels(): consegue os labels dos certificados que estão gravados
69
no token. Retorna uma lista de labels se não ocorrer erro durante a execução da
função, caso acontecer uma falha uma exceção será retornada.
• getCertificate(String label): consegue o certificado correspondente ao label de
entrada. O parâmetro label é o identificador do certificado. Se nenhum problema
ocorrer um certificado será retornado, senão retorna uma exceção.
• decrypt(String privateKeyLabel, InputStream data, EncryptionAlgorithm
decryptionMechanism): decifra usando a chave privada correspondente ao la-
bel e utilizando o algoritmo de decifragem enviados os dados de entrada. Os
parâmetros privateKeyLabel, data e decryptionMechanism são respectivamente:
o label que identifica a chave privada, os dados que serão decifrados e o algo-
ritmo de decifragem. Se a operação for executada com sucesso retorna um array
de bytes representando o valor decifrado, senão retorna uma exceção.
Os algoritmos de assinatura que podem ser usados são:
• sha1WithRSA.
• sha256WithRSA.
• sha384WithRSA.
• sha512WithRSA.
O algorimo de par de chaves suportado é:
• RSA_PKCS_KEY_PAIR_GEN.
Para fazer a decifragem está disponível o algoritmo:
• RSA_PKCS.
70
5.3 ModuleHandler
Esta classe é uma representação de um módulo criptográfico. Os métodos
dessa classe não são chamados diretamente pelo desenvolvedor, mas são invocados
indiretamente pelo objeto da classe CryptoDev em alguns métodos usados pelo pro-
gramador que utiliza a biblioteca LibCryptoDev.
Os principais métodos são:
• getInstance(DeviceInfo deviceInfo): consegue uma instância da classe Mod-
uleHandler correspondente ao deviceInfo passado. O parâmetro deviceInfo rep-
resenta a informação de um dispositivo específico. A função retorna uma in-
stância da classe ModuleHandler em caso de sucesso, se tiver falha retorna uma
exceção.
• getTokens(): consegue uma lista de objetos tokens. Se não ocorrer erro retorna
uma lista de objetos tokens, caso contrário retorna uma exceção.
• close(): finaliza o uso do módulo PKCS #11. Se a execução dessa operação
falhar retorna uma exceção, senão não tem retorno.
5.4 Token
A classe token é uma representação de um dispositivo criptográfico. Da
mesma maneira explicada para os métodos da classe ModuleHandler, os métodos da
classe Token são acessados indiretamente através do objeto CryptoDev em algumas
funções acessadas dessa classe pelo desenvolvedor.
As funcionalidades fundamentais dessa classe são:
• openReadOnlySession(): abre uma sessão RO. Retorna uma instância da classe
ReadOnlySession se não ocorrer falha, caso contrário, retorna uma exceção.
• openReadWriteSession(CallbackHandler loginCallback): abre uma sessão
RW. O parâmetro loginCallback é o PIN do usuário. Se a operação for bem
71
sucedida, retorna um objeto da classe ReadWriteSession, senão retorna uma ex-
ceção.
• getTokenLabel(): consegue o label de um determinado token. Retorna o label
do token em caso de sucesso, caso contrário, retorna uma exceção.
• getPkcs11Provider(): consegue o provedor dos serviços criptográficos PKCS
#11. Se nenhum problema ocorrer retorna uma instância da classe Provider,
senão retorna uma exceção.
5.5 ReadOnlySession
As funções da classe ReadOnlySession também são acessadas indireta-
mente pelo desenvolvedor que utiliza a biblioteca LibCryptoDev.
Os métodos essenciais são:
• getPublicKeyLabels(): consegue os labels das chaves públicas do token. Re-
torna uma lista de labels se nenhuma falha ocorrer, caso contrário, retorna um
exceção.
• getPublicKey(String publicKeyLabel): consegue um objeto da classe Pub-
licKey correspondente ao label da chave pública enviado. O parâmetro publicK-
eyLabel é o label da chave pública. Em caso de sucesso, retorna uma instância
da classe PublicKey, senão retorna uma exceção.
• getCertificateLabels(): consegue os labels dos certificados encontrados no to-
ken. Retorna uma lista de labels dos certificados se a operação foi executada sem
erro, caso contrário, retorna uma exceção.
• getCertificate(String label): consegue um objeto da classe Certificate corre-
spondente ao label de entrada. O parâmetro label é o label do certificado. Se não
houver falha retorna uma instância da classe Certificate, mas se tiver erro será
retornada uma exceção.
72
• hasCorrespondendPublicKey(Certificate certificate): verifica se tem a corre-
spondente chave pública do certificado passado. O parâmetro certificate é o cer-
tificado. Retorna true ou false se nenhum problema ocorrer durante a execução
da operação, caso contrário, retorna uma exceção.
• close(): fecha a sessão atual RO. Em caso de erro retorna uma exceção, se a
operação foi executada com sucesso não tem retorno.
5.6 ReadWriteSession
De forma similar à classe ReadOnlySession, os métodos da classe Read-
WriteSession são acessados indiretamente pelo desenvolvedor.
Os métodos principais são:
• getPrivateKeyLabels(): consegue os labels das chaves privadas do token. Re-
torna uma lista de labels das chaves privadas se a função foi bem sucedida, caso
contrário, retorna uma exceção.
• storeCertificate(Certificate certificate): armazena o certificado passado no to-
ken. O parâmetro certificate é o certificado. Se a operação foi executada com
sucesso não tem retorno, na execução com falha retorna uma exceção.
• generateKeyPair(String keyPairLabel, int keyLenght, KeyPairGenerationAl-
gorithm keyPairGenerationAlgorithm): gera o par de chaves pública/privada
no token. Os parâmetros keyPairLabel, keyLenght e keyPairGenerationAlgo-
rithm são respectivamente: o label que será definido para o par de chaves pública/privada,
o tamanho em bits da chave e o algoritmo de geração do par de chaves. Se houver
falha retorna uma exceção, porém não tem retorno na execução sem erro.
• sign(String privateKeyLabel, byte[] encodedMessageDigest, SignatureAl-
gorithm signatureAlgorithm): assina utilizando a chave privada correspon-
dente com o label de entrada os dados enviados. Os parâmetros privateKeyLa-
bel, encodedMessageDigest e signatureAlgorithm são respectivamente: o label
73
da chave privada, os dados que serão assinados e o algoritmo de assinatura. Em
caso de sucesso retorna um array de bytes representando o valor de assinatura,
caso contrário, retorna uma exceção.
• hasCorrespondendPrivateKey(Certificate certificate): verifica se tem a corre-
spondente chave privada do certificado enviado. Se acontecer falha na operação
retorna uma exceção, senão retorna true ou false.
• decrypt(String privateKeyLabel, byte[] encryptedData, Mechanism decryp-
tionMechanism): decifra os dados utilizando a chave privada correspondente
ao label de entrada. Os parâmetros privateKeyLabel, encryptedData e decryp-
tionMechanism são respectivamente: o label da chave privada, os dados que
serão decifrados e o algoritmo de decifragem. Retorna um array de bytes rep-
resentando os valores decifrados se operação foi executada com sucesso, caso
contrário, retorna uma exceção.
74
Figura 5.1: Diagrama de classes
Capítulo 6
Análises de Resultados
Neste capítulo será abordado o processo de testes da interface gráfica GUICryp-
tokiEasyAccess e da biblioteca LibCryptoDev.
6.1 Testes executados
Os dispositivos criptográficos usados para fazer os testes neste trabalho
foram:
• Smart cards da Starkos spk 2.3 e 2.4 FIPS TESTE.
O módulo PKCS #11 usado foi o libaetpkss.so fornecido pelo fabricante
do token. A interface GUICryptokiEasyAccess e a biblioteca LibCryptoDev foram
executadas no sistema operacional Linux usando a distribuição Ubuntu 10.04.
O ideal seria ter um módulo PKCS #11 genérico para ser utilizado em to-
dos os dispositivos criptográficos, mas atualmente a aplicação que vai se comunicar
com o token depende do módulo PKCS #11 do fabricante desse hardware. Desse
modo, as funcionalidades oferecidas por uma aplicação PKCS #11 somente serão bem
sucedidas se a implementação do módulo do fabricante implementar as função que
serão acessadas pela aplicação, para as funções que não são implementadas o erro
CKR_FUNCTION_NOT_SUPPORTED definido no padrão PKCS #11 deveria ser re-
tornado.
76
6.1.1 GUICryptokiEasyAccess
Para realizar os testes na GUICryptokiEasyAccess foram utilizadas as téc-
nicas: caixa-branca e caixa-preta. A técnica caixa-branca foi usada para avaliar o com-
portamento interno da interface gráfica, em tempo de execução as instruções que es-
tavam sendo executadas foram analisadas para avaliar aspectos como: teste de condição,
teste de ciclos, códigos nunca executados. Já a técnica caixa-preta serviu para avaliar
o comportamento externo da GUICryptokiEasyAccess, foram inseridos dados de en-
tradas nas funções da interface gráfica e os resultados obtidos foram analisados para
verificar se operação testada foi executada com sucesso.
Alguns erros foram encontrados, na reinicialização do token foi digitado o
PIN do oficial de segurança diferente do valor que tinha sido definido na inicialização,
de acordo com a documentação PKCS #11 essa operação não deveria ser autorizada,
pois o PIN do oficial de segurança inserido foi diferente do valor armazenado no token,
porém essa função foi completada com sucesso e o valor do PIN do SO (Security
Officer) passou a ser o valor definido na última inicialização do token.
Também ocorreu uma falha ao tentar gerar uma chave secreta do tipo DES3
para ser armazenada no token, o erro CKR_DEVICE_ERROR foi retornado, alguns
erros definidos na Cryptoki são genéricos dificultando saber onde a falha realmente
aconteceu e por isso o usuário não tem como saber o procedimento certo a ser real-
izado caso existir para efetuar a operação com sucesso. Um desses erros genéricos é o
CKR_DEVICE_ERROR, na qual o problema pode ter ocorrido no token e/ou no slot.
É importante mencionar que foi criada com sucesso uma chave DES3 de sessão (esse
objeto vai existir somente enquanto a sessão que foi usada para criá-lo estiver aberta),
utilizando os mesmos valores de entradas usados para criar um chave DES3 do token.
Alguns comportamentos descritos na documentação PKCS #11 foram anal-
isados na executação da GUICryptokiEasyAccess e pode ser observado que estavam
de acordo com o padrão PKCS #11 tais como: na executação de uma operação que
acessa objetos privados, não foi permitido o acesso a esses objetos usando uma sessão
RW sem estar conectada com o usuário normal e na tentativa de conectar o usuário com
77
o PIN incorreto foi retornado o erro CKR_PIN_INCORRECT conforme esperado.
6.1.2 LibCryptoDev
Foi utilizado o framework JUnit 4.0 para realizar os testes automatizados
na biblioteca LibCryptoDev, a técnica caixa-branca com essa ferramenta também foi
usada. A classe de testes criada foi a CryptoDevTest e os métodos pertencentes à classe
CryptoDev foram testados e os resultados obtidos estavam corretos, as funcionalidades
testadas são listadas abaixo:
• getTokenLabels().
• getKeyLabels().
• sign(String privateKeyLabel, InputStream data, SignatureAlgorithm algorithm).
• generateKeyPair(String keyPairLabel, int keyLength, KeyPairGenerationAlgo-
rithm keyPairGenerationAlgorithm).
• storeCertificate(Certificate certificate).
• decrypt(String privateKeyLabel, InputStream data, EncryptionAlgorithm decryp-
tionMechanism).
Capítulo 7
Considerações Finais
O padrão PKCS #11 criado pelo laboratório RSA define uma API indepen-
dente de plataforma para os dispositivos criptográficos, devido a isso uma aplicação
pode se comunicar com diferentes dispositivos (HSM, smart card, token USB) por
meio desta API. As funções definidas na API PKCS #11 abrangem: admistração de
slot e token, administração de objetos e funções criptográficas.
A API PKCS #11 também chamada de Cryptoki (Cryptographic token in-
terface) foi desenvolvida para ser uma interface entre aplicações e todos os tipos de
dispositivos criptográficos, ou seja, a Cryptoki abstrai os detalhes dos dispositivos, e
apresenta para a aplicação um modelo comum do dispositivo criptográfico, por isso a
aplicação não tem que mudar a interface para um tipo diferente de dispositivo.
A interface gráfica GUICryptokiEasyAccess foi desenvolvida para permi-
tir que um usuário utilizá-a para acessar um dispositivo criptográfico e executar as
operações definidas na API PKCS #11. Nesta aplicação foram definidas as categorias
que contém suas respectivas funções para facilitar o acesso a uma determinada função.
A biblioteca LibCryptoDev foi criada para ser utilizada pelos desenvolve-
dores que irão desenvolver suas próprias aplicações PKCS #11. Uma vantagem de
utilizar essa biblioteca é que um programador não precisa ter conhecimentos avança-
dos sobre os conceitos do padrão PKCS #11.
Foram realizados os testes tanto na GUICryptokiEasyAccess quanto na
79
LibCryptoDev. Na interface gráfica alguns erros foram encontrados, já na biblioteca
os testes foram executados com sucessos. É importante lembrar que para as funcional-
idades acessadas na GUICryptokiEasyAccess e LibCryptoDev somente funcionarão se
o módulo PKCS #11 do fabricante do dispositivo implementá-las.
7.1 Trabalhos Futuros
Na interface gráfica GUICryptokiEasyAccess atual, o usuário tem que se-
lecionar o dispositivo criptográfico que deseja acessar, caso tenha mais de um token
reconhecido ao carregar o módulo PKCS #11. Uma mudança poderia ser feita para que
os dispositivos criptográficos reconhecidos possam ser acessados na mesma aplicação,
dessa forma, o usuário pode escolher o token para ser acessado no momento em que
estiver inserindo os dados de entradas para uma função específica e uma das opções de
entradas seria escolher o token, no qual a função vai ser executada.
Outra melhoria na interface gráfica é adicionar novos algoritmos e funções
definidos no padrão PKCS #11 que não são suportados para a primeira versão da in-
terface gráfica.
Para a biblioteca LibCryptoDev pode ser acrescentados novas funcional-
idades e mecanismos definidos na documentação PKCS #11 que estão faltando, essa
melhoria deixará a biblioteca mais completa para um desenvolvedor criar sua aplicação
PKCS #11.
80
Referências
[And 05] André L.B. Cavalcante. Teoria dos Números e Criptografia. Disponível em
<http://www.upis.br/revistavirtual/Cavalcante_%20Teoria%20dos%20N%FAmeros%20e%20
Criptografia_2005_UPIS.pdf>. Acesso em: 08 de julho de 2011.
[CAC 09] CACHIN, C.; CHANDRAN, N. A secure cryptographic token interface. In: COMPUTER
SECURITY FOUNDATIONS SYMPOSIUM, 2009. CSF ’09. 22ND IEEE, 2009. [s.n.],
2009. p.141 –153.
[CLU 03] CLULOW, J. On the security of pkcs #11. In: IN PROCEEDINGS OF THE 5TH
INTERNATIONAL WORSHOP ON CRYPTOGRAPHIC HARDWARE AND
EMBEDDED SYSTEMS (CHES’03), VOLUME 2779 OF LNCS, 2003. Springer-Verlag,
2003. p.411–425.
[dEeP 12] DE ENSINO E PESQUISA, R. N. RNP. Disponível em <http://www.rnp.br>. Acesso
em: 11 de março de 2012.
[dS 08] DE SOUZA, T. C. S. Aspectos Técnicos e Teóricos da Gestão do Ciclo de Vida de
Chaves Criptográficas no OpenHSM. Universidade Federal de Santa Catarina, 2008.
Dissertação de Mestrado.
[dSeC 12] DE SEGURANçA EM COMPUTAçãO, L. ASI-HSM.
https://projetos.labsec.ufsc.br/openhsmd.
[eSdI 12] EM SEGURANçA DA INFORMAçãO, K. S. Kryptus. Disponível em
<http://www.kryptus.com>. Acesso em: 11 de março de 2012.
[FAL 11] FALEIROS, A. C. Notas em Matemática Aplicada. SBMAC - Sociedade Brasileira de
Matemática Aplicada e Computacional, 2011.
[GRO 12] GROUP, T. C. Trusted platform module specifications. Disponível em
<http://www.trustedcomputinggroup.org>. Acesso em: 10 de março de 2012.
82
[IAI 11] IAIK. IAIK PKCS#11 Wrapper. Disponível em
<http://javadoc.iaik.tugraz.at/pkcs11_wrapper/current/index.html>. Acesso em: 28 de
setembro de 2011.
[IBM 11] IBM Alphaworks. PKCS#11 API for Java, by IBM Alphaworks. Disponível em
<http://alphaworks.ibm.com/>. Acesso em: 28 de setembro de 2011.
[IBM 12] IBM. CCA Basic Services Reference and Guide for the IBM 4758 PCI and IBM 4764
PCI-X Cryptographic Coprocessors. Disponível em
<http://www.ibm.com/security/cryptocards/pcicc/library.shtml>. Acesso em: 10 de março
de 2012.
[IET 11a] IETF Tools. Generic Security Service API Version 2. Disponível em
<http://tools.ietf.org/html/rfc2744>. Acesso em: 27 de setembro de 2011.
[IET 11b] IETF Tools. Generic Security Service Application Program Interface Version 2.
Disponível em <http://tools.ietf.org/html/rfc2743>. Acesso em: 27 de setembro de 2011.
[LAB 12] LABSEC. Biblioteca LibCryptoDev. https://projetos.labsec.ufsc.br/libcryptodev.
[PKC 11] PKCS #11 v2.20: Cryptographic Token Interface Standard. Disponível em:
<http://www.rsa.com/rsalabs/node.asp?id=2133>.
[PRO 12] PRONOVA. O Smart Card da Pronova. Disponível em
<http://www.pronova.com.br/solutions/scard2k.php>. Acesso em: 13 de março de 2012.
[SCH 96] SCHNEIER, B. Applied Cryptography: protocols, algorithms, and source code in C.
John Wiley & Sons, 1996.
[STA 08] STALLINGS, W. Criptografia e segurança de redes. Pearson Prentice Hall, 2008.
Apêndice A
Artigo
Uma aplicação para comunicação com dispositivos criptográficos
Paulo H. Morais1, André Bereza Júnior1, Prof. Ricardo F. Custódio1, Dr
1Departamento de Informática e Estatística (INE)Universidade Federal de Santa Catarina (UFSC) – Florianópolis, SC - Brasil
[email protected], [email protected], [email protected]
Abstract. The communication as between applications as between an application and a cryptographic device is performed through an API. An API developed as an interface between applications and cryptographic devices is the PKCS #11 API. It is necessary to have an application that accesses any cryptographic device using the proposed standards. The goal of this paper is to present the PKCS #11 API to communicate with devices that implement cryptographic functions of this API. The application and the library can be used with this standard to ensure interoperability between applications and cryptographic devices.
Resumo. A comunicação tanto entre aplicações quanto entre uma aplicação e um dispositivo criptográfico é realizada através de uma API. Uma API desenvolvida para ser uma interface entre aplicações e dispositivos criptográficos é a API PKCS #11. É necessário existir uma aplicação que acesse qualquer dispositivo criptográfico utilizando padrões propostos. Este artigo tem o intuito de apresentar a API PKCS #11 para comunicação com os dispositivos criptográficos que implementam as funções dessa API. A aplicação e a biblioteca poderão ser utilizadas com esse padrão para garantir a interoperabilidade entre aplicações e dispositivos criptográficos.
1. Introdução
O PKCS #11 é um dos padrões pertencentes aos Padrões de Criptografia de Chave Pública, publicado pelo laboratório RSA que define uma API (Application Programming Interface) independente de plataforma para dispositivos criptográficos, tais como Hardware Security Modules (HSM), smart cards e tokens USB.
Esta API, chamada também de Cryptoki (Cryptographic token interface) foi desenvolvida para ser uma camada de abstração genérica para dispositivos criptográficos.
Dispositivos criptográficos são utilizados em locais como: uma infraestrutura de chaves públicas, setor bancário. A utilização dos dispositivos deve ser padronizada para garantir a interoperabilidade das aplicações que são desenvolvidas para se comunicar com esses dispositivos. Os dispositivos são importantes, pois armazenam material sensível e valioso para as instituições que o utilizam .
Fabricantes de dispositivos criptográficos criam dispositivos com suporte a padrões em especial o PKCS #11 para acessar as funções criptográficas e também várias aplicações são implementadas para acessá-los.
Para manter a interoperabilidade entre aplicações e dispositivos criptográficos é
necessário que eles sigam a documentação do padrão utilizado. Desse modo, podem ser desenvolvidas diversas aplicações e dispositivos criptográficos com implementações diferentes e com a mesma interface de utilização de funções, permitindo o acesso da aplicação para qualquer dispositivo criptográfico.
O padrão PKCS #11 está cada vez sendo mais utilizado nos dispositivos criptográficos, porém as aplicações desenvolvidas para se comunicarem com esses dispositivos disponibilizam um número pequeno das funções disponíveis dessa API .
O objetivo deste artigo é apresentar uma aplicação e uma biblioteca para utilizar funções do padrão PKCS #11. A aplicação e a biblioteca são compatíveis com qualquer dispositivo criptográfico que implementa as funções da API PKCS #11.
A aplicação PKCS #11 é uma alternativa para que os usuários tenham a possibilidade de acessar os dispositivos criptográficos com uma aplicação que ofereça uma grande parte das funções definida na Cryptoki. Além disso, a aplicação pode ser usada para testar e diagnosticar os dispositivos criptográficos e ser capaz de operar com diferentes módulos PKCS #11.
Faltam aplicações que ofereçam estes suportes genéricos. A aplicação PKCS #11 também pode ser usada como uma ferramenta para encontrar limitações, problemas na implementação do padrão PKCS #11 dos dispositivos criptográficos acessados.
A biblioteca permite que novas aplicações PKCS #11 sejam desenvolvidas. Isso permite que o usuário tenha uma maior flexibilidade para escolher uma aplicação e dessa forma ele não ficará preso a uma determinada aplicação. Ademais, a biblioteca evita que os desenvolvedores tenham que se especializar em uma API de baixo nível, concentrando o conhecimento em nível de operações criptográficas.
Uma das limitações do trabalho está em não existir uma implementação genérica de todas as funções PKCS #11. A aplicação desenvolvida deve utilizar o módulo (implementação da API PKCS #11) específico do fabricante do dispositivo criptográfico e somente executar as funções suportadas de cada implementação.
2. Uma Introdução para PKCS #11
Cryptoki foi concebido para ser uma interface de programação de baixo nível que abstrai os detalhes dos dispositivos, e apresenta para a aplicação um modelo comum do dispositivo criptográfico, chamado um “token criptográfico” (ou simplesmente “token”), desse modo a aplicação não tem que mudar a interface para um tipo diferente de dispositivo.
Cryptoki fornece uma interface para um ou mais dispositivos criptográficos que estão ativos no sistema através de um número de “slots”. Cada slot, que corresponde para um leitor físico ou outra interface do dispositivo, pode conter um token. Um token está tipicamente “presente no slot” quando um dispositivo criptográfico está presente no leitor.
A visão lógica de um token é um dispositivo que armazena objetos e pode executar funções criptográficas. Cryptoki define três classes de objetos: dado, certificado e chave. Um objeto dado é definido por uma aplicação. Um objeto certificado armazena um certificado. Um objeto chave armazena uma chave criptográfica. A chave pode ser um chave pública, uma chave privada, ou uma chave secreta, cada um desses tipos de chaves tem subtipos para uso em algoritmos
específicos. Um token pode criar, manipular, procurar e destruir objetos. Ele pode também executar funções criptográficas com objetos.
Cryptoki reconhece dois tipos de usuário do token. Um tipo é o Security Officer (oficial de segurança). O outro tipo é o usuário normal. Somente o usuário normal tem permissão para acessar os objetos privados do token, e estes acessos são garantidos somente depois que o usuário normal se autentica. Alguns tokens podem também requerer que o usuário seja autenticado antes de qualquer função criptográfica executado no token, se envolvem ou não objetos privados.
O papel do SO (Security Officer) é inicializar um token e definir o PIN (Personal Identification Number) do usuário normal (ou de outra maneira definir por algum método fora do escopo da Cryptoki, como o usuário normal pode ser autenticado), e possivelmente manipular alguns objetos públicos. O usuário normal pode conectar com o token, somente depois que o SO definir seu PIN.
Cryptoki requer que uma aplicação abre uma ou mais sessões com um token para ganhar acesso para o objetos do token e funções. Uma sessão fornece uma conexão lógica entre a aplicação e o token. Uma sessão pode ser read/write (R/W) ou read only (R/O). Sessão read/write (R/W) e sessão read only (R/O) referem se para acessar objetos do token, não para acessar objetos de sessão. Em ambos os tipos de sessão, uma aplicação pode criar, ler, escrever e destruir objetos de sessão, e ler objetos do token. Entretanto, somente sessão read/write (R/W) pode uma aplicação criar, modificar e destruir objetos do token.
3. GUICryptokiEasyAccess
Nesta seção será mostrada a interface gráfica que foi desenvolvida utilizando a linguagem de programação Java e o wrapper PKCS #11 da IAIK (Institute for Applied Information Processing and Communication of the Graz University of Technology) que fornece um mapeamento direto das estruturas de dados definido na Cryptoki através da linguagem de programação C para estruturas de dados em Java. Esta aplicação foi nomeada como GUICryptokiEasyAccess que é uma abreviação para graphical user interface for cryptoki easy access.
Apesar da GUICryptokiEasyAccess ser projetada para o usuário que tem conhecimento dos conceitos básicos da documentação PKCS #11, uma pessoa que não tenha conhecimento desse padrão poderá utilizar muitas funcionalidades desta interface, devido a sua usabilidade, na qual permite que muitas operações sejam intuitivas para o usuário executá-las.
O usuário utiliza a GUICryptokiEasyAccess para fazer chamadas das funções da API PKCS #11, essas funções são executados pelo dispositivo criptográfico acessado. Este cenário pode ser visto na figura 1.
Ao executar a GUICryptokiEasyAccess, é pedido para o usuário inserir o caminho do módulo PKCS #11. Após o campo módulo ser preenchido e a biblioteca for carregada, se tiver mais do que um dispositivo criptográfico conectado no computador, uma janela será exibida para que o usuário selecione um token para ser acessado. Depois que o usuário escolheu o token, a tela principal da interface gráfica PKCS #11 é mostrado. Caso tenha somente um dispositivo criptográfico, a tela principal da GUICryptokiEasyAccess é exibida direta.
Figure 1. Modelo de acesso para as funções da Cryptoki
3.1. Tela Principal
A tela principal da GUICryptokiEasyAccess consiste de uma barra de menu na parte superior com as opções: Token e Help, no lado esquerdo são mostradas as categorias. Cada categoria tem suas respectivas funções para serem acessadas pelo usuário, essas funções serão detalhadas nas próximas seções deste capítulo.
Na região central da tela são exibidas as operações da categoria escolhida, por padrão quando a tela principal é visualizada pela primeira vez, mostra na região central os serviços da categoria de informações. A figura 2 mostra a tela principal da interface gráfica.
Figure 2. Tela Principal da GUICriptokiEasyAccess
3.2. Categoria de Informações
As funções disponíveis são: informações da Cryptoki, Slot, Token e Mechanism, para exibi-las precisa selecionar a opção desejada e clicar no botão Mostrar, após feito isso,
serão mostradas as informações específicas do item escolhido.
3.3. Categoria de Administração do Token
As funcionalidades dessa categoria são: inicialização do Token, alterar PIN e inicializar o PIN do usuário normal. O oficial de segurança utiliza essa sessão para cumprir seu papel que é inicializar o token e definir o PIN do usuário normal, poderia se dizer que essas são as primeiras funções executadas em um dispositivo criptográfico.
3.4. Categoria de Administração de Chaves
Nesta categoria, é possível criar os tipos de objetos: chave secreta e/ou par de chaves pública/privada. As chaves criadas podem ser usadas para realizar operações criptográficas, como exemplo, o usuário pode usar sua chave privada para assinar um documento digital.
3.5. Categoria de Administração de Sessões
Todas operações relacionadas com sessão estão nessa categoria, suas funcionalidades são: conseguir informações, abrir sessão RW/RO, fechar sessão, fechar todas sessões, conectar e desconectar um usuário (usuário normal/ oficial de segurança).
Um token tem um número limitado de sessões que podem ser abertas conforme o padrão PKCS #11, na aplicação GUICryptokiEasyAccess o número de sessões abertas se limita a dois, ou seja, pode abrir uma sessão RW e uma sessão RO somente, quando um tipo de sessão já está aberta e o usuário tenta abrir essa sessão, é mostrada uma mensagem informando que a sessão já existe.
3.6. Categoria de Administração de Objetos
Nesta categoria, o usuário pode procurar, conseguir informações e deletar objetos do token ou de sessão do tipo: chave pública, chave privada, certificado e chave secreta.
Lembrando que a sessão deve estar no estado que permita o acesso para o tipo de objeto que o usuário deseja encontrar, por exemplo, para objetos do tipo privado, a sessão deve estar no estado de usuário para poder acessá-los, caso contrário, não terá acesso, somente depois que o usuário se conectar é que a sessão vai poder acessar os objetos privados.
3.7. Categoria função de resumo
Na categoria função de resumo, pode-se tirar o hash de um arquivo, utilizando um algoritmo de hash desejado como: SHA1, SHA256, entre outros.
3.8. Categoria importar certificado
Nesta seção, o usuário pode importar um certificado no padrão X509, o objeto importado pode ser do token ou de sessão.
3.9. Categoria operações criptográficas
Esta categoria é responsável para oferecer as seguintes operações criptográficas: assinar, verificar assinatura, cifrar e decifrar. Os tipos de chaves que podem ser usadas são: pública, privada e secreta.
3.10. Categoria alterar atributo
Na última categoria, o usuário pode modificar o valor de um atributo específico de objetos como: chave pública, chave privada ou chave secreta.
4. Biblioteca LibCryptoDev
A LibCryptoDev também foi desenvolvida utilizando a linguagem de programação Java e o wrapper PKCS #11 da IAIK com o objetivo de ser uma biblioteca para ser usada por desenvolvedores de software que utilizam a linguagem de programação Java.
A sua estrutura foi construída para facilitar o desenvolvimento de uma aplicação que se comunica com o dispositivo criptográfico através da API PKCS #11. O intuito dessa estrutura é também permiter que programadores que não tenham conhecimento avançado do padrão PKCS #11 possam criar aplicações PKCS #11 por meio desta biblioteca.
As principais classes da LibCryptoDev são: ListUsb, CryptoDev, ModuleHandler, Token, ReadOnlySession e ReadWriteSession. O diagrama de classes da LibCryptoDev é mostrado na figura 3.
Figure 3. Diagrama de classes da LibCryptoDev
4.1. ListUsb
A classe ListUsb foi implementada para reconhecer ''automaticamente'' os tokens presentes sem a necessidade do desenvolvedor ter que informar o módulo PKCS #11 diretamente. Este processo é feito utilizando o arquivo criado supported-devices.xml que contém os módulos registrados e permite que os dispositivos criptográficos, no qual usam um dos módulos cadastrados sejam reconhecidos.
4.2. CryptoDev
A classe CryptoDev possui as funcionalidades PKCS #11 que o desenvolvedor vai utilizá-las para construir sua aplicação. Vários métodos de outras classes serão
chamados indiretamente pelo objeto que representa a instância dessa classe.
Uma grande vantagem que essa classe oferece é que o desenvolvedor não precisa se preocupar com os estados de sessão RO/RW para chamar uma determinada função, para cada método da API PKCS #11, a CryptoDev se encarrega de definir o estado de sessão que é preciso para acessar uma determinada função ou objeto.
4.3. ModuleHandler
Esta classe é uma representação de um módulo criptográfico. Os métodos dessa classe não são chamados diretamente pelo desenvolvedor, mas são invocados indiretamente pelo objeto da classe CryptoDev em alguns métodos usados pelo programador que utiliza a biblioteca LibCryptoDev.
4.4. Token
A classe token é uma representação de um dispositivo criptográfico. Da mesma maneira explicada para os métodos da classe ModuleHandler, os métodos da classe Token são acessados indiretamente através do objeto CryptoDev em algumas funções acessadas dessa classe pelo desenvolvedor.
4.5. ReadOnlySession e ReadWriteSession
Os métodos das classes ReadOnlySession e ReadWriteSession são acessados indiretamente pelo desenvolvedor que utiliza a biblioteca LibCryptoDev.
5. Análises de Resultados
Nesta seção será abordado o processo de testes da interface gráfica GUICryptokiEasyAccess e da biblioteca LibCryptoDev.
5.1. Testes executados
Os dispositivos criptográficos usados para fazer os testes neste trabalho foram: Smart cards da Starkos spk 2.3 e 2.4 FIPS TESTE.
O módulo PKCS #11 usado foi o libaetpkss.so fornecido pelo fabricante do token. A interface GUICryptokiEasyAccess e a biblioteca LibCryptoDev foram executadas no sistema operacional Linux usando a distribuição Ubuntu 10.04.
5.2. GUICryptokiEasyAccess
Para realizar os testes na GUICryptokiEasyAccess foram utilizadas as técnicas: caixa-branca e caixa-preta.
A técnica caixa-branca foi usada para avaliar o comportamento interno da interface gráfica, em tempo de execução as instruções que estavam sendo executadas foram analisadas para avaliar aspectos como: teste de condição, teste de ciclos, códigos nunca executados. Já a técnica caixa-preta serviu para avaliar o comportamento externo da GUICryptokiEasyAccess, foram inseridos dados de entradas nas funções da interface gráfica e os resultados obtidos foram analisados para verificar se operação testada foi executada com sucesso.
5.3. LibCryptoDev
Foi utilizado o framework JUnit 4.0 para realizar os testes automatizados na biblioteca
LibCryptoDev, a técnica caixa-branca com essa ferramenta também foi usada. A classe de testes criada foi a CryptoDevTest e os métodos pertencentes à classe CryptoDev foram testados e os resultados obtidos estavam corretos de acordo com as definições do padrão PKCS #11.
6. Considerações Finais
O padrão PKCS #11 criado pelo laboratório RSA define uma API independente de plataforma para os dispositivos criptográficos, devido a isso uma aplicação pode se comunicar com diferentes dispositivos (HSM, smart card, token USB) por meio desta API. As funções definidas na API PKCS #11 abrangem: admistração de slot e token, administração de objetos e funções criptográficas.
A interface gráfica GUICryptokiEasyAccess foi desenvolvida para permitir que um usuário utilizá-a para acessar um dispositivo criptográfico e executar as operações definidas na API PKCS #11. Nesta aplicação foram definidas as categorias que contém suas respectivas funções para facilitar o acesso a uma determinada função.
A biblioteca LibCryptoDev foi criada para ser utilizada pelos desenvolvedores que irão desenvolver suas próprias aplicações PKCS #11. Uma vantagem de utilizar essa biblioteca é que um programador não precisa ter conhecimentos avançados sobre os conceitos do padrão PKCS #11.
É importante lembrar que para as funcionalidades acessadas na GUICryptokiEasyAccess e LibCryptoDev somente funcionarão se o módulo PKCS #11 do fabricante do dispositivo implementá-las.
7. Referências
RSA Laboratories (2004) “PKCS #11 v.2.20: Cryptographic Token Interface Standard”, http://www.rsa.com/rsalabs/node.asp?id=2133, Junho.
IAIK (2011) “IAIK PKCS #11Wrapper”, http://javadoc.iaik.tugraz.at/pkcs11_wrapper/current/index.html, Novembro.