
É hora de demonstrar como a estação de trabalho criptográfica baseada em
padrões de chave pública
cryptoarmpkcs funciona em uma das plataformas móveis, a saber, o Android.
O conceito estabelecido durante o desenvolvimento do utilitário cryptoarmpkcs é que o usuário deve experimentar um mínimo de inconveniência ao criar e verificar uma assinatura eletrônica. É por isso que propomos o uso
de tokens criptográficos
PKCS # 11 e / ou contêineres
PKCS # 12 como meio-chave para um certificado pessoal. Devo dizer que o uso do PKCS # 12 em muitos casos é quase o único possível, por exemplo, quando os tokens do PKCS # 11 não são suportados para determinadas plataformas.
Por isso, decidimos começar a portar o utilitário cryptoarmpkcs para a plataforma Android com suporte para contêineres seguros PKCS # 12.
Imediatamente, observamos que, como o projeto foi realizado nas plataformas C e Tcl / Tk, a transferência não causou dificuldades fundamentais. Isso foi possível graças à tecnologia
Androwish . Não houve problemas com a implantação e a
configuração do ambiente (meu ambiente de trabalho é Linux - Mageia-7.0). Darei a você apenas um script para implantar as Ferramentas de Linha de Comando do Android (sdk-tools-linux-xxxx.zip):
#!/bin/sh if [ $# -ne 1 ] then echo "./InstallAndroidSDK.sh <sdk-tools-linux-xxxxxxxx.zip>" echo " 1" exit 1 fi if [ ! -f $1 ] then echo "./InstallAndroidSDK.sh <sdk-tools-linux-xxxxxxxx.zip>" echo " $1 " exit 1 fi # SDK-TOOLS tools #unzip sdk-tools-linux-4333796.zip unzip $1 # android-sdk-linux mkdir android-sdk-linux # tools android-sdk-linux mv tools android-sdk-linux cd android-sdk-linux/tools/bin ./sdkmanager "platform-tools" "platforms;android-29"
O mais notável é que o ambiente androwish inclui dois intérpretes, undrowish-xxx e vanillawish-xxx, cuja composição é completamente idêntica à balalaica (pacotes) que na verdade fazem parte do andrewow. A diferença entre undrowish e vanillawish é que no vanillawish o back-end é baseado no tipo SDL / AGG / freet:

A presença desses dois utilitários permite que você desenvolva um aplicativo sem usar o próprio Android e seu emulador com a máxima aproximação ao dispositivo real. Antes de tudo, é claro, undroidwish-xxx.
O próprio pacote Android personalizado foi criado no ambiente AWSDK. A árvore do seu projeto deve ser movida e a pasta ~ / AWSDK / assets / app. Nesse caso, o módulo principal do seu projeto deve ser renomeado para main.tcl. Se você usar balalaikas adicionais com bibliotecas dinâmicas, as bibliotecas deverão ser colocadas nas pastas ~ / AWSDK / libs / x86 para o emulador e ~ / AWSDK / libs / armeabi para o dispositivo real.
Depois disso, basta executar o comando:
$wish ~/AWSDK/tools/bones
e siga as instruções dela:

O pacote apk coletado estará na pasta ~ / AWSDK / build / outputs / apk.
Se você tiver um dispositivo ou emulador real conectado, o pacote poderá ser instalado imediatamente.
Nesse caso, o dispositivo real deve estar no modo de depuração.
Mas voltando ao aplicativo em si. O que tinha que ser mudado nele.
Naturalmente, primeiro, as alterações estão relacionadas ao tamanho da tela. Eu tive que redesenhar a principal (janela inicial). Como resultado, em vez de uma única janela em um computador comum:

Apareceram três janelas no Android:

A primeira janela é informativa. Convencionalmente, é dividido em várias partes. A primeira parte, localizada na parte superior, contém o nome do utilitário e seu logotipo.
Em seguida, vem o logotipo do fabricante, a ajuda de informações e três botões para completar a página.
A página é gravada usando o componente de tela. Existem dois tipos de botões na página: um na forma de um retângulo translúcido (meio) e os outros dois na forma de um retângulo arredondado. Para criar botões com cantos arredondados,
foi utilizado o tkpath "balalaica". Pessoalmente, essa balalaica causou uma impressão muito boa em mim. Naturalmente, ao trabalhar com telas, a maior parte do código é geometria. A seguir está o script create_titul_page.tcl para criar a primeira página do aplicativo. Todo mundo pode editá-lo para se adequar à sua visão.
Script create_titul_page.tcl package require Tk package require tkpath 0.3.0 global mydir set mydir [file dirname [info script]]
Para executar este script, use um dos utilitários undroidwish ou vanillawish:
$ /usr/local/bin64/undroidwish-e5dc71ed9d-linux64 create_titul_page.tcl
ou
$/usr/local/bin64/vanillawish-e5dc71ed9d-linux64 create_titul_page.tcl
O resultado é mostrado na primeira captura de tela.
A segunda página lista a funcionalidade suportada pelo utilitário cryptoarmpkcs-A. Cada linha é um botão; quando clicada, uma página funcional será exibida. A geometria dos botões nesta página é determinada pela fonte usada. A seguir, o script create_page_functions.tcl para criar a segunda página / funcional do aplicativo. Todos também podem editá-lo para suas funções.
Script create_page_functions.tcl package require Tk package require tkpath 0.3.0 global mydir set mydir [file dirname [info script]] #/ ( - ) proc scaleImage {im xfactor {yfactor 0}} { set mode -subsample if {$xfactor>=0 && $yfactor>=0} { set mode -zoom } else { set xfactor [expr $xfactor * -1] } if {$yfactor == 0} {set yfactor $xfactor} set t [image create photo] $t copy $im $im blank $im copy $t -shrink $mode $xfactor $yfactor image delete $t } proc createtile {w backg} { image create photo tiled tiled copy $backg -to 0 0 $::scrwidth $::scrheight -shrink $backg copy tiled image delete tiled # $w create image 0 0 \ -image $backg \ -anchor nw } proc butCliked {num fr} { pack forget .fr1 set ::tekFrfunc $fr pack $fr -side top -anchor center -expand 1 -fill both -side top -padx 0 -pady 0 tk_dialog .dialog1 "Dear user:" "Button $num was clicked\nFr=$fr" info 0 OK } proc butImg {img} { tk_messageBox -title "" -icon info -message " =$img" -detail "::screenwidth=$::scrwidth\n::screenheight=$::scrheight" -parent . if {$img == "exit"} { set answer [tk_dialog .dialog2 " " " \n ?" question 0 "" "" ] if {$answer == 0} { exit } } } proc butReturn {} { pack forget $::tekFrfunc pack .fr1 -side top -anchor center -expand 1 -fill both -side top -padx 0 -pady 0 # tk_dialog .dialog1 "Dear user:" "Button $num was clicked\nFr=$fr" info 0 OK } proc page_func {fr tile titul functions} { # upvar $functions but # if {$::typetlf} { set feFONT_button "-family {Roboto} -size 9 -weight bold -slant roman" set widl 10 } else { set feFONT_button "-family {Arial} -size 12 -weight bold -slant roman" set widl 5 } catch {font delete fontTEMP_drawer} eval font create fontTEMP_drawer $feFONT_button # set drawerCNT 0 set strMaxWidthPx 15 set Ndrawers [expr {[array size but] - 1}] while { $drawerCNT <= $Ndrawers } { set strWidthPx [font measure fontTEMP_drawer "$but($drawerCNT)"] if { $strWidthPx > $strMaxWidthPx } { set strMaxWidthPx $strWidthPx } incr drawerCNT } set drawerWidthPx [expr $strMaxWidthPx + 10] set xxx [expr {($::::scrwidth - $drawerWidthPx) / 2}] if {$fr != ".fr1"} { set hret [expr $::scrheight / 4] } else { set hret $::scrheight } set hret [expr $::scrheight / 4] tkp::canvas $fr.can -borderwidth 0 -height $hret -width $::scrwidth -relief flat # createtile "$fr.can" $tile pack $fr.can -anchor center -expand 1 -fill both -side top -padx 0 -pady 0 if {$titul != "" } { set allfunc $titul catch {font delete fontTEMP_titul} set font_titul "-family {Roboto Condensed Medium} -size 15" eval font create fontTEMP_titul $font_titul set funcWidthPx [font measure fontTEMP_titul "$allfunc"] set dlx [expr {($::::scrwidth - $funcWidthPx) / 2}] $fr.can create text [expr $dlx + 6] [expr {6 + 6}] -anchor nw -text "$allfunc" -fill black -font fontTEMP_titul $fr.can create text $dlx 6 -anchor nw -text "$allfunc" -fill white -font fontTEMP_titul -tag id_text0 set blogo [$fr.can bbox id_text0] set boxbut [expr ([lindex $blogo 3] + 6 + 6)] } else { set boxbut [expr 6 + 6] } # #. # set BDwidth_canvas 0 set maxTextHeightPx [font metrics fontTEMP_drawer -linespace] set maxTextHeightPx [expr {$maxTextHeightPx + ( $maxTextHeightPx / 2)}] set drawerHeightPx $maxTextHeightPx set xLocTextPx [expr {($::::scrwidth - $drawerWidthPx) / 2}] set yLocTextPx [expr $BDwidth_canvas + ($drawerHeightPx / 2) + $boxbut] set canvasHeightPx [expr $Ndrawers * $drawerHeightPx] set drawerCNT 0 set Ndrawers [expr {[array size but] - 1}] while { $drawerCNT <= $Ndrawers } { set yLineLocPx [ expr (( $drawerCNT ) * $drawerHeightPx + $boxbut)] # $fr.can create line \ $xLocTextPx $yLineLocPx \ [expr $drawerWidthPx + $xLocTextPx] $yLineLocPx \ -fill "#a0a0a0" -width $widl $fr.can create text [expr $xLocTextPx + 5] $yLocTextPx \ -anchor w \ -font fontTEMP_drawer \ -text "$but($drawerCNT)" \ -tag textlineTag($drawerCNT) if {$drawerCNT == 0} { if {$fr == ".fr1"} { $fr.can bind textlineTag($drawerCNT) <ButtonRelease-1> {butImg "but1"} } else { $fr.can bind textlineTag($drawerCNT) <ButtonRelease-1> {butReturn} } } else { frame .fn$drawerCNT -background white -relief flat -pady 0 -padx 0 set titul $but($drawerCNT) set cmd "$fr.can bind textlineTag($drawerCNT) <ButtonRelease-1> {butCliked $drawerCNT .fn$drawerCNT}" set cmd [subst "$cmd"] eval $cmd set but1(0) " " page_func ".fn$drawerCNT" voda "$titul" "but1" } incr drawerCNT set yLocTextPx [ expr $yLocTextPx + $drawerHeightPx] # if { $drawerCNT > $Ndrawers } { set yLineLocPx [ expr (( $drawerCNT ) * $drawerHeightPx + $boxbut)] $fr.can create line $xLocTextPx $yLineLocPx \ [expr $drawerWidthPx + $xLocTextPx] $yLineLocPx \ -fill "#a0a0a0" -width $widl } } } # # set ::scrwidth [winfo screenwidth .] set ::scrheight [winfo screenheight .] set ::typetlf 0 #, if {$::scrwidth < $::scrheight} { set ::typetlf 1 } set ::padls 20 set ::padlx 15 set ::padly 15 if {$::typetlf} { wm attributes . -fullscreen 1 # scaleImage logo_product 2 set ::padls 50 set ::padlx 75 set ::padly 50 } else { # set ::scrwidth 370 set ::scrheight 700 wm minsize . $::scrwidth $::scrheight set geometr $::scrwidth append geometr "x" append geometr $::scrheight append geometr "+0+0" wm geometry . $geometr } # image create photo voda -file [file join $mydir "imageme" "voda_400x800.png"] # image create photo logo_product -file [file join $mydir "imageme" "validcertkey_51x24.png"] # set name_product "CryptoArmPKCS-A" label .labtitul -image logo_product -compound left -fg snow -text $name_product -font {Arial 10 bold} -anchor w -width [winfo screenwidth .] -pady $::padls -padx 10 -bg #222222 pack .labtitul -anchor nw -expand 0 -fill x -side top -padx 1 -pady 0 # set i 1 ttk::frame .fr$i -pad 0 -padding 0 # set but(0) " " set but(1) " " set but(2) " (PKCS7)" set but(3) " " set but(4) " /" set but(5) " " set but(6) " ASN1-" set but(7) " " set but(8) " PKCS12/PFX" set but(9) " " set but(10) " /" set but(11) " " set but(12) " " if {$::typetlf} { scaleImage voda 3 2 } # page_func ".fr$i" voda "" "but" # pack .fr$i -side top -anchor center -expand 1 -fill both -side top -padx 0 -pady 0
Este script também prepara espaços em branco para cada botão de função:

