我有一个签名的PDF文件。有了这个使用iTextSharp库的功能,我找到了证书p7m签名:
private void GetSignature(string FileName)
{
AcroFields acroFields = new PdfReader(FileName).AcroFields;
List<string> names = acroFields.GetSignatureNames();
foreach (var name in names)
{
PdfDictionary dict = acroFields.GetSignatureDictionary(name);
PdfString contents = (PdfString)PdfReader.GetPdfObject(dict.Get(PdfName.CONTENTS));
byte[] PKCS7 = contents.GetOriginalBytes();
ByteArrayToFile(@"c:\signature\" + name + ".p7m", PKCS7);
}
}
现在......我如何提取与签名相关联的图像(位图)?可能吗? 谢谢,路易吉
答案 0 :(得分:4)
在您的示例文档中,术语签名适用于三个:
根据创建这些多级签名的软件的制造商,手写签名似乎是身份的主要证明。数字文件仅用于保护文档免受更改;它不一定反映手动签名的人的身份,而不是创建该手册签名的设备的所有者(“请在这里签名表明您已获得包裹”):
<强>功能强>
手写签名捕获 - 签名板,支付终端,iPad或Android设备上的法定可识别签名。
签名验证 - 将手写签名与预先注册的个人资料进行比较。
控制签名过程中的所有步骤 - 包括定位签名字段,填写表单,添加注释,添加附件等等。
保护文档的完整性 - 用数字签名密封它们。
关于使用iText提取所有这些信息......
AcroFields
类的签名相关方法,OP已经观察到,可以轻松提取和验证数字签名的属性。因此,最相关的信息是最不易获取的信息。
PS 关于加密的生物识别有效负载的解密,我在制造商的网站上发现了以下内容:
该文档包含已加密的已捕获签名(RSA 4096 + AES256)。一个人的签名在签名板使用特殊证书的私钥捕获时立即被加密。该特殊证书由公司使用xyzmo套件选择,通常存储在公司外部的安全环境中(银行保险箱,外部公证等)。因此,xyzmo本身无法访问此证书。对于签名加密,xyzmo套件只需要证书的公钥。它仅用于解密,以及从文档中提取签名,即需要私钥。只有公司授予其访问权限的特定人员才能使用PenAnalyst工具解密配置文件,该工具是套件的一部分。
因此,要解密生物识别数据,您必须能够访问相应的私钥,通常存储在公司外部的安全环境中(银行保险,外部公证等)。如果如果您有这种访问权限,我们可能会继续讨论这些解密数据的格式......;)
顺便说一句,如果有人可以简单地从签名文档中检索生物识别数据,那么很容易将它们复制到其他文档来伪造签名。提取手写签名的位图图像
由于对提取手写签名的位图图像特别感兴趣,因此这里有一个快速而又脏的帮助器来提取签名图像。正如已经说过的那样,我在Java中这样做,因为我更喜欢在那里:
public class XyzmoSignatureDataExtractor
{
public XyzmoSignatureDataExtractor(PdfReader reader)
{
this.reader = reader;
}
public PdfImageObject extractImage(String signatureName) throws IOException
{
MyImageRenderListener listener = new MyImageRenderListener();
PdfDictionary sigFieldDic = reader.getAcroFields().getFieldItem(signatureName).getMerged(0);
PdfDictionary appearancesDic = sigFieldDic.getAsDict(PdfName.AP);
PdfStream normalAppearance = appearancesDic.getAsStream(PdfName.N);
PdfDictionary resourcesDic = normalAppearance.getAsDict(PdfName.RESOURCES);
PdfContentStreamProcessor processor = new PdfContentStreamProcessor(listener);
processor.processContent(ContentByteUtils.getContentBytesFromContentObject(normalAppearance), resourcesDic);
return listener.image;
}
class MyImageRenderListener implements RenderListener
{
public void beginTextBlock() { }
public void endTextBlock() { }
public void renderImage(ImageRenderInfo renderInfo)
{
try
{
image = renderInfo.getImage();
}
catch (IOException e)
{
throw new RuntimeException("Failure retrieving image", e);
}
}
public void renderText(TextRenderInfo renderInfo) { }
PdfImageObject image = null;
}
final PdfReader reader;
}
你这样使用它:
PdfReader reader = new PdfReader(resourceStream);
XyzmoSignatureDataExtractor extractor = new XyzmoSignatureDataExtractor(reader);
AcroFields acroFields = reader.getAcroFields();
for (String name: acroFields.getSignatureNames())
{
System.out.printf("\nTesting signature '%s'.\n", name);
PdfImageObject image = extractor.extractImage(name);
OutputStream os = new FileOutputStream("target/test-outputs/SampleXyzmoSignature-image-" + name + "." + image.getFileType());
os.write(image.getImageAsBytes());
os.close();
PdfDictionary imageDictionary = image.getDictionary();
PRStream maskStream = (PRStream) imageDictionary.getAsStream(PdfName.SMASK);
if (maskStream != null)
{
PdfImageObject maskImage = new PdfImageObject(maskStream);
os = new FileOutputStream("target/test-outputs/SampleXyzmoSignature-image-" + name + "-mask." + maskImage.getFileType());
os.write(maskImage.getImageAsBytes());
os.close();
}
}
警告:班级XyzmoSignatureDataExtractor
确实是一个快速而又肮脏的黑客攻击。做出了许多假设,null
- 遗漏了支票,......