nullcpupowermanagement kext-360杀毒软件官方网站
2023年3月30日发(作者:微信跳一跳辅助)
ofd⽂件电⼦签章实现⽅法
前⾔⽂档处理⼀般经过三个环节:流、版、签;流式软件负责编辑,如:office、wps等。版式软件负责⽂档定型,保证显⽰样式不跑偏;
版式⽂件格式有两种:pdf、ofd。签章软件负责对版式⽂档签章。签章是⽂档处理的最后⼀个环节。 当前,市⾯上的版式⽂件还是以
pdf为主;对pdf的签章,国内研究的⽐较多。但是对ofd签章,国内研究时间不长,相关成熟的产品并不多。作者研究ofd多年,仔细分析
了ofd签章标准,编写了⼀套签章软件,可以满⾜⾃由签章、骑缝章等类型的签章。作者采⽤的签章⽅法有以下优点:思路新颖、处理速度
快、能满⾜各类复杂签章需求。
1OFD签章基本概念
签章的⽬的是保证数据的完整性、真实性。完整性是通过记录ofd⽂件的哈希值来保证的(国产算法为SM3);真实性是通过⾮对称加
密算法保证的(国产算法为SM2)。签章的过程其实就是记录ofd内的各个⽂件哈希值,再⽤私钥对哈希值签名。
2OFD签章遵循的标准
OFD签章涉及的标准不⽌⼀个;这往往导致开发签章软件时茫然⽆措。
ofd签章遵循两类标准:
2.1ofd板式⽂件格式标准:《GB/T33190-2016电⼦⽂件存储与交换格式》。
2.2签章密码技术规范:《GM/T0031-2014安全电⼦签章密码技术规范》,《GB/T38540-2020信息安全技术 安全电⼦签
章密码技术规范》。
3签章后,哪些⽂件被改动?
签章过程后,以下⽂件被修改。
签章汇总⽂件
具体签章⽂件,记录印章数据、签章数据、各个⽂件哈希值、印章位置信息等。
4签章需要主要事项
通过以上分析,可以看出签章好像并不难。其实不然,有⼏个问题要注意:
4.1不要想当然的认为OFD⽂件的路径都是固定的。OFD⽂件只有⼊⼝⽂件“OFD.”,名字是固定;其它任何⽂件名字都是可变
的。只是为了⽅便理解,⽣成的ofd⽂件名称遵循⼀定的规则。 下图只是建议的组织和命名规则。
4.2如果是多印章,后签的印章不能影响前⼀个印章。
如果⽂档已经做了签章了,再签章时,除了签章汇总⽂件()外,其他⽂件不能做任何改动。
4.3骑缝章处理。对于骑缝章,需要计算每个章的位置。需要分析出⽂件的页数以及每页尺⼨信息。
5签章处理步骤
5.1分析ofd原⽂件,将⽂件分类。
通过⼊⼝⽂件“”,层层剖析,将ofd内各类⽂件分类,具体分类如下:
在分析过程中,同时解析出ofd页⽂件的尺⼨。得出每个⽂件的属性。
5.2对分析后的⽂件处理
如果是第⼀次签章,需要⽣成。
计算⽂件的哈希值,计算印章的位置,⽣成。
enumclassEN_OfdFileType
{
unset,
root,
doucument,
publicRes,
documentRes,
pageContent,
resFile,
annotations,
annotation_page,
customTags,
customTagContent,
templatePage,
signatures,
signatureContent,
signedValue,
signedSeal,
attachments,
attachmentContent
};
classOfdFileInfoDetail
{
public:
EN_OfdFileTypeOfdFileType=EN_OfdFileType::unset;
QStringFilePath;//⽂件的完整路径
QByteArrayFileContent;//⽂件内容
intOfdFileIndex=-1;//⽂件索引多⽂档的情况下有⽤
//为ofd页⾯时,有效;OfdFileType=pageContent
intPageIndex=-1;//页索引
intPageId=-1;//页id
QStringPhysicalBox;//页尺⼨
//为ofdSignature时,有效;OfdFileType=signatureContent
intSignatureIndex=-1;//在⽂件Signatures中的索引
QStringPathSeal;//印章⽂件路径
QStringPathSignedValue;//签名后⽂件路径
};
QSharedPointer
if(())
{
QStringsignaturesPath=AddSignaturesPathToRoot(rootFile);
OfdFileInfoDetail*signaturesFileInfo=CreateSignaturesFile(signaturesPath);
(signaturesFileInfo);
_(signaturesFile);
}
voidSignOfdFile::CreateSignature(QStringsignaturePath,QByteArray&signatureFileContent,QString&signedValuePath)
{
{
QSharedPointer
header->SetName("Signature");
header->SetNameSpace(OfdCreatorParam::OFD_NameSpace);
header->SetNameSpaceUrl(OfdCreatorParam::OFD_NameSpaceUrl);
XmlNode*nodeSignedInfo=header->AddChildByName("SignedInfo",true);
//nodeProvider
XmlNode*nodeProvider=nodeSignedInfo->AddChildByName("Provider",true);
nodeProvider->SetAttr("Company",_company);
nodeProvider->SetAttr("Version",_version);
nodeProvider->SetAttr("ProviderName",_providerName);
//SignatureMethod
XmlNode*nodeSignatureMethod=nodeSignedInfo->AddChildByName("SignatureMethod",true);
nodeSignatureMethod->SetText(_thod);
//SignatureDateTime
XmlNode*nodeSignatureDateTime=nodeSignedInfo->AddChildByName("SignatureDateTime",true);
nodeSignatureDateTime->SetText(_teTime);
//Seal
if(!_y())
{
XmlNode*nodeSeal=nodeSignedInfo->AddChildByName("Seal",true);
XmlNode*nodeSealBaseLoc=nodeSeal->AddChildByName("BaseLoc",true);
QStringsealPath=OfdPathHelper::GetOfdFullPath(signaturePath,"");
nodeSealBaseLoc->SetText(OfdPathHelper::AddStartSlash(sealPath));
AddSealToFile(sealPath);
}
//References
XmlNode*nodeReferences=nodeSignedInfo->AddChildByName("References",true);
nodeReferences->SetAttr("CheckMethod",SignOfdParam::MethodName_SM3);
foreach(QSharedPointer
{
if(file->OfdFileType==EN_OfdFileType::signatures)
continue;
if(file->y())
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));
}
//StampAnnot
CreateStampAnnot(nodeSignedInfo);
//
signedValuePath=OfdPathHelper::GetOfdFullPath(signaturePath,"");
XmlNode*nodeSignedValue=header->AddChildByName("SignedValue",true);
nodeSignedValue->SetText(OfdPathHelper::AddStartSlash(signedValuePath));
//添加到⽂件列表
QSharedPointer
signatureFile->FilePath=signaturePath;
signatureFile->FileContent=header->CreateXml(true).toUtf8();
signatureFile->OfdFileType=EN_OfdFileType::signatureContent;
_(signatureFile);
signatureFileContent=signatureFile->FileContent;
}
后记本⽂粗略的描述了ofd签章的过程,实现签章的途径有多种。本⽂给出了⼀种可⾏、易懂的签章⽅法。具体的签章过程涉及⼤量细节处
理,对于开发⼈员来讲是⼀种挑战。作者通过多次修改完善,编写了⼀款签章服务软件,可以与签名接⼝对接,就⼤⼤减轻了签章的难度。
}
更多推荐
ofd文件怎么打开
发布评论