1、序言 非接觸式智能卡已經(jīng)廣泛地應(yīng)用于各類門禁控制系統(tǒng),公共交通支付系統(tǒng),e-purse系統(tǒng),高速公路不停車收費(fèi)系統(tǒng),IBMS(智能大樓管理系統(tǒng)),海關(guān)過(guò)境身份識(shí)別,以及醫(yī)療保險(xiǎn)系統(tǒng)等等。 非接觸式智能卡以其高度安全保密性,通信高速性,使用方便性,成本日漸低廉等而受到廣泛使用,給我們的生活質(zhì)量帶來(lái)了很大的提高。因此,如何認(rèn)識(shí)、理解智能卡,特別是帶有非常神秘色彩的非接觸式智能卡,已引起很多智能卡的使用者,包括智能卡專業(yè)研發(fā)的IT科研人員的極大的興趣和愛(ài)好。筆者在此很愿意將自己多年來(lái)在智能卡(接觸式智能卡及非接觸式智能卡)方面的研究及其軟硬件應(yīng)用開(kāi)發(fā)的經(jīng)驗(yàn)與大家一同交流和分享,以取得我國(guó)金卡工程事業(yè)的更進(jìn)一步的發(fā)展。 在此,筆者將以符合ISO/IEC14443TYPEA標(biāo)準(zhǔn)的Mifare1S50系列非接觸式智能卡及其讀寫設(shè)備專用IC(ASIC)RC150/170模塊為對(duì)象,與大家一起就“關(guān)于非接觸式智能卡及其讀寫器ASIC模塊之‘密碼操作’”作一些研究與探討,并將用標(biāo)準(zhǔn)的Intel-51系列微處理器匯編語(yǔ)言進(jìn)行實(shí)際的應(yīng)用程序的開(kāi)發(fā)。在筆者曾設(shè)計(jì)和開(kāi)發(fā)的眾多智能卡項(xiàng)目中,本文所給出的應(yīng)用程序都有著良好的運(yùn)行效果。
2、非接觸式智能卡及其讀寫器ASIC模塊RC150/170 Mifare1S50非接觸式智能卡片有著16個(gè)Sector(扇區(qū));每個(gè)Sector包含4個(gè)Block(塊);每個(gè)Block具有16個(gè)byte的存儲(chǔ)容量。Sector被定義為Sector0至Sector15;Block被分為Block0至Block3;整個(gè)Mifare1S50非接觸式智能卡共有64個(gè)Block。 Sector0中的Block0記錄了該張智能卡的序列號(hào)(SerialNumber)以及生產(chǎn)廠商的標(biāo)志信息等,這些信息已在卡片出廠時(shí)固化,不能更改。因此該Block不能再?gòu)?fù)用為應(yīng)用數(shù)據(jù)塊。 每個(gè)Sector中的Block3被特別用來(lái)存放對(duì)該Sector中應(yīng)用塊Block0,1,2及其本身Block3進(jìn)行數(shù)據(jù)存取的密碼及存取權(quán)限。整個(gè)Mifare1S50非接觸式智能卡共有16個(gè)Block3。根據(jù)絕對(duì)地址編址,他們可被編為Block3(在Sector0中),Block7(在Sector1中),Block11(在Sector2中),以及Block63(在Sector15中)等等。 對(duì)于某一Sector中的Block3的絕對(duì)地址編址可以由下列公式計(jì)算得到: Block X=(N+1)*4-1 其中:X:絕對(duì)地址編址的Block塊號(hào) N:Sector扇號(hào),0至15 通常每個(gè)扇區(qū)的Block0,1,2都存放著非常保密的數(shù)據(jù),例如坐公交車/出租車前在公交公司指定地點(diǎn)已購(gòu)買的車資錢款,智能大廈/智能小區(qū)進(jìn)出時(shí)所需的控制信息,股票交易時(shí)持有股票交易智能卡片者必須對(duì)已存放在智能卡中的交易密碼數(shù)據(jù)(例如帳戶、存款信息、已買進(jìn)股票數(shù)量/品種等等)進(jìn)行確認(rèn),才能得以股票交易,等等。 由于每一個(gè)Block3中包含了該扇區(qū)的密碼字節(jié)以及對(duì)該扇區(qū)中其余Block0,1,2進(jìn)行數(shù)據(jù)處理的存取控制權(quán)限字節(jié),因此如何操作處理Block3將是很重要的內(nèi)容。以下將展開(kāi)對(duì)每個(gè)扇區(qū)的Block3進(jìn)行研究。 Block3有16個(gè)byte組成。前6個(gè)字節(jié)是密碼A(KEYA),KEYA的缺省值可能為“A0A1A2A3A4A5”;最后6個(gè)字節(jié)是密碼B(KEYB),KEYB的缺省值可能為“B0B1B2B3B4B5”;中間4個(gè)字節(jié)是控制字節(jié),缺省值可能為“FFH07H80H69H”;利用KEYA或KEYB并遵守早已定義在4個(gè)控制字節(jié)中的存取條件,我們便能對(duì)該密碼(KEYA或KEYB)所對(duì)應(yīng)的Sector內(nèi)的應(yīng)用塊Block0,1,2進(jìn)行數(shù)據(jù)讀/寫/更新等操作。 由于非接觸式智能卡的操作,包括數(shù)據(jù)流的傳遞等都是以“非接觸”方式來(lái)完成的,因此在MCU與非接觸式智能卡之間必須有一個(gè)傳遞密碼(或數(shù)據(jù)流)的中間媒體,即ASIC模塊。RC150/170就是這樣一種ASIC模塊。它擔(dān)負(fù)著非接觸式智能卡與MCU(微處理機(jī))之間所有的密碼/數(shù)據(jù)相互傳遞的重要任務(wù)。對(duì)非接觸式智能卡進(jìn)行密碼操作,變成對(duì)RC150/170ASIC模塊進(jìn)行密碼操作。RC150/170ASIC模塊與非接觸式智能卡之間的信息傳遞(包括密碼等)對(duì)用戶來(lái)說(shuō)是透明的,會(huì)自動(dòng)傳遞并完成。因此如何對(duì)非接觸式智能卡進(jìn)行“密碼操作”(對(duì)Block3的操作)變成如何對(duì)RC150/170ASIC模塊進(jìn)行密碼操作。Philips公司的MCM200模塊,MCM500模塊或SB201,SB601(Uni-VisionEngineeringLtd.的產(chǎn)品)模塊中都包含有RC150/170ASIC模塊,因此本文所討論的內(nèi)容,包括下面設(shè)計(jì)的程序等,也適用于這些模塊。RC170是RC150的新一代ASIC模塊,速度較快。 現(xiàn)在我們廣泛使用的非接觸式智能卡讀寫設(shè)備中大都包含有以上所列的ASIC模塊之一。 圖1顯示了在用戶(MCU)與非接觸式智能卡之間基本的密碼傳輸關(guān)系,并請(qǐng)?zhí)貏e注意ASIC模塊RC150/170的作用等等。
圖1ASIC模塊密碼傳輸關(guān)系圖 在研究ASIC模塊RC150/170的時(shí)候,我們必須關(guān)注所有與“密碼操作”有關(guān)的寄存器/存儲(chǔ)器的情況。 ●密碼數(shù)據(jù)寄存器KeyDataRegister(寄存器地址:0x0A); ●密碼地址寄存器KeyAddressRegister(寄存器地址:0x0C); ●密碼狀態(tài)/控制寄存器KeyStatus&ControlRegister(KEYSTACON)(寄存器地址:0x0B); ●其他相關(guān)寄存器。 所有這些與“密碼操作”相關(guān)的寄存器都是“只可寫不可讀”的,即WOM(Write-Only-Memory)。因此不要試圖去讀取這些寄存器的內(nèi)容。
3、“密碼操作”的研究及其應(yīng)用程序開(kāi)發(fā) 通常,對(duì)非接觸式智能卡的“密碼操作”有兩個(gè)主要步驟。每一個(gè)主要步驟又有若干個(gè)小的步驟有序并且必須是連續(xù)地完成。 “密碼操作”的兩個(gè)主要步驟是: ●“LOAD_KEY”密碼存取 ●“AUTHENTICATION”密碼認(rèn)證
3.1“LOAD_KEY”密碼存取 “LOAD_KEY”密碼存取必須由以下步驟有序并連續(xù)地完成: ●設(shè)置新的密碼值 ●設(shè)置密碼狀態(tài)/控制寄存器KeyStatus&ControlRegister(KEYSTACON) ●設(shè)置密碼地址寄存器KeyAddressRegister(寄存器地址:0x0C) ●設(shè)置密碼數(shù)據(jù)寄存器KeyDataRegister(寄存器地址:0x0A) ●校驗(yàn)STACON寄存器,以確定這次的“LOAD_KEY”密碼存取是否有效 以下將按照上述的次序進(jìn)行具體的程序設(shè)計(jì),所有的程序都使用標(biāo)準(zhǔn)的Intel-51MCU指令,以利于讀者在LOW-LEVEL級(jí)上移植到其相應(yīng)的應(yīng)用項(xiàng)目中。
3.1.1設(shè)置新的密碼值 新的密碼值為6個(gè)bytes,在如下的程序設(shè)計(jì)中被依次存放在MCU內(nèi)部RAM的72H~77H的6個(gè)單元中;程序員亦可自定義其他的存儲(chǔ)單元作為新的密碼值存放的緩沖區(qū);R1寄存器為新密碼緩存首地址指針。如下所設(shè)置新的密碼值為:“AAAAAAAAAAAA” SETUP_NEW_KEY_VALUE: ;MOV R7,#06H;密碼長(zhǎng)度為6bytes MOV R1,#72H;R1為新密碼緩存首地址指針 MOV @R1,#0AAH;設(shè)置新密碼值 MOV 73H,#0AAH MOV 74H,#0AAH MOV 75H,#0AAH MOV 76H,#0AAH MOV 77H,#0AAH 良好的經(jīng)驗(yàn)告訴我們,為了確保整個(gè)智能卡系統(tǒng)的高度安全保密,我們有必要在程序設(shè)計(jì)中,在完成了“密碼操作”之后,立即清除存放新的密碼值的緩沖區(qū),簡(jiǎn)單的方法如下: CLEAR_NEW_KEY_BUFFER: MOV R7,#06H;密碼長(zhǎng)度為6bytes MOV R1,#72H;R1為新密碼緩存首地址指針 CLEAR_LOOP: MOV @R1,#00H;清除新密碼值所在緩沖區(qū) INC R1 DJNZ R7,CLEAR_LOOP
3.1.2設(shè)置密碼狀態(tài)/控制寄存器KeyStatus&ControlRegister(KEYSTACON) KEYSTACON寄存器是一個(gè)只可讀不可寫的寄存器(存儲(chǔ)器),它指示出“密碼操作”時(shí)所處的狀態(tài)和要控制的ASIC內(nèi)部“密碼存儲(chǔ)器RAM”的選擇。這里所指的“狀態(tài)”是指本次“密碼操作”兩個(gè)主要步驟中的一個(gè)。 KEYSTACON寄存器是一個(gè)8-bit的存儲(chǔ)器,其中有用的位(bit)只有3位。其具體內(nèi)容為:
其中,MSB(“A/L”位)若被設(shè)置為“0”,則意味著當(dāng)前“密碼操作”的“狀態(tài)”是“LOAD_KEY(密碼存取)”;若被設(shè)置為“1”,則當(dāng)前“密碼操作”的“狀態(tài)”是“AUTHENTICATION(密碼認(rèn)證)”。 最后 2個(gè)bit:KS0KS1是密碼集keyset的選擇。在ASIC中共有3套密碼集(keyset)和一個(gè)傳輸密碼(TransportKey)可被選擇。設(shè)置KS0、KS1的值實(shí)際上是在選擇(尋址)ASIC模塊內(nèi)部存放密碼的不同的存儲(chǔ)器單元(密碼箱)。如果“LOAD_KEY”(密碼存取)時(shí)使用了keyset0,則“AUTHENTICATION”(密碼認(rèn)證)時(shí)只能使用keyset0,而不能使用keyset1或keyset2或其他,因?yàn)樵贏SIC模塊內(nèi),keyset0指定的密碼存儲(chǔ)器地址單元與keyset1或keyset2所指定的密碼存儲(chǔ)器地址單元是不同的單元。這就好比去超級(jí)市場(chǎng)購(gòu)物,入超市前您把您的包裹寄存在超市門前包裹箱A中,并得到打印有開(kāi)起包裹箱A的(開(kāi)箱)密碼紙條;當(dāng)您欲取回包裹時(shí),拿著包裹箱A的(開(kāi)箱)密碼紙條而去開(kāi)包裹箱B或C的箱門,當(dāng)然不能打開(kāi),因?yàn)槟牡刂罚ㄏ涮?hào))不對(duì),當(dāng)然您的包裹也不能拿到。這是密碼的認(rèn)證出錯(cuò)。在ASIC中有相同之處。如果“LOAD_KEY”(密碼存?。r(shí)使用了keyset0,并存放上密碼,而在“AUTHENTICATION”(密碼認(rèn)證)時(shí)卻使用keyset1或keyset2或其他而來(lái)驗(yàn)證剛才存放的密碼,當(dāng)然會(huì)得到ASIC模塊返回的認(rèn)證出錯(cuò)(“AE=1”)。 當(dāng)KS1KS0=“00”時(shí),選擇使用keyset0; 當(dāng)KS1KS0=“01”時(shí),選擇使用keyset1; 當(dāng)KS1KS0=“10”時(shí),選擇使用keyset2; 當(dāng)KS1KS0=“11”時(shí),選擇使用傳輸密碼(TransportKey)。 以下是設(shè)置密碼狀態(tài)/控制寄存器KeyStatus&ControlRegister(KEYSTACON)的程序: SETUP_KEYSTACON: MOV 7EH,#00000000B;選擇使用keyset0,并指明是“LOAD_KEY” MOV A,7EH ;7EH單元存放了設(shè)置KEYSTACON的值 MOV R0,#0BH ;KEYSTACON寄存器地址為0Bh OVX @R0,A ;設(shè)置KEYSTACON寄存器 如果我們要選擇使用keyset2,則相應(yīng)可以設(shè)置7EH單元為#00000010b(0x02),即: MOV 7EH,#00000010B
3.1.3設(shè)置密碼地址寄存器KeyAddressRegister(寄存器地址:0x0C) 在成功地完成了對(duì)密碼狀態(tài)/控制寄存器(KEYSTACON)的設(shè)置之后,必須立即對(duì)密碼地址寄存器KeyAddressRegister進(jìn)行設(shè)置,而不能對(duì)密碼數(shù)據(jù)寄存器KeyDataRegister進(jìn)行設(shè)置或做其他設(shè)置,否則將出錯(cuò)。因?yàn)锳SIC內(nèi)部接收MCU指令/數(shù)據(jù)的存儲(chǔ)單元是按照FIFO(“FirstInFirstOut”即“先進(jìn)先出”)方式工作的。 由于一張非接觸式智能卡有16個(gè)Sector(扇區(qū)),并且每個(gè)Sector都可能有著各自不同的密碼,因此在ASIC模塊中就會(huì)有不同的密碼存儲(chǔ)器與之相對(duì)應(yīng)。當(dāng)對(duì)16個(gè)Sector中的一個(gè)Sector進(jìn)行密碼操作時(shí),就必須對(duì)ASIC模塊中與該Sector對(duì)應(yīng)的密碼存儲(chǔ)器進(jìn)行尋址,找到這一密碼存儲(chǔ)器確切位置。不過(guò),MCU送出的尋址地址只是ASIC在其內(nèi)部做第二次尋址(地址變化)的“一部分”地址。這里所指的“一部分”是出于高度安全保密的原因。 以下是8位(bit)密碼地址寄存器的說(shuō)明:
這里, ●MSB(“A/L”bit)與KEYSTACON寄存器中的MSB有著相同的意義; ●“A/B”bit位指出MCU要使用的密碼的類型。當(dāng)“A/B”=“0”時(shí),MCU使用KEYA;當(dāng)“A/B”=“1”時(shí),MCU使用KEYB; ●“A5~A0”指出要求密碼操作的某一Sector的地址。當(dāng)要對(duì)Sector0進(jìn)行密碼操作時(shí),“A5~A0”應(yīng)該被設(shè)置為“00000b”(0x00);如果是Sector1,“A5~A0”應(yīng)該被設(shè)置為“00001b”(0x01);如果是Sector5,“A5~A0”應(yīng)該被設(shè)置為“00101b(0x05),等等。 以下是設(shè)置密碼地址寄存器KeyAddressRegister的程序: SETUP_Key_Address_Reg: MOV 7DH,#00000001B ;使用KEYA,對(duì)Sector1進(jìn)行“LOAD_KEY” MOV A,7DH ;7DH單元存儲(chǔ)了密碼地址寄存器值 MOV R0,#0CH ;密碼地址寄存器地址為“0Ch” MOV X@R0,A ;設(shè)置密碼地址寄存器 如果要對(duì)Sector1使用KEYB,則7DH單元必須設(shè)置為“#01000001b”(0x41),即: MOV 7DH,#01000001B 更進(jìn)一步,如果要對(duì)Sector5使用KEYB,則7DH單元必須設(shè)置為“#01000101b”(0x45),即: V 7DH,#01000101B 這樣,Sector5中Block0,1,2(相應(yīng)于絕對(duì)塊地址為:Block20,21,22)中原有數(shù)據(jù)將可以被操作。Sector5中Block3也可以按照預(yù)先定義的存取控制條件而被改寫密碼,或被讀出密碼或控制字節(jié)。
3.1.4設(shè)置密碼數(shù)據(jù)寄存器KeyDataRegister(寄存器地址:0x0A) 如果成功地完成了以上幾個(gè)方面的設(shè)置,ASIC模塊現(xiàn)在可以接收MCU送出的新的密碼值了,即,現(xiàn)在應(yīng)該設(shè)置密碼數(shù)據(jù)寄存器KeyDataRegister。 密碼數(shù)據(jù)寄存器KeyDataRegister也是WOM類型的存儲(chǔ)器。只可寫入數(shù)據(jù),不可讀出數(shù)據(jù),或讀到的數(shù)據(jù)是無(wú)效的。由于密碼的長(zhǎng)度為6bytes,因此密碼數(shù)據(jù)寄存器KeyDataRegister也將由6個(gè)bytes的FIFO存儲(chǔ)器組成。 以下是設(shè)置密碼數(shù)據(jù)寄存器KeyDataRegister的程序: SETUP_Key_Data_Reg: MOV R1,#72H ;R1為新密碼緩存(72H~77H)首地址指針 MOV R7,#06H ;密碼長(zhǎng)度=6bytes MOV R0,#0AH ;密碼數(shù)據(jù)寄存器地址為:“0Ah” WRITE_Key_Data_Reg_LOOP: MOV A,@R1 ;取出一個(gè)byte的新密碼值 MOV X@R0,A ;將一個(gè)byte的新密碼值送入密碼數(shù)據(jù)寄 ;存器中(ASIC模塊中) INC R1 DJNZ R7,WRITE_Key_Data_Reg_LOOP 這里有一個(gè)非常重要的問(wèn)題,即傳送6bytes長(zhǎng)度的密碼時(shí),這6bytes的順序必須引起高度重視。 由于每一個(gè)Block3都有著如下的存儲(chǔ)格式存放著密碼KEYA,KEYB及4個(gè)字節(jié)的存取控制條件:
因此,密碼數(shù)據(jù)寄存器接收MCU發(fā)送的第一個(gè)密碼字節(jié)(byte)必須是KEYA中的第一個(gè)字節(jié),即表中的“A0”字節(jié)。否則送入非接觸式智能卡中的密碼將是反向的6個(gè)字節(jié)。 密碼KEYB具有相同之處。 3.1.5校驗(yàn)STACON寄存器,以確定這次的“LOAD_KEY”(密碼存取)是否有效 在完成上述操作后,接著應(yīng)該對(duì)以上的結(jié)果進(jìn)行校驗(yàn),以確定這次的“LOAD_KEY”(密碼存取)是否有效。這可以通過(guò)校驗(yàn)STACON寄存器中的“AE”bit位來(lái)完成。 STACON寄存器是ASIC模塊中極為重要的狀態(tài)寄存器和控制寄存器。 當(dāng)對(duì)ASIC模塊進(jìn)行任何讀/寫操作時(shí),它是一個(gè)狀態(tài)寄存器,指出當(dāng)時(shí)讀/寫操作的狀態(tài)是如何的。此時(shí)的STACON寄存器有著如下的8個(gè)bit的狀態(tài)格式:
當(dāng)對(duì)ASIC模塊進(jìn)行任何控制操作時(shí),它是一個(gè)控制寄存器,此時(shí)的STACON寄存器又有著如下的8個(gè)bit的控制格式:
我們進(jìn)行密碼操作,讀寫ASIC模塊時(shí),只是會(huì)涉及STACON寄存器中的“AuthenticationError”bit(即“AE”位)。 ●當(dāng)“AE”=“1”時(shí),指明剛才的密碼操作(“LOAD_KEY”或“AUTHENTICATION”)沒(méi)有成功; ●當(dāng)“AE”=“0”時(shí),指明剛才的密碼操作(“LOAD_KEY”或“AUTHENTICATION”)成功; 以下是校驗(yàn)STACON寄存器,以確定這次“LOAD_KEY”密碼存取操作是否有效的校驗(yàn)程序: VERIFY_LOAD_KEY_Operationroutine: VERIFY_LOAD_KEY_OP: MOV R0,#01H ;STACON寄存器地址為“01H” MOV XA,@R0 ;讀ASIC內(nèi)的STACON寄存器;如果“AE”=“1”,轉(zhuǎn)出錯(cuò)處理 JB ACC.2, LOAD_KEY_Operation_ERR ;否則“AE”=“00”,此次“LOAD_KEY”成功 MOV B,#00H;送OK標(biāo)志“00” AJMP LOAD_KEY_Operation_OK LOAD_KEY_Operation_ERR: MOV B,#99H;送出錯(cuò)標(biāo)志“99”,此次“LOAD_KEY”失敗 ...... ?。ǔ鲥e(cuò)處理) ...... AJMP VERIFY_EXIT LOAD_KEY_Operation_OK: MOV A,B ACALL DISPLAY ...... ?。ā癘K”處理) ...... VERIFY_EXIT: RET
3.2“AUTHENTICATION”(密碼認(rèn)證) “AUTHENTICATION”(密碼認(rèn)證)操作必須按照如下的幾個(gè)步驟進(jìn)行: ●設(shè)置ASIC模塊中的TOC/BCNTS寄存器等 ●設(shè)置密碼狀態(tài)/控制寄存器KeyStatus&ControlRegister(KEYSTACON) ●設(shè)置密碼地址寄存器KeyAddressRegister(寄存器地址:0x0C) ●設(shè)置AUTHENTICATION指令碼 ●密碼地址變換 ●校驗(yàn)STACON寄存器,以確定這次的“AUTHENTICATION”密碼認(rèn)證是否有效 ●關(guān)閉TOC及一些其它操作等 由于“AUTHENTICATION”(密碼認(rèn)證)操作同“LOAD_KEY”(密碼存取)操作相互類似,在此不再重復(fù)。 只有在完全完成了上述的兩個(gè)主要的密碼操作步驟,并且得當(dāng)了ASIC模塊“OK”的響應(yīng),非接觸式智能卡上相對(duì)應(yīng)與剛才進(jìn)行過(guò)密碼操作的某一扇區(qū)Sectorm內(nèi)的Block0,1,2才能被MCU進(jìn)行訪問(wèn),包括進(jìn)行讀/寫等數(shù)據(jù)操作。一旦要求對(duì)另一扇區(qū)Sectorn內(nèi)的Block進(jìn)行數(shù)據(jù)讀寫時(shí),則必須重新開(kāi)始對(duì)扇區(qū)Sectorn進(jìn)行密碼操作,包括“LOAD_KEY”(密碼存取)操作和“AUTHENTICATION”(密碼認(rèn)證)操作等。
4、結(jié)束語(yǔ) 非接觸式智能卡技術(shù)雖然至今只有4~5年的成熟發(fā)展期,但是由于它的高度保密性,以及使用的方便性,得到了很快的普及。這種普及又加速了非接觸式智能卡技術(shù)的飛躍發(fā)展。它同銀行用接觸式CPU卡相互融合,產(chǎn)生了新的雙界面智能卡(Contact&ContactlessInterface),在e-purse電子錢包系統(tǒng)等方面取得到了很大的成功。世界上一些著名的大公司,如SONY公司等,也介入了非接觸式智能卡技術(shù)領(lǐng)域,并且SONY的非接觸式智能卡技術(shù)又有著非常獨(dú)到之處。根據(jù)筆者對(duì)SONY非接觸式智能卡技術(shù)的使用、研究和了解,相對(duì)MIFARE而言,其在讀卡的速度、穩(wěn)定性、誤碼率等性能上都有很大的提高,這也是其溶入了新的技術(shù)所致。
|