Provider JCE

Bom dia pessoal,

Estou tentando desenvolvendo um Provider JCE e estou com um problema ao capturar a instancia de um Cipher. Consigo instanciar um objeto de assinatura mas quando tento instanciar um cipher recebo a seguinte exceção

Exception in thread “main” java.lang.SecurityException: JCE cannot authenticate the provider ProviderTeste
at javax.crypto.Cipher.getInstance(DashoA12275)
at javax.crypto.Cipher.getInstance(DashoA12275)
at providerteste.Teste.main(Teste.java:22)
Caused by: java.lang.SecurityException: Cannot verify jar:file:/C:/Desenvolvimento/workspace/ProviderTeste/bin/!/
at javax.crypto.SunJCE_d.b(DashoA12275)
at javax.crypto.SunJCE_d.a(DashoA12275)
at javax.crypto.SunJCE_d.a(DashoA12275)
at javax.crypto.SunJCE_b.b(DashoA12275)
at javax.crypto.SunJCE_b.a(DashoA12275)
… 3 more
Caused by: java.security.PrivilegedActionException: java.util.zip.ZipException: Acesso negado
at java.security.AccessController.doPrivileged(Native Method)
… 8 more
Caused by: java.util.zip.ZipException: Acesso negado
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.(ZipFile.java:203)
at java.util.jar.JarFile.(JarFile.java:132)
at java.util.jar.JarFile.(JarFile.java:70)
at sun.net.www.protocol.jar.URLJarFile.(URLJarFile.java:56)
at sun.net.www.protocol.jar.URLJarFile.getJarFile(URLJarFile.java:41)
at sun.net.www.protocol.jar.JarFileFactory.get(JarFileFactory.java:63)
at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:102)
at sun.net.www.protocol.jar.JarURLConnection.getJarFile(JarURLConnection.java:69)
at javax.crypto.SunJCE_e.run(DashoA12275)
… 9 more

Obrigado
Arturo Garcia

Para desenvolver um provider, acho que ele deve ser assinado de alguma maneira. É melhor consultar a documentação da Sun para ver o que deve ser feito (acho que você contacta a Sun, e eles emitem um certificado para você que permite a você assinar o JAR do seu JCE Provider. É questão de olhar a documentação).

[quote=thingol]Para desenvolver um provider, acho que ele deve ser assinado de alguma maneira. É melhor consultar a documentação da Sun para ver o que deve ser feito (acho que você contacta a Sun, e eles emitem um certificado para você que permite a você assinar o JAR do seu JCE Provider. É questão de olhar a documentação).
[/quote]

http://java.sun.com/products/jce/doc/guide/HowToImplAProvider.html#Step%205
É exatamente isto que o thingol falou: gera as chaves, manda o CSR para a Sun que eles enviam um certificado para assinar o seu jar. Eu já pedi um destes certificados uma vez. Para JDK 1.4 e 5.0 é obrigatório fazer isto.

Mas tipo…
Ainda estou desenvolvendo o provider, esse erro ocorre quando estou debugando.
Não é possível debugar um provider então?
E pq consigo pegar um objeto de assinatura?

O problema está acontecendo especificamente com Ciphers.

[quote=Arturo]Ainda estou desenvolvendo o provider, esse erro ocorre quando estou debugando.
Não é possível debugar um provider então?[/quote]

Para acessar um algoritmo de criptografia a JVM faz uma verificação se o provider está assinado. Acho que debugar um código de um provider vai exigir que o mesmo esteja assinado. Ou seja, vai ter que gerar um jar e assiná-lo.

[quote=Arturo]E pq consigo pegar um objeto de assinatura?
O problema está acontecendo especificamente com Ciphers.[/quote]

Você também implementou os algoritmos de assinatura (hash e algum algoritmo assimétrico)? Se você usou MD5/SHA-1 + RSA/DSA, você provavelmente usou o provider da Sun.

Cara … Implementei de certo modo.
Esse provider que estou tentando desenvolver é baseado no wrapper da IAIK. Portanto tudo que é preciso usar a chave privada eu delego à sessão do token

[quote=Arturo]Cara … Implementei de certo modo.
Esse provider que estou tentando desenvolver é baseado no wrapper da IAIK. Portanto tudo que é preciso usar a chave privada eu delego à sessão do token[/quote]

Não sei como funciona o provider da IAIK (lembro de ter testado um provider com este nome a uns 6 anos atrás). Este token é um Smart Card ou HSM, ou apenas armazena chaves? No caso de Smart Card ou HSM, o algoritmo assimétrico é via “hardware”.

Este seu “… de certo modo…” ficou estranho. Você implementou RSA ou outro algoritmo assimétrico? Se não implementou, então ou está usando o da Sun ou o do IAIK (que provavelmente é assinado).

[Editado]
Para entender como funciona a verificação de assinatura de provider pela JVM, de uma olhadinha neste link
[/Editado]

[quote=oyama]Você implementou RSA ou outro algoritmo assimétrico? Se não implementou, então ou está usando o da Sun ou o do IAIK (que provavelmente é assinado).
[/quote]

Sim na prática estou usando a implementadão do wrapper da IAIK (que é executada no hardware)

Curte só o trecho de código das classes de assinatura.

Na classe concreta SHA1RSASig que herda da classe abstrata de assinatura

	protected Digest doGetDigest() {
		return new SHA1Digest();
	}

no método engineSign na classe abstrata de assinatura que herda de SignatureSpi

	byte[] b = null;
	byte[] dig = null;
	try {
		dig = new byte[getDigest().getDigestSize()];
		getDigest().doFinal(dig, 0);
		
		//Esse session é um objeto de sessão do token (smartcard)
		//toda operação que usa a chave prevada só pode ser executada pelo token
		Session s = getSession((Storage) prKey);
		s.signInit(getDefaultMechanism(),(Key) prKey);
		b = getSession((Storage) prKey).sign(derEncode(dig));
	} catch (TokenException e) {
		throw new SignatureException(e);
	} catch (IOException e) {
		throw new SignatureException(e);
	}
	return b;

enfim… é isso.

Já fiz a requisição do certificado de assinatura da Sun (já que vou precisar de qualquer modo mesmo)

Obrigado pela ajuda