锁定数字签名中的字段

锁定数字签名中的字段

我用eforms它来创建可以应用数字签名的 PDF。每个文档可能有一个以上的数字签名字段,也就是说,文档可以在人与人之间传递。

这里增加了复杂性,因为根据解析到自定义命令的参数,\mySigField{...}用户名和标题字段可以编辑也可以不编辑。换句话说,第 4 个和第 5 个参数分别代表姓名和职位。如果这些输入参数为空,则会创建一个可编辑字段,如果它们包含某些内容,则会打印这些内容,并且不会创建任何可编辑字段。

我的问题是,如果至少有一个可编辑的相关字段,那么在特定用户签名后,我该如何锁定该字段。

以下示例输出:

输出

由以下代码生成:

\documentclass{article}

\usepackage{varwidth}
\usepackage{hyperref}
\usepackage[pdftex]{eforms}
\usepackage{xcolor}
\usepackage{xifthen}

\def\colFeat{blue!50!black} %Feature Color 1 for Main Color Theme.

\makeatletter
    \def\eq@SigField{\centerWidget\eq@rectH
        \if\autoCenter n\eqcenterWidget=0pt\fi
        \leavevmode\hbox{\pdfstartlink user{\common@SigFieldCode}%
        \lower\eqcenterWidget\Bbox{\eq@rectW}{\eq@rectH}\pdfendlink}%
        \endgroup
    }
\makeatother

\newcommand{\mySigField}[5]{
    \begin{varwidth}{#2}
        \textcolor{\colFeat}{
            \fcolorbox{black!5!white}{black!5!white}{\sigField{#1}{#2}{#3}}\\[1mm]
            \rule{#2+3mm}{2pt}\\[2mm]
            \begin{tabular}{rl}
                \raggedleft Name: & \ifthenelse{\equal{#4}{}}{\TextField[name=name#1,width=6cm]{}}{#4}\\\\[-3mm]
                \raggedleft Position: & \ifthenelse{\equal{#5}{}}{\TextField[name=pos#1,width=6cm]{}} {#5}
            \end{tabular}
        }
    \end{varwidth}
}

\begin{document}
\def\WS{8cm}
\def\HS{2.5cm}
\section{Example of No Related Fields}
\mySigField{PERSONA}{\WS}{\HS}{John Smith}{Garbo}
\section{Example of One Related Field}
\mySigField{PERSONB}{\WS}{\HS}{Jane Doe}{}
\section{Example of Two Related Fields}
\mySigField{PERSONC}{\WS}{\HS}{}{}
\end{document}

答案1

根据PDF 规范(第 446f 页),可以指定一旦签名字段被签名就不再更改的表单字段,即所谓的签名字段锁定字典. 随着eforms包中,执行此操作的签名字段的代码\mySigField将是:

\sigField[\Lock{/Action/Include/Fields [(name#1)(pos#1)]}]{#1}{#2}{#3}

应锁定的表单字段的名称在圆括号中给出。其他可能的规范是\Lock{/Action/All}锁定所有表单字段,以及\Lock{/Action/Exclude/Fields [(field1)(field2)...]}锁定除指定字段之外的所有字段。

在您的示例中,如果提供了名称和位置的一个或两个参数,则上述代码将指定不存在的表单字段,因此使用一系列条件可能会更清晰:

\ifthenelse{\equal{#4}{}}%
  {\ifthenelse{\equal{#5}{}}%
    {\sigField[\Lock{/Action/Include/Fields [(name#1)(pos#1)]}]{#1}{#2}{#3}}%
    {\sigField[\Lock{/Action/Include/Fields [(name#1)]}]{#1}{#2}{#3}}%
  }%
  {\ifthenelse{\equal{#5}{}}%
    {\sigField[\Lock{/Action/Include/Fields [(pos#1)]}]{#1}{#2}{#3}}%
    {\sigField{#1}{#2}{#3}}%
  }%

不幸的是,我无法测试它是否能按预期工作,因为我没有 Adob​​e Acrobat 来实际用签名填充其中一个字段。

答案2

我想发布该解决方案的最终代码,该代码由上面的 diabonas 提供。

我既可以在 Adob​​e Professional 中打开它并签名,也可以将文件拖到 Web 浏览器中并执行相同操作。据推测,这是因为 Adob​​e Professional 劫持了我的浏览器 pdf 插件。

放入序言中:

\usepackage{eforms}
\makeatletter
    \def\eq@SigField{%
        \centerWidget\eq@rectH%
        \if\autoCenter n\eqcenterWidget=0pt\fi%
        \leavevmode\hbox{\pdfstartlink user{\common@SigFieldCode}%
                \lower\eqcenterWidget\Bbox{\eq@rectW}{\eq@rectH}\pdfendlink%
        }%
        \endgroup%
    }
\makeatother

\newcommand{\mySigField}[5]{
    \begin{varwidth}{#2}
        \textcolor{\colFeat}{
            \fcolorbox{black!5!white}{black!5!white}{
                \ifthenelse{\equal{#4}{}}%
                    {\ifthenelse{\equal{#5}{}}%
                        {\sigField[\Lock{/Action/Include/Fields [(name#1)(pos#1)]}]{#1}{#2}{#3}}%
                        {\sigField[\Lock{/Action/Include/Fields [(name#1)]}]{#1}{#2}{#3}}%
                    }%  
                    {\ifthenelse{\equal{#5}{}}%
                        {\sigField[\Lock{/Action/Include/Fields [(pos#1)]}]{#1}{#2}{#3}}%
                        {\sigField{#1}{#2}{#3}}%
                    }%
                }\\[1mm]            
            \rule{#2+3mm}{2pt}\\[2mm]
            \begin{tabular}{rl}
                \raggedleft Name: & \ifthenelse{\equal{#4}{}}{\TextField[name=name#1,width=6cm]{}}{#4}\\\\[-3mm]
                \raggedleft Position: & \ifthenelse{\equal{#5}{}}{\TextField[name=pos#1,width=6cm]{}} {#5}
            \end{tabular}
        }
    \end{varwidth}
}

然后在实际文档中:

可以使用以下命令创建签名字段:

\mySigField{\KEY}{\HEIGHT}{\WIDTH}{\NAME}{\POSITION}

注意到:

  • 对于多个签名,\KEY 应该定义并且每个签名块都是唯一的
  • \HEIGHT 和 \WIDTH ...不言自明。
  • \NAME 和 \POSITION 可以留空或填写。如果留空,则会创建一个字段,然后在最终用户签名时锁定该字段。这就是为什么密钥需要唯一的原因,因为字段需要链接到签名。

最终签名面板如下所示: 输出

签名后看起来像这样。 [该字段不可更改] 输出2

最后,请注意,我已检查了只有一个字段的行为,并且该单个字段位于任一位置。在这两种情况下,签名后所有内容都会锁定。

相关内容