Java 更改数字签名者";“主要所有者名称”;

Java 更改数字签名者";“主要所有者名称”;,java,itext,Java,Itext,我正在用itext5签署一份pdf文件 MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter); 生成的文本是:由JOHN MORGAN数字签名+时间戳 当我编辑Layer2文本时 appearance.setLayer2Text("Signed by "); 我只得到:签名人(没有名字) 我需要编辑“数字签名人”,

我正在用itext5签署一份pdf文件

MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
生成的文本是:由JOHN MORGAN数字签名+时间戳

当我编辑Layer2文本时

appearance.setLayer2Text("Signed by ");
我只得到:签名人(没有名字)

我需要编辑“数字签名人”,但我想保留密钥所有者的姓名

如何获取密钥所有者的姓名

我尝试使用别名(用于从密钥库获取密钥),但名称不正确(包含特殊字符)


谢谢

如果您设置第2层文本,您必须设置整个第2层文本,即不仅是由“签名的
,而且是由约翰·摩根签名的
”加上时间戳“

由于iText是开源的,您可以简单地复制粘贴和操作iText代码来生成第2层文本。iText代码负责:

String text;
if (layer2Text == null) {
    StringBuilder buf = new StringBuilder();
    buf.append("Digitally signed by ");
    String name = null;
    X500Name x500name = CertificateInfo.getSubjectFields((X509Certificate)signCertificate);
    if (x500name != null) {
        name = x500name.getField("CN");
        if (name == null)
            name = x500name.getField("E");
    }
    if (name == null)
        name = "";
    buf.append(name).append('\n');
    SimpleDateFormat sd = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");
    buf.append("Date: ").append(sd.format(signDate.getTime()));
    if (reason != null)
        buf.append('\n').append(reasonCaption).append(reason);
    if (location != null)
        buf.append('\n').append(locationCaption).append(location);
    text = buf.toString();
}
else
    text = layer2Text;
(来自
PdfSignatureAppearance.getAppearance()

用getter和常量替换对受保护成员的引用,并从此代码中删除
“数字”
,这样您就可以在任务中使用:

StringBuilder buf = new StringBuilder();
buf.append("Signed by ");
String name = null;
X500Name x500name = CertificateInfo.getSubjectFields((X509Certificate)chain[0]);
if (x500name != null) {
    name = x500name.getField("CN");
    if (name == null)
        name = x500name.getField("E");
}
if (name == null)
    name = "";
buf.append(name).append('\n');
SimpleDateFormat sd = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");
buf.append("Date: ").append(sd.format(appearance.getSignDate().getTime()));
if (appearance.getReason() != null)
    buf.append('\n').append("Reason: ").append(appearance.getReason());
if (appearance.getLocation() != null)
    buf.append('\n').append("Location: ").append(appearance.getLocation());
appearance.setLayer2Text(buf.toString());

(从test
signWithCustomLayer2Text

如果设置第2层文本,则必须设置整个第2层文本,即不仅是由“
签名的
,而且是由JOHN MORGAN+Timestamp”
签名的
。是的,这就是如何获取令牌所有者的名称的问题?@mkl(我编辑主帖子)我尝试使用别名(用于从密钥库获取密钥)但名称不正确(包含特殊字符)请使用签名证书中的信息,如我的回答中所述。我的回答对您有帮助吗?
StringBuilder buf = new StringBuilder();
buf.append("Signed by ");
String name = null;
X500Name x500name = CertificateInfo.getSubjectFields((X509Certificate)chain[0]);
if (x500name != null) {
    name = x500name.getField("CN");
    if (name == null)
        name = x500name.getField("E");
}
if (name == null)
    name = "";
buf.append(name).append('\n');
SimpleDateFormat sd = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");
buf.append("Date: ").append(sd.format(appearance.getSignDate().getTime()));
if (appearance.getReason() != null)
    buf.append('\n').append("Reason: ").append(appearance.getReason());
if (appearance.getLocation() != null)
    buf.append('\n').append("Location: ").append(appearance.getLocation());
appearance.setLayer2Text(buf.toString());