Os espaços em branco são preenchidos com widgets clássicos e temáticos (quadro de etiqueta, botão etc.). Uma dessas telas preenchidas pode ser vista na primeira captura de tela à direita. Como no primeiro estágio, focamos no trabalho com o contêiner PKCS # 12, o código foi usado quase sem alterações no cryptoarmpkcs-A. Nesta fase, as seguintes funções são implementadas:
- Assine o documento (Cades-BES, CAdes-T, CAdes-XLT1);
- Trabalhamos com ES (PKCS7), incluindo a adição de um assinante;
- Exibir certificados / solicitações de certificado:

- Trabalhamos com PKCS12 / PFX;
- Sobre Utilitários / Distribuições:

Outras funções estão mais relacionadas aos tokens PKCS # 11. A sua portabilidade é adiada para o Ano Novo. Está planejado conectar um token de software e uma
nuvem de tokens .
Do ponto de vista da funcionalidade, quase tudo é semelhante ao utilitário cryptoarmpkcs. Mas existem algumas diferenças. Por exemplo, depois de assinar um documento, o utilitário pergunta se a assinatura será verificada no site dos Serviços de Estado:
Quando você clica em Sim, um navegador será carregado com uma página para verificar a assinatura de documentos e certificados. Faça imediatamente uma reserva de que esta página não foi muito projetada para a tela de um smartphone. Isso será perceptível ao escolher uma assinatura e, se a assinatura for desconectada, o arquivo com o documento. Mas se tudo estiver bem, obteremos um resultado positivo:

Deve-se ter em mente que a verificação da assinatura e do certificado no site do Serviço de Estado só é desbotada se o certificado foi recebido em um centro de certificação credenciado. Caso contrário, a assinatura sempre será inválida.
Para chamar o navegador, tive que adicionar algumas linhas ao procedimento openUrl:
proc openURL {url} { global typesys global macos # global windowsOS #, Android if {$::typetlf} { # borg activity android.intent.action.VIEW $url text/html return } . . . }
O navegador Android é chamado da seguinte maneira:
borg activity android.intent.action.VIEW <URL> text/html
Um pequeno recurso é ao adicionar um novo assinante a um documento assinado anteriormente. O certificado do novo assinante (ou melhor, mesmo o contêiner PKCS # 12 com o certificado e a chave privada) deve ser pré-selecionado na página "Assinar um documento" ou "Trabalhar com PKCS12 / PFX", que o utilitário lembrará:
Nas operações de longo prazo, o relógio continua como antes:
Resta dizer onde baixar distribuições e parabéns pelo próximo ano novo e desejar a todos tudo de bom para 2020!

Então, distribuições para Linux, OS X, Windows e Android: