日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ofd文件电子签章实现方法

發(fā)布時(shí)間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ofd文件电子签章实现方法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言?文檔處理一般經(jīng)過(guò)三個(gè)環(huán)節(jié):流、版、簽;流式軟件負(fù)責(zé)編輯,如:office、wps等。版式軟件負(fù)責(zé)文檔定型,保證顯示樣式不跑偏;版式文件格式有兩種:pdf、ofd。簽章軟件負(fù)責(zé)對(duì)版式文檔簽章。簽章是文檔處理的最后一個(gè)環(huán)節(jié)。
  當(dāng)前,市面上的版式文件還是以pdf為主;對(duì)pdf的簽章,國(guó)內(nèi)研究的比較多。但是對(duì)ofd簽章,國(guó)內(nèi)研究時(shí)間不長(zhǎng),相關(guān)成熟的產(chǎn)品并不多。作者研究ofd多年,仔細(xì)分析了ofd簽章標(biāo)準(zhǔn),編寫了一套簽章軟件,可以滿足自由簽章、騎縫章等類型的簽章。作者采用的簽章方法有以下優(yōu)點(diǎn):思路新穎、處理速度快、能滿足各類復(fù)雜簽章需求。

1 OFD簽章基本概念

  簽章的目的是保證數(shù)據(jù)的完整性、真實(shí)性。完整性是通過(guò)記錄ofd文件的哈希值來(lái)保證的(國(guó)產(chǎn)算法為SM3);真實(shí)性是通過(guò)非對(duì)稱加密算法保證的(國(guó)產(chǎn)算法為SM2)。簽章的過(guò)程其實(shí)就是記錄ofd內(nèi)的各個(gè)文件哈希值,再用私鑰對(duì)哈希值簽名。

2 OFD簽章遵循的標(biāo)準(zhǔn)

  OFD簽章涉及的標(biāo)準(zhǔn)不止一個(gè);這往往導(dǎo)致開發(fā)簽章軟件時(shí)茫然無(wú)措。

  ofd簽章遵循兩類標(biāo)準(zhǔn):

  2.1? ofd板式文件格式標(biāo)準(zhǔn):《 GB/T 33190-2016電子文件存儲(chǔ)與交換格式》。
  2.2? 簽章密碼技術(shù)規(guī)范:?《GM/T 0031-2014 安全電子簽章密碼技術(shù)規(guī)范》,《GB/T 38540-2020信息安全技術(shù) 安全電子簽章密碼技術(shù)規(guī)范》。

3 簽章后,哪些文件被改動(dòng)?

  簽章過(guò)程后,以下文件被修改。

3.1 OFD.xml

3.2 Signatures.xml

  簽章匯總文件

3 Signature.xml

  具體簽章文件,記錄印章數(shù)據(jù)、簽章數(shù)據(jù)、各個(gè)文件哈希值、印章位置信息等。

4 簽章需要主要事項(xiàng)

  通過(guò)以上分析,可以看出簽章好像并不難。其實(shí)不然,有幾個(gè)問(wèn)題要注意:

  4.1?? 不要想當(dāng)然的認(rèn)為OFD文件的路徑都是固定的。OFD文件只有入口文件“OFD.xml”,名字是固定;其它任何文件名字都是可變的。只是為了方便理解,生成的ofd文件名稱遵循一定的規(guī)則。
  下圖只是建議的組織和命名規(guī)則。

  4.2??如果是多印章,后簽的印章不能影響前一個(gè)印章。

    如果文檔已經(jīng)做了簽章了,再簽章時(shí),除了簽章匯總文件(Signatures.xml)外,其他文件不能做任何改動(dòng)。

  4.3??騎縫章處理。對(duì)于騎縫章,需要計(jì)算每個(gè)章的位置。需要分析出文件的頁(yè)數(shù)以及每頁(yè)尺寸信息。

5 簽章處理步驟

5.1 分析ofd原文件,將文件分類。

  通過(guò)入口文件“OFD.xml”,層層剖析,將ofd內(nèi)各類文件分類,具體分類如下:

enum class EN_OfdFileType {unset,root,doucument,publicRes,documentRes,pageContent,resFile,annotations,annotation_page,customTags,customTagContent,templatePage,signatures,signatureContent,signedValue,signedSeal,attachments,attachmentContent };

在分析過(guò)程中,同時(shí)解析出ofd頁(yè)文件的尺寸。得出每個(gè)文件的屬性。

class OfdFileInfoDetail { public:EN_OfdFileType OfdFileType = EN_OfdFileType::unset;QString FilePath; //文件的完整路徑QByteArray FileContent; //文件內(nèi)容int OfdFileIndex = -1; //文件索引 多文檔的情況下 有用//為ofd頁(yè)面時(shí),有效;OfdFileType=pageContentint PageIndex = -1; //頁(yè)索引int PageId = -1; //頁(yè)idQString PhysicalBox; //頁(yè)尺寸//為ofd Signature時(shí),有效;OfdFileType=signatureContentint SignatureIndex = -1;//在文件Signatures中的索引QString PathSeal; //印章文件路徑QString PathSignedValue;//簽名后文件路徑 };

5.2 對(duì)分析后的文件處理

  如果是第一次簽章,需要生成Signatures.xml。

QSharedPointer<OfdFileInfoDetail> signaturesFile = GetOfdFile(EN_OfdFileType::signatures);if(signaturesFile.isNull()){QString signaturesPath = AddSignaturesPathToRoot(rootFile);OfdFileInfoDetail *signaturesFileInfo = CreateSignaturesFile(signaturesPath);signaturesFile.reset(signaturesFileInfo);_listOfdFile.append(signaturesFile);}

  計(jì)算文件的哈希值,計(jì)算印章的位置,生成Signature.xml。

void SignOfdFile::CreateSignature(QString signaturePath,QByteArray& signatureFileContent,QString& signedValuePath) {QSharedPointer<XmlNode> header(new XmlNode());header->SetName("Signature");header->SetNameSpace(OfdCreatorParam::OFD_NameSpace);header->SetNameSpaceUrl(OfdCreatorParam::OFD_NameSpaceUrl);XmlNode *nodeSignedInfo = header->AddChildByName("SignedInfo",true);//nodeProviderXmlNode *nodeProvider = nodeSignedInfo->AddChildByName("Provider",true);nodeProvider->SetAttr("Company",_company);nodeProvider->SetAttr("Version",_version);nodeProvider->SetAttr("ProviderName",_providerName);//SignatureMethodXmlNode *nodeSignatureMethod = nodeSignedInfo->AddChildByName("SignatureMethod",true);nodeSignatureMethod->SetText(_signInfoInput.signMethod);//SignatureDateTimeXmlNode *nodeSignatureDateTime = nodeSignedInfo->AddChildByName("SignatureDateTime",true);nodeSignatureDateTime->SetText(_signInfoInput.signDateTime);//Sealif(!_sealData.isEmpty()){XmlNode *nodeSeal = nodeSignedInfo->AddChildByName("Seal",true);XmlNode *nodeSealBaseLoc= nodeSeal->AddChildByName("BaseLoc",true);QString sealPath = OfdPathHelper::GetOfdFullPath(signaturePath,"Seal.esl");nodeSealBaseLoc->SetText(OfdPathHelper::AddStartSlash(sealPath));AddSealToFile(sealPath);}//ReferencesXmlNode *nodeReferences = nodeSignedInfo->AddChildByName("References",true);nodeReferences->SetAttr("CheckMethod",SignOfdParam::MethodName_SM3);foreach(QSharedPointer<OfdFileInfoDetail> file , _listOfdFile){if(file->OfdFileType == EN_OfdFileType::signatures)continue;if(file->FileContent.isEmpty())continue;XmlNode *nodeReference = nodeReferences->AddChildByName("Reference",true);nodeReference->SetAttr("FileRef",OfdPathHelper::AddStartSlash(file->FilePath));XmlNode *nodeCheckValue = nodeReference->AddChildByName("CheckValue",true);nodeCheckValue->SetText(sm3_digest_base64(file->FileContent));}//StampAnnotCreateStampAnnot(nodeSignedInfo);//SignedValue.datsignedValuePath = OfdPathHelper::GetOfdFullPath(signaturePath,"SignedValue.dat");XmlNode *nodeSignedValue = header->AddChildByName("SignedValue",true);nodeSignedValue->SetText(OfdPathHelper::AddStartSlash(signedValuePath));//添加到文件列表QSharedPointer<OfdFileInfoDetail> signatureFile(new OfdFileInfoDetail());signatureFile->FilePath = signaturePath;signatureFile->FileContent = header->CreateXml(true).toUtf8();signatureFile->OfdFileType = EN_OfdFileType::signatureContent;_listOfdFile.append(signatureFile);signatureFileContent = signatureFile->FileContent; }

后記?本文粗略的描述了ofd簽章的過(guò)程,實(shí)現(xiàn)簽章的途徑有多種。本文給出了一種可行、易懂的簽章方法。具體的簽章過(guò)程涉及大量細(xì)節(jié)處理,對(duì)于開發(fā)人員來(lái)講是一種挑戰(zhàn)。作者通過(guò)多次修改完善,編寫了一款簽章服務(wù)軟件,可以與簽名接口對(duì)接,就大大減輕了簽章的難度。

總結(jié)

以上是生活随笔為你收集整理的ofd文件电子签章实现方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。