目录 1.了解数字证书 1.1.为什么需要数字证书? 1.2.查看WINDOWS中的证书 2.数字证书格式 2.1.X公钥证书(不带私钥) 2.2.P12证书(带私钥) 3.证书内容解析程序 3.1.解析证书存储区中的证书 3.2.解析X公钥证书文件 4.基于证书的数字签名与验证程序 1.了解数字证书 1.1.为什么需要数字证书? 在公钥密码体制的应用中,私钥由个人保存,公钥要公开发布。 公钥如何发布并保证其真实可信呢?解决办法是建立公钥基础设施(PKI),由可信第三方(CA)签发数字证书(简称证书)。 数字证书由权威机构CA签名,将主体和公钥信息进行绑定,以确保公钥与主体的对应关系及其有效性。 1.2. 查看Windows中的证书 在Windows系统中运行crtmgr.msc,进入证书管理界面,可以观察已安装的证书内容。 图1-1运行crtmgr.msc 图1-2查看证书 2.数字证书格式 常用的数字证书有两种格式:X公钥证书(不带私钥)和p12证书(带私钥)。所有的证书都符合为PublicKyInfrastructur(PKI)制定的ITU-TX国际标准。 2.1.X公钥证书(不带私钥) Xv3公钥证书是通用的证书格式,其不含主体的私钥,用于公开发布。Xv3证书文件后缀名通常为cr/.crt,证书格式定义如下(ASN1语法): Crtificat::=SIGEND{ SEQUENCE{ vrsion[0]EXPLICITVrsionDEFAULTv1,--证书版本号 srialNumbrCrtificatSrialNumbr,--证书序列号,对同一CA所颁发的证书,序列号唯一标识证书 signaturAlgorithmIdntifir,--证书签名算法标识 issurNam,--证书颁发者名称 validityValidity,--证书有效期 subjctNam,--证书主体名称 subjctPublicKyInfoSubjctPublicKyInfo,--证书公钥 issurUniquID[1]IMPLICITUniquIdntifirOPTIONAL,--证书颁发者ID(可选),只在证书版本2、3中才有 subjctUniquID[2]IMPLICITUniquIdntifirOPTIONAL,--证书主体ID(可选),只在证书版本2、3中才有 xtnsions[3]EXPLICITExtnsionsOPTIONAL--证书扩展段(可选),只在证书版本3中才有 } } 在Windows证书管理器中,可以导出X公钥证书。导出时选择“不要导出私钥”即可得到一个公钥证书。 图2-1导出X公钥证书 2.2.p12证书(带私钥) p12证书是指以pkcs#12标准(个人信息交换语法标准)格式存储的证书,其包含公钥证书(也可以包含整个证书链)和相应私钥,通常还包含保护密码。所以,可从p12证书中提取制作X公钥证书。 为防私钥泄露,获取p12证书中的私钥时需要用户输入保护密码。p12证书文件后缀名为p12/pfx。 在Windows证书管理器中,如果当前用户拥有公钥证书对应的私钥,则可以导出p12证书。过程如下: 图2-2导出p12证书 图2-3导出p12证书 图2-4导出p12证书 图2-5导出p12证书 3.数字证书相关类 3.1. XCrtificat2类 3.2. XStor类 4.证书内容解析程序 4.1. 解析证书存储区中的证书 usingSystm; usingSystm.Scurity.Cryptography.XCrtificats; //注:使用XCrtificat2UI时需要在“引用”中添加对组件Systm.Scurity的引用 classCrtSlct { staticvoidMain() { Consol.WritLin("********证书内容解析实例********"); try { //打开当前Windows用户的个人证书存储区 varxStor=nwXStor("MY",StorLocation.CurrntUsr); xStor.Opn(OpnFlags.RadOnly OpnFlags.OpnExistingOnly); //获取有效证书的集合 varcrts=xStor.Crtificats.Find(XFindTyp.FindByTimValid,DatTim.Now,fals); //提示用户选取一个或多个证书(调用证书UI) varslctdCrts=XCrtificat2UI.SlctFromCollction(crts,"证书列表","请选择一个或多个证书:",XSlctionFlag.MultiSlction); Consol.WritLin("您选择的证书数:"+slctdCrts.Count); Consol.WritLin(); //列举证书中的信息 forach(varcrtinslctdCrts) { ShowCrtInfo(crt); Consol.WritLin(); } //关闭证书存储区 xStor.Clos(); } catch(Excptionx) { Consol.WritLin(x.Mssag); } Consol.WritLin("请按下[Entr]键结束程序.."); Consol.RadLin(); } //------------------------------------------------------ staticvoidShowCrtInfo(XCrtificat2crt) { Consol.WritLin("简单名称:{0}",crt.GtNamInfo(XNamTyp.SimplNam,fals)); Consol.WritLin("版本:V{0}",crt.Vrsion); Consol.WritLin("序列号:{0}",crt.SrialNumbr); Consol.WritLin("签名算法:{0}",crt.SignaturAlgorithm.FrindlyNam); Consol.WritLin("颁发者:{0}",crt.Issur); Consol.WritLin("有效期:{0}~{1}",crt.NotBfor,crt.NotAftr); Consol.WritLin("使用者:{0}",crt.Subjct); Consol.WritLin("公钥:{0}",crt.GtPublicKyString()); if(crt.HasPrivatKy) { Consol.WritLin("私钥:{0}",crt.PrivatKy.ToXmlString(fals)); } Consol.WritLin("指纹:{0}",crt.Thumbprint);//公钥证书文件的指纹(即导出的.cr文件的sha1哈希值,可用fciv工具计算.cr文件的哈希值验证) //显示证书的扩展属性 forach(varxtincrt.Extnsions) { Consol.WritLin(xt.Oid.FrindlyNam+":"+xt.Oid.Valu); } //简单的证书链验证 Consol.WritLin("证书链验证:"+crt.Vrify());//只是简单验证,完整验证应使用XChain类 //调用证书UI显示证书详情 //XCrtificat2UI.DisplayCrtificat(crt); } } 4.2. 解析X公钥证书文件 usingSystm; usingSystm.Scurity.Cryptography.XCrtificats; namspacCrtFilInfo { classProgram { staticvoidMain(string[]args) { Consol.WritLin("********证书文件解析实例********"); varcrt=nwXCrtificat2(); crt.Import("crt.cr"); ShowCrtInfo(crt); /*将证书添加到证书存储区 varstor=nwXStor(); stor.Opn(OpnFlags.MaxAllowd); stor.Add(crt); stor.Clos(); //*/ Consol.WritLin("请按下[Entr]键结束程序.."); Consol.RadLin(); } //-------------------------------------------------- staticvoidShowCrtInfo(XCrtificat2crt) { Consol.WritLin("简单名称:{0}",crt.GtNamInfo(XNamTyp.SimplNam,fals)); Consol.WritLin("版本:V{0}",crt.Vrsion); Consol.WritLin("序列号:{0}",crt.SrialNumbr); Consol.WritLin("签名算法:{0}",crt.SignaturAlgorithm.FrindlyNam); Consol.WritLin("颁发者:{0}",crt.Issur); Consol.WritLin("有效期:{0}~{1}",crt.NotBfor,crt.NotAftr); Consol.WritLin("使用者:{0}",crt.Subjct); Consol.WritLin("公钥:{0}",crt.GtPublicKyString()); if(crt.HasPrivatKy) { Consol.WritLin("私钥:{0}",crt.PrivatKy.ToXmlString(fals)); } Consol.WritLin("指纹:{0}",crt.Thumbprint);//公钥证书文件的指纹(即导出的.cr文件的sha1哈希值,可用fciv工具计算.cr文件的哈希值验证) //显示证书的扩展属性 forach(varxtincrt.Extnsions) { Consol.WritLin(xt.Oid.FrindlyNam+":"+xt.Oid.Valu); } //简单的证书链验证 Consol.WritLin("证书链验证:"+crt.Vrify());//只是简单验证,完整验证应使用XChain类 //调用证书UI显示证书详情 //XCrtificat2UI.DisplayCrtificat(crt); } } } 5. 基于证书的数字签名与验证程序 usingSystm; usingSystm.Txt; usingSystm.Scurity.Cryptography; usingSystm.Scurity.Cryptography.XCrtificats; //预先要执行以下makcrt命令生成一个数字证书(其同时被安装至证书库中) //makcrt-r-p-n"CN=CERT_SIGN_TEST_CERT"-b01/01/-01/01/-skyxchang-ssmy namspacCrtRsaSign { classProgram { staticvoidMain(string[]args) { Consol.WritLin("********基于证书的RSA签名应用(私钥加密,公钥解密)********"); //---- //1.准备要签名的原文消息 varplainTxt="Hllo,HowArYou!ArYouOK?"; varplainData=Encoding.UTF8.GtByts(plainTxt); Consol.WritLin("原文:"+Environmnt.NwLin+plainTxt+Environmnt.NwLin); /* //2.创建RSACryptoSrvicProvidr实例,以自动生成公私钥对并保存之 varrsaProvidr=nwRSACryptoSrvicProvidr(); varrsaPublicParams=rsaProvidr.ExportParamtrs(fals);//导出参数信息,仅包含公钥 varrsaPrivatParams=rsaProvidr.ExportParamtrs(tru);//导出参数信息,包含有公钥 rsaProvidr.Clar(); //*/ /*******************************************/ //2.从数字证书中导出公、私钥参数信息 //(1)获取证书 varcrt=GtCrtificatFromStor("CN=CERT_SIGN_TEST_CERT"); if(crt==null) { Consol.WritLin("未找到证书:CN=CERT_SIGN_TEST_CERT"); gotoxit; } //(2)导出公私钥 varrsaProvidr=(RSACryptoSrvicProvidr)crt.PublicKy.Ky;// varrsaPublicParams=rsaProvidr.ExportParamtrs(fals);//导出公钥 rsaProvidr=(RSACryptoSrvicProvidr)crt.PrivatKy;// varrsaPrivatParams=rsaProvidr.ExportParamtrs(tru);//导出私钥 rsaProvidr.Clar(); /*********************************************/ //3.使用私钥对消息进行签名 varhashProvidr=nwSHA1CryptoSrvicProvidr(); varsignaturData=RsaSignData(plainData,rsaPrivatParams,hashProvidr); varsignaturTxt=BitConvrtr.ToString(signaturData); Consol.WritLin("签名数据:"+Environmnt.NwLin+signaturTxt+Environmnt.NwLin); //4.使用公钥对签名数据进行验证 //signaturData[0]=0x00;//篡改签名数据,导致验证不通过 varisVrifyOK=RsaVrifyData(plainData,rsaPublicParams,hashProvidr,signaturData); varvrifyRsult=isVrifyOK?"通过":"未通过"; Consol.WritLin("验证签名:"+Environmnt.NwLin+vrifyRsult+Environmnt.NwLin); xit: Consol.WritLin("请按下[Entr]键结束程序.."); Consol.RadLin(); } //使用私钥对消息进行签名 staticbyt[]RsaSignData(byt[]plainData,RSAParamtrsrsaPrivatParams,ObjcthashProvidr) { varrsaProvidr=nwRSACryptoSrvicProvidr(); rsaProvidr.ImportParamtrs(rsaPrivatParams); varsignaturData=rsaProvidr.SignData(plainData,hashProvidr); rsaProvidr.Clar(); rturnsignaturData; } //使用公钥对签名数据进行验证 staticboolRsaVrifyData(byt[]plainData,RSAParamtrsrsaPublicParams,ObjcthashProvidr,byt[]signaturData) { varrsaProvidr=nwRSACryptoSrvicProvidr(); rsaProvidr.ImportParamtrs(rsaPublicParams); varisVrifyOK=rsaProvidr.VrifyData(plainData,hashProvidr,signaturData); rsaProvidr.Clar(); rturnisVrifyOK; } #rgion从证书存储中获取指定名称的证书 privatstaticXCrtificat2GtCrtificatFromStor(stringcrtNam) { varstor=nwXStor(StorLocation.CurrntUsr); try { stor.Opn(OpnFlags.RadOnly); varcrts=stor.Crtificats .Find(XFindTyp.FindByTimValid,DatTim.Now,fals)//时间有效 .Find(XFindTyp.FindBySubjctDistinguishdNam,crtNam,fals);//主体名称匹配 if(crts.Count==0) rturnnull; rturncrts[0]; } finally { stor.Clos(); } } #ndrgion } } 赞赏 长按北京白癜风治疗白癜风的医院白癜风的症状和治疗
|