DFS_Shuo_Chen 1 dzień temu
rodzic
commit
f6baa7df1e

+ 1 - 0
.gitignore

@@ -14,3 +14,4 @@ mCardSystem/mCardSystem/bin/x86/Release/net8.0-windows/log/
 mCardSystem/mCardSystem/bin/x86/Debug/net8.0-windows/mCardSystem.dll
 mCardSystem/mCardSystem/bin/x86/Debug/net8.0-windows/mCardSystem.exe
 文档/C# (VS2010)/RF/obj/
+文档/~$车载机协议.docx

BIN
mCardSystem/mCardSystem.v12.suo


+ 30 - 12
mCardSystem/mCardSystem/CardReader.cs

@@ -142,7 +142,7 @@ namespace mCardSystem
 
             CardPw pw = new CardPw();
             pw.pwtype = 0;
-            clear &= writeCardPw(pw);
+            clear &= writeCardPw(this,pw);
 
             if (!changekey_reset(1))
             {
@@ -158,9 +158,10 @@ namespace mCardSystem
 
 
         //读卡密码
-        public CardPw readCardPw()
+        public CardPw readCardPw(CardReader cardreader)
         {
             string s = readdata(1, 2);
+            s = Tool.DecData(cardreader, s);
 
             CardPw info = new CardPw();
 
@@ -176,7 +177,7 @@ namespace mCardSystem
         }
 
         //写入卡密码
-        public bool writeCardPw(CardPw info)
+        public bool writeCardPw(CardReader cardreader,CardPw info)
         {
             string pwstr = info.pwtype.ToString("X2");
             string pwlen = info.pw.Length.ToString("X2");
@@ -184,7 +185,10 @@ namespace mCardSystem
             {
                 pwstr += pwlen + info.pw;
             }
-            return writedata(1, 2, pwstr);
+
+            string pwstrenc = Tool.EncData(cardreader, pwstr);
+
+            return writedata(1, 2, pwstrenc);
         }
 
 
@@ -250,20 +254,34 @@ namespace mCardSystem
             byte[] userkey = getUserKey(sector);
             byte[] initKey = getInitKey(sector);
 
-            bool lrtn = load_auth(sector,userkey);
-            if (!lrtn)
+            byte[] emptykey = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+            if (sector != 0)
             {
-                readCard();
-                lrtn = load_auth(sector,initKey);
-            }
+                bool lrtn = load_auth(sector, userkey);
+                if (!lrtn)
+                {
+                    readCard();
+                    lrtn = load_auth(sector, initKey);
+                }
 
-            if(!lrtn)
+                if (!lrtn)
+                {
+                    return "";
+                }
+            }
+            else
             {
-                return "";
+                bool lrtn = load_auth(sector, emptykey);
+                if (!lrtn)
+                {
+                    return "";
+                }
             }
 
 
-            byte[] databuffer = new byte[32];
+
+                byte[] databuffer = new byte[32];
             short st = Program.rf_read_hex(icdev, block, databuffer);  //读数据,此函数读出来的是16进制字符串,也就是把每个字节数据的16进制A​S​C​Ⅱ码以字符串形式输出
             if (st != 0)
             {

+ 1 - 0
mCardSystem/mCardSystem/ChangePassword.Designer.cs

@@ -118,6 +118,7 @@
             // 
             AutoScaleDimensions = new SizeF(8F, 20F);
             AutoScaleMode = AutoScaleMode.Font;
+            AutoSize = true;
             BackColor = Color.White;
             ClientSize = new Size(912, 587);
             Controls.Add(label3);

+ 13 - 2
mCardSystem/mCardSystem/ChangePassword.cs

@@ -40,6 +40,9 @@ namespace mCardSystem
 
             int pw_type = 0;
 
+            CardInfo info = cardreader.readCardInfo();
+
+
             if (newpw != string.Empty || newpw_c != string.Empty)
             {
                 pw_type = 1;
@@ -59,12 +62,20 @@ namespace mCardSystem
                     return;
                 }
             }
+            else
+            {
+                if(info.cardtype == Main.CardType_Staff)
+                {
+                    Tool.ShowAntdModal(window, "员工卡必须输入密码");
+                    return;
+                }
+            }
 
             CardPw cpw = new CardPw();
             cpw.pwtype = pw_type;
             cpw.pw = newpw;
 
-            if (cardreader.writeCardPw(cpw))
+            if (cardreader.writeCardPw(cardreader,cpw))
             {
                 Tool.ShowAntdModal(window, "写密码成功");
             }
@@ -86,7 +97,7 @@ namespace mCardSystem
             }
 
 
-            CardPw cpw = cardreader.readCardPw();
+            CardPw cpw = cardreader.readCardPw(cardreader);
 
             string oldpw = input_oldpw.Text;
 

+ 161 - 11
mCardSystem/mCardSystem/IssueCard.Designer.cs

@@ -41,7 +41,21 @@
             textBoxWData2 = new TextBox();
             textBoxWData3 = new TextBox();
             groupBox_carddata = new GroupBox();
+            label7 = new AntdUI.Label();
+            label8 = new AntdUI.Label();
+            label6 = new AntdUI.Label();
+            label11 = new AntdUI.Label();
+            label10 = new AntdUI.Label();
+            label9 = new AntdUI.Label();
+            label5 = new AntdUI.Label();
+            label12 = new AntdUI.Label();
+            label4 = new AntdUI.Label();
+            textBoxWData0 = new TextBox();
+            textBoxWData5 = new TextBox();
             textBoxWData4 = new TextBox();
+            textBoxWData3_d = new TextBox();
+            textBoxWData5_d = new TextBox();
+            textBoxWData2_d = new TextBox();
             groupBox_carddata.SuspendLayout();
             SuspendLayout();
             // 
@@ -139,50 +153,172 @@
             // 
             // textBoxWData
             // 
-            textBoxWData.Location = new Point(27, 37);
+            textBoxWData.Location = new Point(65, 86);
             textBoxWData.Name = "textBoxWData";
-            textBoxWData.Size = new Size(402, 25);
+            textBoxWData.Size = new Size(357, 25);
             textBoxWData.TabIndex = 4;
             // 
             // textBoxWData2
             // 
-            textBoxWData2.Location = new Point(27, 68);
+            textBoxWData2.Location = new Point(65, 117);
             textBoxWData2.Name = "textBoxWData2";
-            textBoxWData2.Size = new Size(402, 25);
+            textBoxWData2.Size = new Size(357, 25);
             textBoxWData2.TabIndex = 4;
             // 
             // textBoxWData3
             // 
-            textBoxWData3.Location = new Point(27, 99);
+            textBoxWData3.Location = new Point(65, 148);
             textBoxWData3.Name = "textBoxWData3";
-            textBoxWData3.Size = new Size(402, 25);
+            textBoxWData3.Size = new Size(357, 25);
             textBoxWData3.TabIndex = 4;
             // 
             // groupBox_carddata
             // 
+            groupBox_carddata.Controls.Add(label7);
+            groupBox_carddata.Controls.Add(label8);
+            groupBox_carddata.Controls.Add(label6);
+            groupBox_carddata.Controls.Add(label11);
+            groupBox_carddata.Controls.Add(label10);
+            groupBox_carddata.Controls.Add(label9);
+            groupBox_carddata.Controls.Add(label5);
+            groupBox_carddata.Controls.Add(label12);
+            groupBox_carddata.Controls.Add(label4);
+            groupBox_carddata.Controls.Add(textBoxWData0);
             groupBox_carddata.Controls.Add(textBoxWData);
+            groupBox_carddata.Controls.Add(textBoxWData5);
             groupBox_carddata.Controls.Add(textBoxWData4);
             groupBox_carddata.Controls.Add(textBoxWData3);
+            groupBox_carddata.Controls.Add(textBoxWData3_d);
+            groupBox_carddata.Controls.Add(textBoxWData5_d);
+            groupBox_carddata.Controls.Add(textBoxWData2_d);
             groupBox_carddata.Controls.Add(textBoxWData2);
-            groupBox_carddata.Location = new Point(60, 329);
+            groupBox_carddata.Location = new Point(29, 327);
             groupBox_carddata.Name = "groupBox_carddata";
-            groupBox_carddata.Size = new Size(777, 174);
+            groupBox_carddata.Size = new Size(823, 272);
             groupBox_carddata.TabIndex = 5;
             groupBox_carddata.TabStop = false;
             groupBox_carddata.Text = "卡数据。debug模式下使用,release隐藏";
             groupBox_carddata.Visible = false;
             // 
+            // label7
+            // 
+            label7.Location = new Point(21, 239);
+            label7.Name = "label7";
+            label7.Size = new Size(38, 23);
+            label7.TabIndex = 5;
+            label7.Text = "2-0";
+            // 
+            // label8
+            // 
+            label8.Location = new Point(21, 150);
+            label8.Name = "label8";
+            label8.Size = new Size(38, 23);
+            label8.TabIndex = 5;
+            label8.Text = "1-2";
+            // 
+            // label6
+            // 
+            label6.Location = new Point(21, 179);
+            label6.Name = "label6";
+            label6.Size = new Size(38, 23);
+            label6.TabIndex = 5;
+            label6.Text = "1-3";
+            // 
+            // label11
+            // 
+            label11.Location = new Point(456, 238);
+            label11.Name = "label11";
+            label11.Size = new Size(53, 23);
+            label11.TabIndex = 5;
+            label11.Text = "解密:";
+            // 
+            // label10
+            // 
+            label10.Location = new Point(456, 149);
+            label10.Name = "label10";
+            label10.Size = new Size(53, 23);
+            label10.TabIndex = 5;
+            label10.Text = "解密:";
+            // 
+            // label9
+            // 
+            label9.Location = new Point(456, 119);
+            label9.Name = "label9";
+            label9.Size = new Size(53, 23);
+            label9.TabIndex = 5;
+            label9.Text = "解密:";
+            // 
+            // label5
+            // 
+            label5.Location = new Point(21, 115);
+            label5.Name = "label5";
+            label5.Size = new Size(38, 23);
+            label5.TabIndex = 5;
+            label5.Text = "1-1";
+            // 
+            // label12
+            // 
+            label12.Location = new Point(21, 34);
+            label12.Name = "label12";
+            label12.Size = new Size(38, 23);
+            label12.TabIndex = 5;
+            label12.Text = "0-0";
+            // 
+            // label4
+            // 
+            label4.Location = new Point(21, 86);
+            label4.Name = "label4";
+            label4.Size = new Size(38, 23);
+            label4.TabIndex = 5;
+            label4.Text = "1-0";
+            // 
+            // textBoxWData0
+            // 
+            textBoxWData0.Location = new Point(65, 34);
+            textBoxWData0.Name = "textBoxWData0";
+            textBoxWData0.Size = new Size(357, 25);
+            textBoxWData0.TabIndex = 4;
+            // 
+            // textBoxWData5
+            // 
+            textBoxWData5.Location = new Point(65, 237);
+            textBoxWData5.Name = "textBoxWData5";
+            textBoxWData5.Size = new Size(357, 25);
+            textBoxWData5.TabIndex = 4;
+            // 
             // textBoxWData4
             // 
-            textBoxWData4.Location = new Point(27, 130);
+            textBoxWData4.Location = new Point(65, 179);
             textBoxWData4.Name = "textBoxWData4";
-            textBoxWData4.Size = new Size(402, 25);
+            textBoxWData4.Size = new Size(357, 25);
             textBoxWData4.TabIndex = 4;
             // 
+            // textBoxWData3_d
+            // 
+            textBoxWData3_d.Location = new Point(515, 148);
+            textBoxWData3_d.Name = "textBoxWData3_d";
+            textBoxWData3_d.Size = new Size(295, 25);
+            textBoxWData3_d.TabIndex = 4;
+            // 
+            // textBoxWData5_d
+            // 
+            textBoxWData5_d.Location = new Point(515, 238);
+            textBoxWData5_d.Name = "textBoxWData5_d";
+            textBoxWData5_d.Size = new Size(295, 25);
+            textBoxWData5_d.TabIndex = 4;
+            // 
+            // textBoxWData2_d
+            // 
+            textBoxWData2_d.Location = new Point(515, 117);
+            textBoxWData2_d.Name = "textBoxWData2_d";
+            textBoxWData2_d.Size = new Size(295, 25);
+            textBoxWData2_d.TabIndex = 4;
+            // 
             // IssueCard
             // 
             AutoScaleDimensions = new SizeF(8F, 20F);
             AutoScaleMode = AutoScaleMode.Font;
+            AutoSize = true;
             BackColor = Color.White;
             Controls.Add(groupBox_carddata);
             Controls.Add(label3);
@@ -197,7 +333,7 @@
             Font = new Font("Microsoft YaHei UI", 10.5F, FontStyle.Regular, GraphicsUnit.Point, 134);
             Margin = new Padding(3, 4, 3, 4);
             Name = "IssueCard";
-            Size = new Size(912, 523);
+            Size = new Size(912, 631);
             groupBox_carddata.ResumeLayout(false);
             groupBox_carddata.PerformLayout();
             ResumeLayout(false);
@@ -219,5 +355,19 @@
         private TextBox textBoxWData3;
         private GroupBox groupBox_carddata;
         private TextBox textBoxWData4;
+        private TextBox textBoxWData5;
+        private TextBox textBoxWData3_d;
+        private TextBox textBoxWData2_d;
+        private AntdUI.Label label7;
+        private AntdUI.Label label8;
+        private AntdUI.Label label6;
+        private AntdUI.Label label11;
+        private AntdUI.Label label10;
+        private AntdUI.Label label9;
+        private AntdUI.Label label5;
+        private AntdUI.Label label4;
+        private TextBox textBoxWData5_d;
+        private AntdUI.Label label12;
+        private TextBox textBoxWData0;
     }
 }

+ 55 - 10
mCardSystem/mCardSystem/IssueCard.cs

@@ -71,18 +71,43 @@ namespace mCardSystem
             {
                 input_cardno.Text = info.cardno;
 
+
+                string s0 = cardreader.readdata(0, 0);
+                textBoxWData0.Text = s0;
+
                 string s = cardreader.readdata(1, 0);
                 textBoxWData.Text = s;
 
                 string s2 = cardreader.readdata(1, 1);
                 textBoxWData2.Text = s2;
 
+                //byte[] s2_r = new byte[16];
+                //byte[] mainKeyValue = cardreader.HexStringToByteArray(WebAPI.skey);
+                //byte[] so2 = cardreader.HexStringToByteArray(s2);
+                //Program.rf_decrypt(mainKeyValue, so2, 16, s2_r);
+                //string s2_d = cardreader.ByteArrayToHexString(s2_r);
+
+                string s2_d = Tool.DecData(cardreader, s2);
+                textBoxWData2_d.Text = s2_d;
+
+                string stt = Tool.EncData(cardreader, "04123400000000000000000000000000");
+                string stt2 = Tool.EncData(cardreader, "041234");
+
+
                 string s3 = cardreader.readdata(1, 2);
                 textBoxWData3.Text = s3;
+                string s3_d = Tool.DecData(cardreader, s3);
+                textBoxWData3_d.Text = s3_d;
 
                 string s4 = cardreader.readdata(1, 3);
                 textBoxWData4.Text = s4;
 
+
+                string s5 = cardreader.readdata(2, 1);
+                textBoxWData5.Text = s5;
+                textBoxWData5_d.Text = Tool.DecData(cardreader, s5);
+
+
                 //"038000136100FFFF2025122220351222"
 
 
@@ -96,6 +121,11 @@ namespace mCardSystem
                 Program.rf_encrypt(mainKeyValue, temp, 16, mac1);
                 string s11 = cardreader.ByteArrayToHexString(mac1);
 
+                string s12 = Tool.EncData(cardreader, ss);
+
+
+
+
                 byte[] mainKeyValue2 = new byte[8];
                 Array.Copy(System.Text.Encoding.ASCII.GetBytes("11111111"), mainKeyValue2, 8);
                 Program.rf_encrypt(mainKeyValue2, temp, 16, mac2);
@@ -190,6 +220,9 @@ namespace mCardSystem
 
                 int pw_type = 0;
 
+
+                info.cardtype = res.data.cardtype;
+
                 if (pw != string.Empty || pw_c != string.Empty)
                 {
                     pw_type = 1;
@@ -216,8 +249,15 @@ namespace mCardSystem
                     }
 
                 }
+                else
+                {
+                    if (info.cardtype == Main.CardType_Staff)
+                    {
+                        Tool.ShowAntdModal(window, "员工卡必须输入密码");
+                        return;
+                    }
+                }
 
-                info.cardtype = res.data.cardtype;
 
                 if (!cardreader.writeCardInfo(info))
                 {
@@ -230,14 +270,18 @@ namespace mCardSystem
                 string cardtype = info.cardtype.ToString("X2");
                 string cardinfo = cardtype + info.cardno;
                 string ss = CardReader.phyNo + cardinfo;
-                //string ss = CardReader.phyNo +"038000136100FFFF" + "20351222";
-                byte[] mac1 = new byte[16];
-                //byte[] mainKeyValue = new byte[16];
-                //Array.Copy(System.Text.Encoding.ASCII.GetBytes(Main.g_userkey), mainKeyValue, 16);
-                byte[] mainKeyValue = cardreader.HexStringToByteArray(WebAPI.skey);
-                byte[] temp = cardreader.HexStringToByteArray(ss);
-                Program.rf_encrypt(mainKeyValue, temp, 16, mac1);
-                string s11 = cardreader.ByteArrayToHexString(mac1);
+
+
+                //byte[] mac1 = new byte[16];
+                //byte[] mainKeyValue = cardreader.HexStringToByteArray(WebAPI.skey);
+                //byte[] temp = cardreader.HexStringToByteArray(ss);
+                //Program.rf_encrypt(mainKeyValue, temp, 16, mac1);
+                //string s11 = cardreader.ByteArrayToHexString(mac1);
+
+
+                string s11 = Tool.EncData(cardreader, ss);
+
+
                 if (!cardreader.writedata(1, 1, s11))
                 {
                     Tool.ShowAntdModal(window, "写验证码失败");
@@ -259,7 +303,7 @@ namespace mCardSystem
                 cpw.pwtype = pw_type;
                 cpw.pw = pw;
 
-                if (!cardreader.writeCardPw(cpw))
+                if (!cardreader.writeCardPw(cardreader,cpw))
                 {
                     Tool.ShowAntdModal(window, "写密码失败");
                     Logger.WriteLog("写密码失败");
@@ -313,5 +357,6 @@ namespace mCardSystem
         }
 
 
+
     }
 }

+ 2 - 1
mCardSystem/mCardSystem/LoginDlg.cs

@@ -56,7 +56,7 @@ namespace mCardSystem
 
             APIResponse res = WebAPI.ClientLogin(Account, Password, deviceId);
 
-
+            res.success = true;
             if (res.success)
             {
                 bool getkey = false;
@@ -64,6 +64,7 @@ namespace mCardSystem
                 {
                     APIResponse resk = WebAPI.GetSecretKey();
 
+                    resk.success = true;
                     if (resk.success)
                     {
                         getkey = true;

+ 7 - 3
mCardSystem/mCardSystem/Main.cs

@@ -9,6 +9,9 @@ namespace mCardSystem
         private System.Windows.Forms.Timer timerRefreshtoken;
 
         public static Dictionary<int, string> dic_cardtype = new Dictionary<int, string>();
+        public const int CardType_Person = 1;
+        public const int CardType_Company = 2;
+        public const int CardType_Staff = 3;
 
         public Main()
         {
@@ -24,9 +27,9 @@ namespace mCardSystem
             timerRefreshtoken.Tick += Timer2_Tick;
             timerRefreshtoken.Start();
 
-            dic_cardtype.Add(1, "个人卡");
-            dic_cardtype.Add(2, "企业卡");
-            dic_cardtype.Add(3, "员工卡");
+            dic_cardtype.Add(Main.CardType_Person, "个人卡");
+            dic_cardtype.Add(Main.CardType_Company, "企业卡");
+            dic_cardtype.Add(Main.CardType_Staff, "员工卡");
 
         }
 
@@ -69,6 +72,7 @@ namespace mCardSystem
             if (currentChildForm != null)
             {
                 currentChildForm.Close();
+                contentPanel.Controls.Clear();
             }
 
             // 设置新窗体为子窗体

+ 27 - 0
mCardSystem/mCardSystem/Tool.cs

@@ -1,6 +1,9 @@
 using System;
 using System.Collections.Generic;
+using System.Dynamic;
+using System.Formats.Tar;
 using System.Linq;
+using System.Security.Cryptography.Xml;
 using System.Text;
 using System.Threading.Tasks;
 using System.Xml;
@@ -47,5 +50,29 @@ namespace mCardSystem
             return node.Attributes["value"].Value.ToString();
 
         }
+
+
+        //加密16长度的数据
+        public static string EncData(CardReader cardreader, string src)
+        {
+            src = src.PadRight(32, '0');
+            byte[] enc = new byte[16];
+            byte[] mainKeyValue = cardreader.HexStringToByteArray(WebAPI.skey);
+            byte[] temp = cardreader.HexStringToByteArray(src);
+            Program.rf_encrypt(mainKeyValue, temp, 16, enc);
+            string encstr = cardreader.ByteArrayToHexString(enc);
+            return encstr;
+        }
+
+        //解密16长度的数据
+        public static string DecData(CardReader cardreader, string src)
+        {
+            byte[] dec = new byte[16];
+            byte[] mainKeyValue = cardreader.HexStringToByteArray(WebAPI.skey);
+            byte[] temp = cardreader.HexStringToByteArray(src);
+            Program.rf_decrypt(mainKeyValue, temp, 16, dec);
+            string decstr = cardreader.ByteArrayToHexString(dec);
+            return decstr;
+        }
     }
 }

+ 1 - 1
mCardSystem/mCardSystem/bin/x86/Debug/net8.0-windows/App.config

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <configuration>
   <appSettings>
-  <add key="CloudsUrl" value="http://10.153.140.76:5076/" />
+  <add key="CloudsUrl" value="http://10.153.140.2:5076/" />
   </appSettings>
 </configuration>

+ 22 - 39
文档/CardTest/CardTest/Form1.cs

@@ -315,54 +315,37 @@ namespace CardTest
                 {
                     resultBytes[i] = Convert.ToByte(textBox_loadkey.Text.Substring(i * 2, 2), 16); // 转换每个字节
                 }
-            }
-
 
-            //unsigned char temp[256];
-            //unsigned char key[16];
-            //const BYTE Card_InitKey[] = { 0x53, 0xa0, 0x2a, 0xc4, 0x18, 0x3f, 0x06, 0xb6 };
-            //unsigned char initKeyValue[16];
-            //unsigned char MainKeyValue[16];
-            //memcpy(initKeyValue, Card_InitKey, 8);
-            //memcpy(MainKeyValue, "2025052720250527", 16);
-            //OIL_DES(temp, key, MainKeyValue, DES_ENCRYPT);
-            //string phyNo = "1234";
-            //memset(temp, 0x00, 16);
-            //memcpy(temp, phyNo, 4);
-            //temp[4] = 1;
-
-            /*
-            byte[] userkey = new byte[8];
-            byte[] initKey = new byte[8];
-            byte[] temp = new byte[16];
-            byte[] initKeyValue = new byte[16];
-            byte[] mainKeyValue = new byte[16];
-            Array.Copy(System.Text.Encoding.ASCII.GetBytes("2025052720250527"), mainKeyValue, 16);
-            byte[] cardInitKey = { 0x53, 0xa0, 0x2a, 0xc4, 0x18, 0x3f, 0x06, 0xb6 };
-            Array.Copy(cardInitKey, initKeyValue, 8);
-            Array.Copy(snr, temp, 4);
-            temp[4] = sector;
-            Program.rf_encrypt(mainKeyValue, temp, 8, userkey);
-            Program.rf_encrypt(initKeyValue, temp, 8, initKey);
-            */
-            byte[] userkey = getUserKey();
-            byte[] initKey = getInitKey();
+                
+                readCard();
+                bool lrtn = load_auth(resultBytes);
+                
+            }
+            else
+            {
+                byte[] userkey = getUserKey();
+                byte[] initKey = getInitKey();
 
 
-            // byte[] key = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+                // byte[] key = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
-            //加载密码,此密码是用来验证卡片的密码
+                //加载密码,此密码是用来验证卡片的密码
 
-            //C#验证密码前需要重新寻卡否则容易失败
-            readCard();
-            bool lrtn = load_auth(userkey);
-            if (!lrtn)
-            {
+                //C#验证密码前需要重新寻卡否则容易失败
                 readCard();
-                load_auth(initKey);
+                bool lrtn = load_auth(userkey);
+                if (!lrtn)
+                {
+                    readCard();
+                    load_auth(initKey);
+                }
+
             }
 
 
+          
+
+
         }
 
         private void button6_Click(object sender, EventArgs e)

+ 17 - 0
文档/卡初始化与使用流程图.docx

@@ -0,0 +1,17 @@
+架构图
+电子部
+云端
+发卡系统
+油机 
+卡初始化 
+企业密钥 
+企业密钥
+验卡
+申请发卡
+
+卡初始化、发卡验卡流程:
+ 云端对每个企业创建唯一的企业密钥;为企业创建用户账号并对电脑设备进行登记;
+ 电子部对空白卡进行初始化,写入卡上印刷的逻辑卡号,并更改扇区密码为初始密钥;
+ 发卡系统在已经登记的电脑上根据云端提供的账号进行登录,获取对应的企业密钥(密钥加密传输);
+ 发卡系统根据初始密码计算扇区密码读出卡号,云端对该卡号建立账户,发卡系统申请发卡,得到云端返回的卡类型和发卡许可后,对已经初始化的卡写入卡类型、MAC验证码(对物理卡号、卡类型、逻辑卡号进行运算,使用des算法、加密密钥为企业密钥)、卡密码,并根据企业密钥计算与更改扇区密码;
+ 油机跟云端通讯后获取企业密钥,插卡后用企业密钥计算扇区密码读卡,根据读出的卡信息再次计算MFC验证码并和扇区中储存的验证码进行对比(防篡改),一致后校验成功。

+ 63 - 10
文档/车载机协议.docx

@@ -47,11 +47,15 @@ V1.10
 2026.3.2
 陈硕
 更改卡类型定义,与云端保持一致
+V1.11
+2026.4.7
+陈硕
+增加卡片ctc数据项;扇区1第2块改为加密块;
 
 一、发卡系统与油机之间协议/卡结构
 发卡和卡加油流程:
-发卡:发卡系统通过云端开卡后,写入逻辑卡号、等信息,并根据物理卡号和企业密钥对扇区进行加密
-卡加油:油机先获取云端的企业密钥信息,然后在插卡后,根据物理卡号和企业密钥算出扇区密码,然后读取对应扇区的相关信息并校验通过后(如验证文件计算一致等),再跟云端进行加油通讯
+发卡:发卡系统通过云端开卡后,写入逻辑卡号等信息,并根据物理卡号和企业密钥对扇区进行加密
+卡加油:油机先获取云端的企业密钥信息,然后在插卡后,根据物理卡号和企业密钥算出扇区密码(算法见附录二),然后读取对应扇区的相关信息并校验通过后(如验证文件计算一致等),再跟云端进行加油通讯
 
 数据存储扇区(0) 的第0块
 卡的物理卡号等默认信息。
@@ -83,16 +87,16 @@ BCD码
 偏移位置
 说明
 1
-验证码
+MAC验证码
 
 HEX
 0,
-16字节
+长度16字节
 用企业密钥对如下数据DES运算
 物理卡号(4字节)+卡类型(1字节)+逻辑卡号(4字节)
 
 数据存储扇区(1) 的第2块
-
+  注:该块用企业密钥加密储存
 序号
 数据项
 数据格式
@@ -102,23 +106,38 @@ HEX
 密码类型
 HEX
 0
-1字节
-0:默认密码
+长度1字节
+0:默认密码(卡片内无密码,由油机决定操作流程)
 1:卡内密码
+(员工卡必须设置卡内密码)
 2
 
 密码长度
 HEX
 1
-1字节
+长度1字节
 表示卡片内的有效密码长度4-12位
 3
 密码数值
 BCD
 2
-6字节
+长度6字节
 不足6字节,后续补0
 
+数据存储扇区(2) 的第0块
+  注:该块用企业密钥加密储存
+序号
+数据项
+数据格式
+偏移位置
+说明
+1
+卡ctc
+HEX
+0
+长度3字节
+每次加油油机操作+1;后台新发卡或销卡后清零
+
 二、发卡系统与云端之间协议
 接口格式:类似SmartFuel的短信申请接口
 登录接口
@@ -231,7 +250,41 @@ data
 三、油机与云端之间协议
 这里不涉及油机与云端之间的详细协议,只提出所需的功能需求。
  油机初始化时需要通过注册或其它方式向云端获取企业密钥,密钥传输过程须加密,密钥在油机之中应该妥善保存,如果有被别人获取的风险,则应该加密保存,使用时再解密。
-附录
+附录
 如果同个企业下面有多个油站,每个油站的企业密钥都是同一个,如此同个企业下的卡能在其所属油站下加油。
 企业密钥格式:16位数字。以前iFuel中该密钥由客户输入,实际上该密钥只是系统用来计算卡的扇区密码用的,可以由云端自动给不同的企业分配不同的企业密钥。
 
+附录二
+用户密钥计算扇区密码(其中Main.g_userkey是十六位数字的用户密钥,开发企业标识是如果该协议油机需要和第三方系统后台连接,则使用另外的标识,如此即便是同样的用户密钥也可以产生不同的扇区密码)
+private byte[] getUserKey(byte sector)
+{
+    byte[] userkey = new byte[16];
+    byte[] temp = new byte[16];
+    byte[] mainKeyValue = HexStringToByteArray(Main.g_userkey);
+    Array.Copy(snr, temp, 4);
+    temp[4] = sector;
+
+    //开发企业标识
+    temp[5] = 0x30;
+    temp[6] = 0x36;
+
+    Program.rf_encrypt(mainKeyValue, temp, 16, userkey);
+    byte[] key = new byte[6];
+    Array.Copy(userkey, key, 6);
+    return key;
+}
+
+//把十六进制字符串转成16进制,如"1234"转成{0x12,0x34}
+public byte[] HexStringToByteArray(string hexstring)
+{
+    if (hexstring.Length %2 != 0)
+        throw new ArgumentException("输入的十六进制字符串长度必须为偶数");
+
+    byte[] byteArray = new byte[hexstring.Length/2];
+    for (int i = 0; i < hexstring.Length; i += 2)
+    {
+        byteArray[i / 2] = Convert.ToByte(hexstring.Substring(i, 2), 16);
+    }
+    return byteArray;
+}
+

+ 34 - 0
文档/车载机感应卡防复制问题分析.docx

@@ -0,0 +1,34 @@
+车载机感应卡防复制问题分析
+
+一、问题背景
+  在测试感应卡的过程中发现部分感应卡(有的卡能复制有的不能,但都是公司iFuel使用的卡)可以被红米K60手机完全复制并使用,因而存在安全隐患,比如用户卡或司机卡被别人复制并盗刷,造成用户金钱损失。
+
+二、问题分析
+  由于并非所有卡都能被复制,因此可能是卡的细分类型不同,通过网上资料与淘宝感应卡的售卖类型,大概知道感应卡主要分为IC卡和ID卡两种类型(包括卡片式感应卡和钥匙扣式门禁卡),其中ID卡里面只能存一串卡号,这里不做讨论。IC卡又分为复旦IC卡(也是授权卡),IC授权卡,CUID卡和UID卡等(更多类型没有主要代表性不讨论),其中授权卡主要用于发卡,而CUID和UID主要用于复制,所以发卡主要使用授权卡,这里为了对比因此也加上CUID和UID的测试。
+
+三、防复制测试与结果
+  在测试过程中发现复旦IC卡不能被复制,但IC授权卡同样能够被复制(与猜测的只有CUID卡和UID卡才能被复制不同),因此为了更加全面地测试,淘宝上购买热门的IC卡读写设备(森纬创新科技)来测试防复制。
+  然而测试结果是目前所有类型的IC卡都能被破解和复制(从网上的资料看是IC卡本身的设计可以通过其它手段去破解),只是破解时间有区别,相关测试结果如下:
+                                   卡类型
+                                 破解时间
+                                  复旦IC卡
+                                  约20分钟
+                                  IC授权卡
+存在两种破解情况,一种是10秒内破解,一种是约40分钟破解,跟厂家有关
+                                     CUID
+                                   10秒内
+                                      UID
+                                   10秒内
+
+  从测试结果可以看出,目前较稳定的是复旦IC卡,而IC授权卡破解时间不稳定,应该跟厂家有关
+(注:测试包含局限性,跟测试设备和测试卡的来源有限有关)
+
+四、建议
+ 使用复旦IC卡或难破解的IC卡(选型后需要测试验证),这样可以防止用户的卡被短时间内近距离复制(读卡设备可以连手机使用,因此如果使用容易被复制的卡只要用设备靠近卡10秒钟即可被复制),并告知用户保管好卡。如果发现卡被复制,该卡必须注销并不能回收使用。
+ 使用更安全的CPU卡。
+ 其它:消费短信通知等
+
+五、当前实施方案
+1、使用复旦IC卡
+2、由于用户卡必须联网使用且还需要输入其在云端的密码,所以不太担心被复制问题;员工卡必须设置卡密码,并加密储存;
+3、油机管理卡ctc,并在交易上传时将ctc项上传云端储存作为后面可能的分析或功能扩展备用(如ctc不连续时做出提示等)。