
现在该演示基于公钥
标准cryptoarmpkcs的密码工作站如何在一种移动平台即Android上工作。
在cryptoarmpkcs实用程序的开发过程中提出的概念是,用户在创建和验证电子签名时应尽量减少不便。 因此,我们建议使用
PKCS#11加密令牌和/或
PKCS#12安全容器作为个人证书的密钥介质。 我必须说,在许多情况下几乎只能使用PKCS#12,例如,当某些平台不支持相同的PKCS#11令牌时。
因此,我们决定开始将cryptoarmpkcs实用程序移植到支持PKCS#12安全容器的Android平台上。
随即,我们注意到由于该项目是在C和Tcl / Tk平台上完成的,因此移植没有造成任何根本性的困难。 这要归功于
Androwish技术。 部署和
设置环境没有问题(我的工作环境是Linux-Mageia-7.0)。 我只给您一个脚本来部署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"
最值得注意的是,Androwish环境包含两个解释器,undrowish-xxx和vanillawish-xxx,其构成与实际上是Androwish的一部分的“ balalaika”(程序包)完全相同。 undrowish和vanillawish之间的区别在于,在vanillawish中,后端基于SDL / AGG / freetype:

这两个实用程序的存在使您可以在不使用Android本身及其仿真器的情况下(最大程度逼近真实设备)开发应用程序。 首先,当然是undroidwish-xxx。
自定义Android程序包本身是在AWSDK环境中构建的。 您的项目树应该被移动,文件夹〜/ AWSDK / assets / app。 在这种情况下,您项目的主模块应重命名为main.tcl。 如果您将其他balalaikas与动态库一起使用,则必须将库放置在仿真器的〜/ AWSDK / libs / x86文件夹中,真实设备中的〜/ AWSDK / libs / armeabi文件夹中。
之后,只需运行以下命令:
$wish ~/AWSDK/tools/bones
并按照她的指示进行:

收集的apk包将位于〜/ AWSDK / build / outputs / apk文件夹中。
如果您连接的是真实设备或仿真器,则可以立即安装该软件包。
在这种情况下,实际设备必须处于调试模式。
但是回到应用程序本身。 必须更改的内容。
自然,首先,更改与屏幕尺寸有关。 我不得不重新设计主窗口(开始窗口)。 结果,而不是常规计算机上的单个窗口:

Android上出现了三个窗口:

第一个窗口是信息性的。 按照惯例,它分为几个部分。 第一部分位于顶部,包含实用程序的名称及其徽标。
接下来是制造商的徽标,信息帮助和三个按钮来完成页面。
该页面是使用canvas组件编写的。 页面上有两种类型的按钮:一种是半透明矩形(中间),另一种是圆角矩形。 为了创建带有圆角的按钮,使用了“ balalaika”
tkpath 。 就个人而言,这个莱莱卡舞给我留下了很好的印象。 自然,在使用画布时,代码的主要部分是几何。 以下是用于创建应用程序第一页的create_titul_page.tcl脚本。 每个人都可以对其进行编辑以适应他们的愿景。
脚本create_titul_page.tcl package require Tk package require tkpath 0.3.0 global mydir set mydir [file dirname [info script]]
要执行此脚本,请使用undroidwish或vanillawish实用程序之一:
$ /usr/local/bin64/undroidwish-e5dc71ed9d-linux64 create_titul_page.tcl
或
$/usr/local/bin64/vanillawish-e5dc71ed9d-linux64 create_titul_page.tcl
结果显示在第一个屏幕截图中。
第二页列出了cryptoarmpkcs-A实用程序支持的功能。 每行是一个按钮,单击时将显示功能页面。 此页面上按钮的几何形状由所使用的字体决定。 以下是create_page_functions.tcl脚本,用于创建应用程序的第二个/功能页面。 每个人都可以根据其功能对其进行编辑。
脚本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
该脚本还为每个功能按钮准备了空格:

空白处充满了经典和主题的小部件(标签框架,按钮等)。 在右边的第一个屏幕截图中可以看到这些填充的画布之一。 因为在第一阶段我们专注于使用PKCS#12容器,所以对于cryptoarmpkcs-A几乎无需更改即可使用该代码。 在此阶段,实现以下功能:
- 在文档上签名(Cades-BES,CAdes-T,CAdes-XLT1);
- 我们使用ES(PKCS7),包括添加签名者;
- 查看证书/证书请求:

- 我们与PKCS12 / PFX合作;
- 关于实用程序/发行版:

其他功能与PKCS#11令牌更相关。 他们的移植被推迟到新年。 计划连接软件令牌并连接到
令牌云 。
从功能的角度来看,几乎所有内容都与cryptoarmpkcs实用程序相似。 但是有一些区别。 例如,在签署文件后,该实用程序会询问是否在国家服务网站上检查签名:
当您单击“是”时,将在浏览器中加载一个页面,用于验证文档和证书的签名。 立即预订该页面不是针对智能手机的屏幕而专门设计的。 选择签名时,这将很明显;如果签名断开,则选择包含文档的文件。 但是,如果一切顺利,那么我们将获得积极的结果:

应该记住的是,只有在授权的认证中心(
CA )收到证书的情况下,才可以清除国家服务网站上的签名和证书的验证。 否则,签名将始终无效。
要调用浏览器,我必须在openUrl过程中添加几行:
proc openURL {url} { global typesys global macos # global windowsOS #, Android if {$::typetlf} { # borg activity android.intent.action.VIEW $url text/html return } . . . }
Android浏览器的调用方式如下:
borg activity android.intent.action.VIEW <URL> text/html
将新的签署者添加到先前签署的文档时,这是一个小功能。 必须在“对文档签名”或“使用PKCS12 / PFX”页面上预先选择新签名者的证书(甚至是带有证书和私钥的PKCS#12容器),该实用程序将使您想到以下内容:
如果长时间运行,时钟将像以前一样继续工作:
还要说在即将到来的新年下载发行和祝贺的地方,并祝大家在2020年一切顺利!

因此,适用于Linux,OS X,Windows和Android的发行版: