terça-feira, novembro 06, 2012

Desenvolvendo para o Android: Assinando a Aplicação

O sistema Android exige que as aplicações sejam assinadas digitalmente. Sem isto, elas não poderão ser instaladas ou executadas. É uma pequena medida de segurança, que às vezes se torna um pequeno aborrecimento para o desenvolvedor.

Assinando uma Aplicação

A assinatura da aplicação é feita através de um aplicativo padrão do JDK, o Jarsigner. Para isto você precisa de um certificado digital, armazenado em um arquivo .keyfile. Este certificado pode ser gerado por você mesmo (um certificado self signed), usando um outro aplicativo do JDK, o Keytool.

O certificado possui um alias (apelido) que é usado para fazer a assinatura e uma validade. Duas senhas são envolvidas na sua criação e uso: a storepass (que garante a integridade do certificado) e a keypass (que protege a chave privada).

No final do post você tem os links para a documentação da Oracle para estes aplicativos.

Assinando no Modo Debug

Quando você cria um novo projeto Android no Eclipse, o padrão é ser gerada a versão debug. Neste modo as coisas são bem automáticas e você nem percebe que a aplicação está sendo assinada (até ter problemas, ver adiante).

Na primeira compilação do primeiro projeto, é criado automaticamente um certificado. Ele é guardado na sua pasta de usuário, no arquivo debug.keyfilse. No modo debug, a sua aplicação é automaticamente assinada com este certificado, permitindo a sua instalação e execução tanto no emulador como em dispositivos.

Tudo muito bom, tudo muito bem, até que o seu certificado chega ao primeiro aniversário. O certificado de debug é criado com uma validade de 365 dias. Quando ele expira, não pode mais ser usado para assinar e as aplicações assinadas anteriormente com ele não podem mais ser instaladas (mas ainda podem ser executadas). Quando o Eclipse tenta gerar uma aplicação em modo debug e o certificado está vencido, você recebe o seguinte erro:

Error generating final archive: Debug certificate expired

Existem duas formas de corrigir este problemas:
  • Forçar a geração automática de um novo certificado: basta apagar o arquivo debug.keystore. No Windows este arquivo está no diretório .android do usuário.
  • Recriar manualmente o certificado com uma validade maior.
O comando para criar manualmente o certificado com validade de 14000 dias é:

keytool -genkey -v -keystore debug.keystore -alias androiddebugkey
-storepass android -keypass android -keyalg RSA -validity 14000




Neste comando são usados os valores padrão do Android para o alias e senhas.

Assinando no Modo Release

Quando a sua aplicação está pronta para ser exposta ao mundo, é hora de gerar a versão release. A versão release não deve ser assinada com o certificado de debug. O ideal é você usar um certificado emitido por uma entidade certificadora, mas provavelmente você vai usar um certificado assinado por você mesmo (usando o Keytool).

Um exemplo de comando para criar o seu certificado:

keytool -genkey -v -keystore meucertificado.keystore
-alias dqsoft -keyalg RSA -keysize 2048 -validity 10000


Como as senhas não são fornecidas na linha de comando elas serão solicitadas pelo keytool. Não esqueça a senha que você usar!


Infelizmente não há um procedimento automático para gerar a versão release. Novamente temos duas opções:
  • Usar o "Export Wizard" acrescentado ao Eclipse pelo plugin ADT: selecione File Export e navege pelas telas do wizard.
  • Fazer o processo manualmente:
    • Compile a aplicação em modo release e sem assinatura (não dá para assinar uma aplicação que já esteja assinada):  Android Tools > Export Unsigned Application Package.
    • Assine a aplicação 
    • Alinhe o pacote
Para assinar manualmente a aplicação você deve usar um comando como:

jarsigner --sigalg MD5withRSA -digestalg SHA1 -keystore meucertificado.keystore
minha_app_u.apk dqsoft


Os parâmetros sigalg e digestalg são necessários devido a mudanças no default do jarsigner entre as versões do Java.

O alinhamento do pacote é feito pelo  comando:

zipalign -v 4 minha_app_u.apk minha_app.apk

Note que este comando requer que a saída tenha um nome diferente da entrada.


Referências

A explicação oficial sobre a assinatura de aplicações:
http://developer.android.com/tools/publishing/app-signing.html

Recriação manual do certificado de debug:
http://stackoverflow.com/questions/2194808/debug-certificate-expired-error-in-eclipse-android-plugins

Documentação da Oracle para o jarsigner
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/jarsigner.html

Documentação da Oracle para o keytool:
http://docs.oracle.com/javase/6/docs/technotes/tools/windows/keytool.html

Nenhum comentário: