首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何实现我自己的函数来验证SM2签名?

如何实现我自己的函数来验证SM2签名?
EN

Stack Overflow用户
提问于 2019-01-17 01:36:49
回答 1查看 250关注 0票数 0

在我的工作中,我必须使用中文SM2加密算法来签署一个pdf并验证签名,我选择了itext来帮助我的work.But,因为这是我第一次使用itext库,我对它非常陌生。

签名部分我使用了外部签名,将一个SM2签名放到一个pdf的签名字典中。我可以在互联网上找到很多关于this.But的代码,当涉及到验证签名时,我可以找到很少的帮助(itext不支持SM2算法,这就是为什么我不能使用standart验证方法,并且必须实现我自己的功能来验证SM2签名).I意味着我不知道如何获得签名的原始数据,就像在使用"GetRangeStream“的签名部分中所做的那样,并且我不知道如何从pdf的表单字段中读取SM2签名。

有人能帮我一下吗?非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-21 11:38:20

您需要的代码显然类似于iText方法AcroFields.VerifySignature在创建表示所涉签名的PdfPKCS7对象时执行的代码。由于iText是开源的,所以只要您需要,就可以简单地复制该代码!

例如。

我不知道如何从pdf的表单字段读取SM2签名。

AcroFields.VerifySignature的启动方式如下:

代码语言:javascript
复制
    virtual public PdfPKCS7 VerifySignature(String name) {
        PdfDictionary v = GetSignatureDictionary(name);
        if (v == null)
            return null;
        PdfName sub = v.GetAsName(PdfName.SUBFILTER);
        PdfString contents = v.GetAsString(PdfName.CONTENTS);
        PdfPKCS7 pk = null;
        if (sub.Equals(PdfName.ADBE_X509_RSA_SHA1)) {
            PdfString cert = v.GetAsString(PdfName.CERT);
            if (cert == null)
                cert = v.GetAsArray(PdfName.CERT).GetAsString(0);
            pk = new PdfPKCS7(contents.GetOriginalBytes(), cert.GetBytes());
        }
        else
            pk = new PdfPKCS7(contents.GetOriginalBytes(), sub);

因此,提取嵌入式签名对象的基本代码如下所示

代码语言:javascript
复制
AcroFields acroFields = reader.AcroFields;
PdfDictionary v = acroFields.GetSignatureDictionary(name);
if (v != null) {
    PdfString contents = v.GetAsString(PdfName.CONTENTS);
    byte[] embeddedSignatureObjectBytes = contents.GetOriginalBytes();
    [... process embeddedSignatureObjectBytes ...]
}

注意:由于Content字符串填充了零,实际签名对象后面的embeddedSignatureObjectBytes字节将包含0x00字节的尾。

我不知道如何获得有符号的原始数据

AcroFields.VerifySignature继续这样说:

代码语言:javascript
复制
UpdateByteRange(pk, v);

AcroFields.UpdateByteRange的实现方式如下:

代码语言:javascript
复制
private void UpdateByteRange(PdfPKCS7 pkcs7, PdfDictionary v) {
    PdfArray b = v.GetAsArray(PdfName.BYTERANGE);
    RandomAccessFileOrArray rf = reader.SafeFile;
    Stream rg = null;
    try {
        rg = new RASInputStream(new RandomAccessSourceFactory().CreateRanged(rf.CreateSourceView(), b.AsLongArray()));
        byte[] buf = new byte[8192];
        int rd;
        while ((rd = rg.Read(buf, 0, buf.Length)) > 0) {
            pkcs7.Update(buf, 0, rd);
        }
    } finally {
        if (rg != null) rg.Close();
    }
}

因此,读取签名文档字节的基本代码如下所示

代码语言:javascript
复制
AcroFields acroFields = reader.AcroFields;
PdfDictionary v = acroFields.GetSignatureDictionary(name);
if (v != null) {
    PdfArray b = v.GetAsArray(PdfName.BYTERANGE);
    RandomAccessFileOrArray rf = reader.SafeFile;
    Stream rg = null;
    try {
        rg = new RASInputStream(new RandomAccessSourceFactory().CreateRanged(rf.CreateSourceView(), b.AsLongArray()));
        [... process the signed data in the Stream rg ...]
    } finally {
        if (rg != null) rg.Close();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54227807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档