版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、白話數(shù)字簽名 3 Web程序中的數(shù)字簽名 轉(zhuǎn)帖白話數(shù)字簽名(3)-Web程序中的數(shù)字簽名摘要閱讀本文并探索-如何突破Web程序無狀態(tài)性這個讓人抓狂的障礙實現(xiàn)自動顯示簽名結(jié)果和批量簽名功能。-如何將簽名功能封裝到一個實現(xiàn)了IHttpHandler接口的類庫中,使Client端的代碼盡可能的簡單。-使用數(shù)字簽名API函數(shù)需要注意的幾個問題。本文介紹在Web程序中使用數(shù)字簽名所遇到的特殊困難和解決方法,并給出一個超簡單但相當(dāng)實用的DEMO。DEMO程序的效果讓我們先來看看實現(xiàn)之后的效果。讓Client端代碼盡可能的簡單我們將數(shù)字簽名操作的復(fù)雜性全部封裝到一個命名空間為mylib.util.lnca的
2、類庫中,類庫只暴露一個名為Signer的類。Signer的Client(本例中的Default.aspx)的職責(zé)只有-構(gòu)造一個含有待簽名的數(shù)據(jù)的Dictionary作為Signer的輸入,然后調(diào)用Signer.do_sign()函數(shù)進行數(shù)字簽名。-在頁面上放置一個專門用于取得并顯示簽名結(jié)果的按鈕,并將這個按鈕的ClientID傳遞給Signer,這樣Signer在完成簽名后就可以自動觸發(fā)這個按鈕。在將程序發(fā)布給最終用戶時,要把這個按鈕的top屬性設(shè)為-10000,這樣最終用戶就看不到這個按鈕了。Default.aspx的設(shè)計視圖的截圖Default.aspx的源代碼如下%Page Langua
3、ge=C#AutoEventWireup=trueCodeFile=Default.aspx.csInherits=_Default%!DOCTYPE html PUBLIC-/W3C/DTD XHTML 1.0 Transitional/ENhtmlxmlns=headrunat=servertitle無標(biāo)題頁/title/head body formid=form1runat=servertable tr td asp:ButtonID=do_sign_buttonrunat=serverText=簽名OnClick=do_sign_button_Click/asp:LabelID=Lab
4、el1runat=serverText=Label/asp:Label/td td asp:ButtonID=show_signed_data_buttonrunat=serverText=顯示簽名結(jié)果(自動)OnClick=show_signed_data_button_Click/td/tr tr tdstyle=border:solid 1px black;vertical-align:top;asp:GridViewID=sign_candidates_gridviewrunat=serverCaption=簽名前的數(shù)據(jù)CellPadding=4ForeColor=#333333Fon
5、t-Names=宋體Font-Size=10ptFooterStyleBackColor=#1C5E55Font-Bold=TrueForeColor=White/RowStyleBackColor=#E3EAEB/EditRowStyleBackColor=#7C6F57/SelectedRowStyleBackColor=#C5BBAFFont-Bold=TrueForeColor=#333333/PagerStyleBackColor=#666666ForeColor=WhiteHorizontalAlign=Center/HeaderStyleBackColor=#1C5E55Font
6、-Bold=TrueForeColor=White/AlternatingRowStyleBackColor=White/asp:GridView/td tdstyle=border:solid 1px black;vertical-align:top;asp:GridViewID=signed_data_gridviewrunat=serverCaption=簽名結(jié)果BackColor=LightGoldenrodYellowBorderColor=TanBorderWidth=1pxCellPadding=2ForeColor=BlackOnRowDataBound=signed_data
7、_gridview_RowDataBoundFont-Names=宋體Font-Size=10ptFooterStyleBackColor=Tan/SelectedRowStyleBackColor=DarkSlateBlueForeColor=GhostWhite/PagerStyleBackColor=PaleGoldenrodForeColor=DarkSlateBlueHorizontalAlign=Center/HeaderStyleBackColor=TanFont-Bold=True/AlternatingRowStyleBackColor=PaleGoldenrod/asp:G
8、ridView/td/tr/table/form/body/html using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Collections.Generic;using
9、 mylib.util.lnca;public partialclass _Default:System.Web.UI.Pageprotectedvoid Page_Load(object sender,EventArgs e)protectedvoid do_sign_button_Click(object sender,EventArgs e)/這是待簽名的數(shù)據(jù),保存在一個Dictionary中。Key為數(shù)據(jù)的ID,Value為待簽名的數(shù)據(jù)。Dictionary string,string sign_candidates=new Dictionary string,string();sig
10、n_candidates.Add(1,123.45);sign_candidates.Add(2,678.90);sign_candidates.Add(3,zhf);sign_candidates.Add(4,7788);sign_candidates.Add(5,1-2-3);sign_candidates.Add(6,cnblogs);sign_candidates_gridview.DataSource=sign_candidates;sign_candidates_gridview.DataBind();/調(diào)用Signer.do_sign()進行簽名Signer.do_sign(Pa
11、ge,show_signed_data_button.ClientID,sign_candidates);protectedvoid show_signed_data_button_Click(object sender,EventArgs e)if(Signer.error_code=0)/簽名成功signed_data_gridview.DataSource=Signer.signed_datas;signed_data_gridview.DataBind();else/簽名失敗Label1.Text=Signer.error_message;protectedvoid signed_da
12、ta_gridview_RowDataBound(object sender,GridViewRowEventArgs e)/每個簽名結(jié)果的長度都要將近2000個字符,會把GridView撐得很大,為了方便寫B(tài)log時截圖,我/加了一個滾動條,實際作程序時是不需將簽名數(shù)據(jù)顯示給用戶看的,也就用不著這段代碼了。if(e.Row.RowType=DataControlRowType.DataRow)string content=e.Row.Cells1.Text;e.Row.Cells1.Text=div style=overflow:auto;width:300px;height:150px;+
13、content+/div;由于Signer是一個HTTP處理程序,所以需要在Web.config中添加一行對Signer.ashx的注冊:?xml version=1.0?configuration appSettings/connectionStrings/system.web httpHandlers addpath=Signer.ashxverb=*type=mylib.util.lnca.Signer,mylib.util.lncavalidate=false/httpHandlers/system.web/configuration有關(guān)HTTP處理程序的創(chuàng)建和應(yīng)用,可以看實戰(zhàn)HTTP
14、處理程序(HTTP Handler)系列。由于我們把復(fù)雜性都放在了Signer.cs中,Signer.cs的代碼有些長,我們會在后面討論它的幾個要點。1 using System;2 using System.Collections.Generic;3 using System.Text;4 using System.Web;5 using System.Web.UI;6 using System.Web.SessionState;7 using mylib.util.lnca.Properties;8 using System.Diagnostics;9 10 namespace mylib
15、.util.lnca 1112 publicclass Signer:IHttpHandler,IRequiresSessionState 1314/summary 15/Opens anew window to do signing.16/Example 17/Dictionary string,string sign_candidates=new Dictionary string,string();18/sign_candidates.Add(1,123.45);19/sign_candidates.Add(2,678.90);20/sign_candidates.Add(3,zhf);
16、21/sign_candidates.Add(4,7788);22/sign_candidates.Add(5,1-2-3);23/sign_candidates.Add(6,cnblogs);24/Signer.do_sign(Page,on_finished_signing_button.ClientID,sign_candidates);25/summary 26 publicstaticvoid do_sign(Page page,string on_signing_finished_button_client_id,27 Dictionary string,string sign_c
17、andidates)2829 Debug.Assert(sign_candidates!=null,sign_candidates should not be null);30 31 Signer.sign_candidates=sign_candidates;32 Signer.sign_candidates_enumerator=Signer.sign_candidates.GetEnumerator();33 Signer.on_signing_finished_button_client_id=on_signing_finished_button_client_id;34 35/ini
18、tializes Signer.signed_datas 36 Signer.signed_datas=new Dictionary string,string();37 Signer.signing_counter=0;38 foreach(string keyin sign_candidates.Keys)3940 Signer.signed_datas.Add(key,);4142 43 error_code=0;44 error_message=;45 46 if(!page.ClientScript.IsStartupScriptRegistered(page.GetType(),O
19、penSignerWindow)4748 page.ClientScript.RegisterStartupScript(page.GetType(),OpenSignerWindow,49window.open(Signer.ashx,Signer_ashx,height=100,alwaysRaised=true,width=200,top=300,left=400,toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,status=no);,true);505152 53/summary 54/Stores error_
20、code during signing.55/summary 56 publicstaticlong error_code 5758 getreturn(long)System.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.error_code;59 setSystem.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.error_code=value;6061 62/summary 63/Stores error_message during signing.64/summ
21、ary 65 publicstaticstring error_message 6667 getreturn System.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.error_messageasstring;68 setSystem.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.error_message=value;6970 71/summary 72/Stores datas had be signed.73/summary 74 publicstatic Di
22、ctionary string,string signed_datas 7576 getreturn System.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.signed_datasas Dictionary string,string;77 setSystem.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.signed_datas=value;7879 80/summary 81/The enumerator of sign_candidates 82/summar
23、y 83 privatestatic IEnumerator KeyValuePair string,string sign_candidates_enumerator 8485 getreturn System.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.sign_candidates_enumeratoras IEnumerator KeyValuePair string,string;86 setSystem.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.sign
24、_candidates_enumerator=value;8788 89/summary 90/Datas needs signing.91/summary 92 privatestatic Dictionary string,string sign_candidates 9394 get 9596 return System.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.sign_candidatesas Dictionary string,string;9798 set 99100 System.Web.HttpContext.
25、Current.Sessionmylib.util.lnca.Signer.sign_candidates=value;101102103 104/Returns the current signing progress.105 privatestaticint signing_counter 106107 getreturn(int)System.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.signing_counter;108 setSystem.Web.HttpContext.Current.Sessionmylib.uti
26、l.lnca.Signer.signing_counter=value;109110 111/summary 112/Returns javascript code called doSignData()function at client.113/param name=sourceData想要進行簽名的數(shù)據(jù)/param 114/param name=signAlgo簽名算法,推薦使用SignAlgo.RSA_MD5/param 115/param name=isAddSignCert是否在結(jié)果中攜帶證書/param 116/param name=isAddSrcData是否在結(jié)果中攜帶原文/
27、param 117/param name=innerOid數(shù)據(jù)類型,使用InnerOid.EMPUTY即可/param 118/param name=isAddTime是否添加簽名時間/param 119/param name=pin用戶口令,如果設(shè)為空字符串,則每次都會提示用戶輸入密碼;如果在此參數(shù)中傳入了正確的密碼,則只要求用戶輸入密碼一次./param 120/summary 121 privatestring sign_data(string source_data,string sign_algo,bool is_add_sign_cert,bool is_add_src_data,
28、string inner_oid,long is_add_time,string pin)122123 returnstring.Format(doSignData(0,1,2,3,4,5,6);,124 source_data,125 sign_algo,126 is_add_sign_cert=true?1:0,127 is_add_src_data=true?1:0,128 inner_oid,129 is_add_time,130 pin);131132 133/summary 134/Alias of sign_data(source_data,SignAlgo.RSA_MD5,is
29、_add_sign_cert,true,InnerOid.EMPUTY,0,string.Empty)135/summary 136 privatestring sign_data(string source_data,bool is_add_sign_cert)137138 return sign_data(source_data,SignAlgo.RSA_MD5,is_add_sign_cert,true,InnerOid.EMPUTY,0,string.Empty);139140 141/summary 142/Alias of sign_data(source_data,SignAlg
30、o.RSA_MD5,true,true,InnerOid.EMPUTY,0,string.Empty);143/summary 144 privatestring sign_data(string source_data)145146 return sign_data(source_data,SignAlgo.RSA_MD5,true,true,InnerOid.EMPUTY,0,string.Empty);147148 149/summary 150/Returns signed data from HiddenFields in form.151/summary 152 privatest
31、ring get_signed_data(HttpRequest request)153154 if(get_error_code(request)!=0)155156 returnstring.Empty;157158 159 if(request.FormSigner_SubPage_SignedData_HiddenField=null)160161 returnstring.Empty;162163 164 return request.FormSigner_SubPage_SignedData_HiddenField.ToString();165166 167/summary 168
32、/Returns error_code from the HiddenField in form.169/summary 170 privatelong get_error_code(HttpRequest request)171172 if(request.FormSigner_SubPage_ErrorCode_HiddenField=null)173174 return-1;175176 177 try 178179 returnlong.Parse(request.FormSigner_SubPage_ErrorCode_HiddenField.ToString();180181 ca
33、tch(Exception)182183 return-1;184185186 187/summary 188/Returns error_message from the HiddenField in form.189/summary 190 privatestring get_error_message(HttpRequest request)191192 if(get_error_code(request)=-1)193194 return取得簽名結(jié)果失敗。;195196 197 if(request.FormSigner_SubPage_ErrorMessage_HiddenField
34、=null)198199 returnstring.Empty;200201 202 return request.FormSigner_SubPage_ErrorMessage_HiddenField.ToString();203204 205/summary 206/Stores the client_id of button of father page wants to auto trigger.207/summary 208 privatestaticstring on_signing_finished_button_client_id 209210 getreturn System
35、.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.on_signing_finished_button_client_idasstring;211 setSystem.Web.HttpContext.Current.Sessionmylib.util.lnca.Signer.on_signing_finished_button_client_id=value;212213 214 publicbool IsReusable 215216 getreturntrue;217218 219 publicvoid ProcessReques
36、t(System.Web.HttpContext context)220221 context.Response.Clear();222 context.Response.ContentType=text/html;223 context.Response.Write(!DOCTYPE html PUBLIC-/W3C/DTD XHTML 1.0 Transitional/EN);224 context.Response.Write(html xmlns=+Environment.NewLine);225 context.Response.Write(title簽名中/title);226 c
37、ontext.Response.Write(form name=form1method=postid=form1+Environment.NewLine);227 context.Response.Write(Settings.Default.controls+Environment.NewLine);228 context.Response.Write(Settings.Default.js+Environment.NewLine);229 230 if(sign_candidates_enumerator.Current.Key!=null)/not first reach here.23
38、1232 if(get_error_code(context.Request)=0)/signing success 233234 signed_datassign_candidates_enumerator.Current.Key=get_signed_data(context.Request);/gathers signed data.235236 else/signing failed.237238/sets error_code and error_message 239 error_code=get_error_code(context.Request);240 error_mess
39、age=get_error_message(context.Request);241/terminates signing 242 context.Response.Write(script type=text/javascript+Environment.NewLine);243 context.Response.Write(244 string.Format(opener.document.getElementById_x(0).click();,on_signing_finished_button_client_id);245 context.Response.Write(window.
40、close(););246 context.Response.Write(/script+Environment.NewLine);247248249 250 if(sign_candidates_enumerator.MoveNext()251252 signing_counter+;253 context.Response.Write(span正在簽名+signing_counter.ToString()+/+sign_candidates.Count.ToString()+/span);254 context.Response.Write(script type=text/javascr
41、ipt+Environment.NewLine);255 context.Response.Write(sign_data(sign_candidates_enumerator.Current.Value)+Environment.NewLine);256 context.Response.Write(/script+Environment.NewLine);257258 else 259260 context.Response.Write(script type=text/javascript+Environment.NewLine);261 context.Response.Write(2
42、62 string.Format(opener.document.getElementById_x(0).click();,on_signing_finished_button_client_id);263 context.Response.Write(window.close(););264 context.Response.Write(/script+Environment.NewLine);265266 context.Response.Write(/form+Environment.NewLine);267 context.Response.Write(/html+Environmen
43、t.NewLine);268269/class Signer 270/namespace mylib.util.lnca 271 Signer.cs的第227和228行的Settings.Default.controls和Settings.Default.js是需要發(fā)送給客戶端瀏覽器用于回傳簽名結(jié)果的HiddenFields和執(zhí)行簽名操作的Javascript語句。我把它們放在了類庫的配置文件里,它們的代碼如下:1 objectid=subpage_Signer_SubPage_LNCAToolkitsclassid=clsid:6FBE853D-0DB0-4C62-B7DC-B49E9D44
44、7AF9style=width:0px;2 height:0px;codebase=3/object 4inputid=Signer_SubPage_ErrorCode_HiddenFieldname=Signer_SubPage_ErrorCode_HiddenFieldtype=hidden/5 inputid=Signer_SubPage_ErrorMessage_HiddenFieldname=Signer_SubPage_ErrorMessage_HiddenFieldtype=hidden/6 inputid=Signer_SubPage_SignedData_HiddenFiel
45、dname=Signer_SubPage_SignedData_HiddenFieldtype=hidden/1 script type=text/javascript2 function doSignData(sourceData,signAlgo,isAddSignCert,isAddSrcData,innerOid,isAddTime,pin)34 var caTool=document.getElementById_x(subpage_Signer_SubPage_LNCAToolkits);5 var ret=caTool.EnumClientCert();6 7if(ret=0)8
46、9 var signedData=caTool.SignDataEx(sourceData,signAlgo,isAddSignCert,isAddSignCert,innerOid,isAddTime,pin);10 11 document.getElementById_x(Signer_SubPage_ErrorCode_HiddenField).value=caTool.ErrorCode;12 document.getElementById_x(Signer_SubPage_ErrorMessage_HiddenField).value=caTool.ErrorMessage;13 d
47、ocument.getElementById_x(Signer_SubPage_SignedData_HiddenField).value=signedData;1415 else 1617 document.getElementById_x(Signer_SubPage_ErrorCode_HiddenField).value=caTool.ErrorCode;18 document.getElementById_x(Signer_SubPage_ErrorMessage_HiddenField).value=caTool.ErrorMessage;19 document.getElemen
48、tById_x(Signer_SubPage_SignedData_HiddenField).value=;2021 22 document.forms0.submit();2324/script自動顯示簽名結(jié)果我們想要實現(xiàn)這樣的交互效果:用戶選定想要進行簽名的數(shù)據(jù)后,只要按一個按鈕就會自動彈出一個小窗體顯示簽名的進度;當(dāng)簽名結(jié)束后,可以自動顯示簽名結(jié)果,就像上面那個DEMO程序所展示的那樣。如果我們開發(fā)的是WinForm的信息系統(tǒng),實現(xiàn)這樣的效果簡直易如反掌??墒窃赪eb程序中,我們卻遇到了一點麻煩。自動顯示簽名結(jié)果的困難正如我們在第2篇所介紹的,為了防復(fù)制破解,我們是使用USB Key做數(shù)
49、字簽名。這個USB Key必須插在客戶端的電腦上,我們在Server端無法直接控制它,只能通過在客戶端瀏覽器上執(zhí)行的javascript代碼調(diào)用一個由遼寧CA認證中心開發(fā)的一個ActiveX控件操作USB Key進行簽名,再將簽名結(jié)果通過HiddenFields Post回Server端-不過這個Server端已經(jīng)不是以前的Server端了,Web程序的這種無狀態(tài)性沒少讓我們吃虧。換句話說,我們沒辦法像下面這樣寫(偽碼):protected void do_sign_button_Click(object sender,EventArgs e)1 Dictionary string,strin
50、g sign_candidates=prepare_sign_candidates();2 Dictionary string,string signed_datas=excute javascript at client browser to sign data,and return signed datas 3signed_data_gridview.DataSource=signed_datas;4 signed_data_gridview.DataBind();實現(xiàn)自動顯示簽名結(jié)果我們遇到的問題的實質(zhì)是:準(zhǔn)備簽名數(shù)據(jù)(偽代碼第1行)、顯示簽名結(jié)果(偽代碼第3、4行)的操作在Server
51、端進行;而使用USB Key進行簽名的操作(偽代碼第2行)必須在Client端的瀏覽器上執(zhí)行,并且這兩種操作是異步的!所以我們只能將顯示簽名結(jié)果的代碼放到另一個函數(shù)中,在簽名結(jié)束后以某種方法觸發(fā)它。我們在Demo中所使用的方法是,將顯示簽名結(jié)果的代碼放到顯示簽名結(jié)果(自動)按鈕的Click事件中,在簽名結(jié)束后,使用javascript:opener.document.getElementById_x(show_signed_data_button.ClientID).click();來觸發(fā)這個按鈕的Click事件。思考題我們使用一個偽隱藏的按鈕可以簡單地實現(xiàn)自動顯示簽名結(jié)果的效果,不過這種作法
52、似乎有點土。你能否使用其它更高級的方法來實現(xiàn)同樣的效果?實現(xiàn)批量簽名我們需要讓用戶按一次按鈕,就可以簽名n條數(shù)據(jù),可是數(shù)字簽名API SignDataEx(sourcedata,.)一次只能簽名一條數(shù)據(jù)。我們需要遍歷每條待簽名數(shù)據(jù),調(diào)用SignDataEx()進行簽名。我們有兩種選擇:1.在Server端進行遍歷,每次傳送一條數(shù)據(jù)給Client端進行簽名。2.將n條待簽名數(shù)據(jù)一次全部傳給Client端,在Client端使用javascript的for循環(huán)遍歷待簽名數(shù)據(jù)并進行簽名。我們在Demo程序中是使用了第1種方法。基于和自動顯示簽名結(jié)果一節(jié)所述的同樣的困難,我們無法在Signer.cs的P
53、rocessRequest()中這樣寫(偽碼):public void ProcessRequest(System.Web.HttpContext context)foreach(string key in sign_candidates.Keys)string signed_data=excute javascript at client browser to sign data,and return signed data好在已經(jīng)有大師發(fā)明了外部迭代器(external iterator),我們可以在第一次迭代之前,先創(chuàng)建一個待簽名數(shù)據(jù)的一個外部迭代器,并把它保存在Session中。每次簽
54、名后,Client端PostBack回Server端,在Server端從Session中取出這個外部迭代器,調(diào)用sign_candidates_enumerator.MoveNext(),之后繼續(xù)向Client端發(fā)送簽名用的javascript語句,直至完成全部遍歷,請參見Signer.cs的250268行。下面的時序圖表示批量簽名3條數(shù)據(jù)的過程。思考題我們的DEMO實現(xiàn)了第1種方法,你能否實現(xiàn)第2種方法?這兩種實現(xiàn)方法各有什么優(yōu)缺點?綜合起來我們把批量簽名與自動顯示簽名結(jié)果的功能都放在Signer.cs中,可以用下面這個經(jīng)過簡化的時序圖來表示。附錄數(shù)字簽名API簡介我們使用的是遼寧省數(shù)字認證
55、中心發(fā)放的數(shù)字證書。他們還提供了兩套數(shù)字簽名API:一個是ActiveX控件;一個是COM組件。兩套API都有完整、豐富的數(shù)字簽名相關(guān)的函數(shù),可以單獨使用。如果是WinForm程序,直接使用COM組件即可。不過由于Web程序必須使用ActiveX控件,所以我們在作數(shù)字簽名的時候使用ActiveX控件,在驗證簽名的時候使用COM組件。也許您手頭的API和我們使用的API并不相同,不過您仍然可以下載這兩套API的手冊找找感覺。LNCAToolkits控件(通用版)程序員手冊_v2.pdf-這個是ActiveX控件的手冊LNCA-CryptoAPI-Com版程序員手冊_v1.pdf-這個是COM組件
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣東揭榜制科技協(xié)議書
- 工業(yè)廠房代建合同范本
- 工程售賣居間合同范本
- 對口班入學(xué)協(xié)議書模板
- 打印室承包協(xié)議書范本
- 學(xué)校招聘保安合同范本
- 危重病人的風(fēng)險評估及護理安全
- 冀教版七年級數(shù)學(xué)下冊對頂角和三線八角張教案
- 理順前后序簡明表其意結(jié)構(gòu)把握類教案
- 道路標(biāo)線的施工工藝質(zhì)量控制教案(2025-2026學(xué)年)
- 2025-2030房地產(chǎn)行業(yè)人才結(jié)構(gòu)轉(zhuǎn)型與復(fù)合型培養(yǎng)體系構(gòu)建
- 道路車輛汽車列車多車輛間連接裝置強度要求
- 樂高大班匯報課
- 2026年度安全生產(chǎn)工作計劃
- 社區(qū)教育師資管理辦法
- 自動駕駛汽車在自動駕駛電動游艇領(lǐng)域的應(yīng)用前景研究報告
- 電纜銷售員知識培訓(xùn)內(nèi)容課件
- 西南空管面試題目及答案
- 醫(yī)療器械銷售年終匯報
- 煤礦數(shù)據(jù)管理辦法
- 《設(shè)備故障診斷與維修》課件-項目二 設(shè)備故障診斷
評論
0/150
提交評論