diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/FrmChangePassword.Designer.cs b/FrmChangePassword.Designer.cs index 7e83f42..aa98573 100644 --- a/FrmChangePassword.Designer.cs +++ b/FrmChangePassword.Designer.cs @@ -51,7 +51,7 @@ this.labelX1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX1.Location = new System.Drawing.Point(23, 13); this.labelX1.Name = "labelX1"; - this.labelX1.Size = new System.Drawing.Size(50, 16); + this.labelX1.Size = new System.Drawing.Size(56, 18); this.labelX1.TabIndex = 0; this.labelX1.Text = "原始密码"; // @@ -65,7 +65,7 @@ this.labelX2.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX2.Location = new System.Drawing.Point(23, 49); this.labelX2.Name = "labelX2"; - this.labelX2.Size = new System.Drawing.Size(50, 16); + this.labelX2.Size = new System.Drawing.Size(56, 18); this.labelX2.TabIndex = 0; this.labelX2.Text = "最新密码"; // @@ -79,7 +79,7 @@ this.labelX3.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX3.Location = new System.Drawing.Point(23, 85); this.labelX3.Name = "labelX3"; - this.labelX3.Size = new System.Drawing.Size(50, 16); + this.labelX3.Size = new System.Drawing.Size(56, 18); this.labelX3.TabIndex = 0; this.labelX3.Text = "密码确认"; // @@ -107,7 +107,7 @@ this.txt_pwd_new.Name = "txt_pwd_new"; this.txt_pwd_new.PasswordChar = '*'; this.txt_pwd_new.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_new.TabIndex = 1; + this.txt_pwd_new.TabIndex = 2; // // txt_pwd_cfm // @@ -120,7 +120,7 @@ this.txt_pwd_cfm.Name = "txt_pwd_cfm"; this.txt_pwd_cfm.PasswordChar = '*'; this.txt_pwd_cfm.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_cfm.TabIndex = 1; + this.txt_pwd_cfm.TabIndex = 3; // // btn_ok // @@ -130,7 +130,7 @@ this.btn_ok.Name = "btn_ok"; this.btn_ok.Size = new System.Drawing.Size(75, 23); this.btn_ok.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btn_ok.TabIndex = 2; + this.btn_ok.TabIndex = 4; this.btn_ok.Text = "确定"; this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); // diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/FrmChangePassword.Designer.cs b/FrmChangePassword.Designer.cs index 7e83f42..aa98573 100644 --- a/FrmChangePassword.Designer.cs +++ b/FrmChangePassword.Designer.cs @@ -51,7 +51,7 @@ this.labelX1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX1.Location = new System.Drawing.Point(23, 13); this.labelX1.Name = "labelX1"; - this.labelX1.Size = new System.Drawing.Size(50, 16); + this.labelX1.Size = new System.Drawing.Size(56, 18); this.labelX1.TabIndex = 0; this.labelX1.Text = "原始密码"; // @@ -65,7 +65,7 @@ this.labelX2.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX2.Location = new System.Drawing.Point(23, 49); this.labelX2.Name = "labelX2"; - this.labelX2.Size = new System.Drawing.Size(50, 16); + this.labelX2.Size = new System.Drawing.Size(56, 18); this.labelX2.TabIndex = 0; this.labelX2.Text = "最新密码"; // @@ -79,7 +79,7 @@ this.labelX3.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX3.Location = new System.Drawing.Point(23, 85); this.labelX3.Name = "labelX3"; - this.labelX3.Size = new System.Drawing.Size(50, 16); + this.labelX3.Size = new System.Drawing.Size(56, 18); this.labelX3.TabIndex = 0; this.labelX3.Text = "密码确认"; // @@ -107,7 +107,7 @@ this.txt_pwd_new.Name = "txt_pwd_new"; this.txt_pwd_new.PasswordChar = '*'; this.txt_pwd_new.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_new.TabIndex = 1; + this.txt_pwd_new.TabIndex = 2; // // txt_pwd_cfm // @@ -120,7 +120,7 @@ this.txt_pwd_cfm.Name = "txt_pwd_cfm"; this.txt_pwd_cfm.PasswordChar = '*'; this.txt_pwd_cfm.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_cfm.TabIndex = 1; + this.txt_pwd_cfm.TabIndex = 3; // // btn_ok // @@ -130,7 +130,7 @@ this.btn_ok.Name = "btn_ok"; this.btn_ok.Size = new System.Drawing.Size(75, 23); this.btn_ok.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btn_ok.TabIndex = 2; + this.btn_ok.TabIndex = 4; this.btn_ok.Text = "确定"; this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); // diff --git a/FrmChangePassword.cs b/FrmChangePassword.cs index a78b93f..9e22417 100644 --- a/FrmChangePassword.cs +++ b/FrmChangePassword.cs @@ -1,6 +1,9 @@ using System; using System.Data; +using System.Data.OracleClient; +using System.Text.RegularExpressions; using System.Windows.Forms; +using Cyberpipe.SM4; using DevComponents.DotNetBar; namespace Cyberpipe @@ -28,22 +31,43 @@ MessageBox.Show("请确认要修改的密码!"); return; } - string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME='" + Utility.userName + "' and PASSWORD='" + Utility.MD5Encrypt2(txt_pwd_old.Text.Trim()) + "'"; - int count = int.Parse(OracleUtils.ExecuteScalar(OracleUtils.ConnectionString, CommandType.Text, sql).ToString()); + + // 验证密码的复杂度——大小写字母+数字+特殊字符,长度不低于8位 + bool regMatch = Regex.IsMatch(txt_pwd_new.Text.Trim(), "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$"); + if (regMatch == false) + { + MessageBox.Show("请确保密码强度:至少包含字母、数字和特殊字符,不少于8位!"); + return; + } + string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME=:username and PASSWORD=:passwordOld"; + + OracleParameter usernameParam = new OracleParameter(":username", Utility.userName); + OracleParameter passwordOldParam = new OracleParameter(":passwordOld", SM4Utils.SM4EncryptStr(txt_pwd_old.Text.Trim())); + + int count = int.Parse(OledbHelper.ExecuteScalar(sql, usernameParam, passwordOldParam).ToString()); if (count <= 0) { MessageBox.Show("密码错误!"); return; } - sql = "update casic_userinfotest set password='" + Utility.MD5Encrypt2(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; - OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); - MessageBox.Show("修改成功!"); + sql = "update casic_userinfotest set password='" + SM4Utils.SM4EncryptStr(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; + int rowCount = OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); + if (rowCount == 1) + { + MessageBox.Show("修改成功!请退出系统后重新登录"); + } else + { + MessageBox.Show("修改失败"); + } } catch (Exception ex) { MessageBox.Show("修改失败:" + ex); + this.Hide(); } + this.Hide(); + } private void FrmChangePassword_Load(object sender, EventArgs e) diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/FrmChangePassword.Designer.cs b/FrmChangePassword.Designer.cs index 7e83f42..aa98573 100644 --- a/FrmChangePassword.Designer.cs +++ b/FrmChangePassword.Designer.cs @@ -51,7 +51,7 @@ this.labelX1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX1.Location = new System.Drawing.Point(23, 13); this.labelX1.Name = "labelX1"; - this.labelX1.Size = new System.Drawing.Size(50, 16); + this.labelX1.Size = new System.Drawing.Size(56, 18); this.labelX1.TabIndex = 0; this.labelX1.Text = "原始密码"; // @@ -65,7 +65,7 @@ this.labelX2.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX2.Location = new System.Drawing.Point(23, 49); this.labelX2.Name = "labelX2"; - this.labelX2.Size = new System.Drawing.Size(50, 16); + this.labelX2.Size = new System.Drawing.Size(56, 18); this.labelX2.TabIndex = 0; this.labelX2.Text = "最新密码"; // @@ -79,7 +79,7 @@ this.labelX3.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX3.Location = new System.Drawing.Point(23, 85); this.labelX3.Name = "labelX3"; - this.labelX3.Size = new System.Drawing.Size(50, 16); + this.labelX3.Size = new System.Drawing.Size(56, 18); this.labelX3.TabIndex = 0; this.labelX3.Text = "密码确认"; // @@ -107,7 +107,7 @@ this.txt_pwd_new.Name = "txt_pwd_new"; this.txt_pwd_new.PasswordChar = '*'; this.txt_pwd_new.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_new.TabIndex = 1; + this.txt_pwd_new.TabIndex = 2; // // txt_pwd_cfm // @@ -120,7 +120,7 @@ this.txt_pwd_cfm.Name = "txt_pwd_cfm"; this.txt_pwd_cfm.PasswordChar = '*'; this.txt_pwd_cfm.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_cfm.TabIndex = 1; + this.txt_pwd_cfm.TabIndex = 3; // // btn_ok // @@ -130,7 +130,7 @@ this.btn_ok.Name = "btn_ok"; this.btn_ok.Size = new System.Drawing.Size(75, 23); this.btn_ok.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btn_ok.TabIndex = 2; + this.btn_ok.TabIndex = 4; this.btn_ok.Text = "确定"; this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); // diff --git a/FrmChangePassword.cs b/FrmChangePassword.cs index a78b93f..9e22417 100644 --- a/FrmChangePassword.cs +++ b/FrmChangePassword.cs @@ -1,6 +1,9 @@ using System; using System.Data; +using System.Data.OracleClient; +using System.Text.RegularExpressions; using System.Windows.Forms; +using Cyberpipe.SM4; using DevComponents.DotNetBar; namespace Cyberpipe @@ -28,22 +31,43 @@ MessageBox.Show("请确认要修改的密码!"); return; } - string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME='" + Utility.userName + "' and PASSWORD='" + Utility.MD5Encrypt2(txt_pwd_old.Text.Trim()) + "'"; - int count = int.Parse(OracleUtils.ExecuteScalar(OracleUtils.ConnectionString, CommandType.Text, sql).ToString()); + + // 验证密码的复杂度——大小写字母+数字+特殊字符,长度不低于8位 + bool regMatch = Regex.IsMatch(txt_pwd_new.Text.Trim(), "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$"); + if (regMatch == false) + { + MessageBox.Show("请确保密码强度:至少包含字母、数字和特殊字符,不少于8位!"); + return; + } + string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME=:username and PASSWORD=:passwordOld"; + + OracleParameter usernameParam = new OracleParameter(":username", Utility.userName); + OracleParameter passwordOldParam = new OracleParameter(":passwordOld", SM4Utils.SM4EncryptStr(txt_pwd_old.Text.Trim())); + + int count = int.Parse(OledbHelper.ExecuteScalar(sql, usernameParam, passwordOldParam).ToString()); if (count <= 0) { MessageBox.Show("密码错误!"); return; } - sql = "update casic_userinfotest set password='" + Utility.MD5Encrypt2(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; - OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); - MessageBox.Show("修改成功!"); + sql = "update casic_userinfotest set password='" + SM4Utils.SM4EncryptStr(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; + int rowCount = OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); + if (rowCount == 1) + { + MessageBox.Show("修改成功!请退出系统后重新登录"); + } else + { + MessageBox.Show("修改失败"); + } } catch (Exception ex) { MessageBox.Show("修改失败:" + ex); + this.Hide(); } + this.Hide(); + } private void FrmChangePassword_Load(object sender, EventArgs e) diff --git a/FrmChangePassword.resx b/FrmChangePassword.resx index 1af7de1..7eadc96 100644 --- a/FrmChangePassword.resx +++ b/FrmChangePassword.resx @@ -117,4 +117,25 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + 112, 17 + + + 207, 17 + + + 302, 17 + + + 425, 17 + + + 553, 17 + + + 679, 17 + \ No newline at end of file diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/FrmChangePassword.Designer.cs b/FrmChangePassword.Designer.cs index 7e83f42..aa98573 100644 --- a/FrmChangePassword.Designer.cs +++ b/FrmChangePassword.Designer.cs @@ -51,7 +51,7 @@ this.labelX1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX1.Location = new System.Drawing.Point(23, 13); this.labelX1.Name = "labelX1"; - this.labelX1.Size = new System.Drawing.Size(50, 16); + this.labelX1.Size = new System.Drawing.Size(56, 18); this.labelX1.TabIndex = 0; this.labelX1.Text = "原始密码"; // @@ -65,7 +65,7 @@ this.labelX2.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX2.Location = new System.Drawing.Point(23, 49); this.labelX2.Name = "labelX2"; - this.labelX2.Size = new System.Drawing.Size(50, 16); + this.labelX2.Size = new System.Drawing.Size(56, 18); this.labelX2.TabIndex = 0; this.labelX2.Text = "最新密码"; // @@ -79,7 +79,7 @@ this.labelX3.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX3.Location = new System.Drawing.Point(23, 85); this.labelX3.Name = "labelX3"; - this.labelX3.Size = new System.Drawing.Size(50, 16); + this.labelX3.Size = new System.Drawing.Size(56, 18); this.labelX3.TabIndex = 0; this.labelX3.Text = "密码确认"; // @@ -107,7 +107,7 @@ this.txt_pwd_new.Name = "txt_pwd_new"; this.txt_pwd_new.PasswordChar = '*'; this.txt_pwd_new.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_new.TabIndex = 1; + this.txt_pwd_new.TabIndex = 2; // // txt_pwd_cfm // @@ -120,7 +120,7 @@ this.txt_pwd_cfm.Name = "txt_pwd_cfm"; this.txt_pwd_cfm.PasswordChar = '*'; this.txt_pwd_cfm.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_cfm.TabIndex = 1; + this.txt_pwd_cfm.TabIndex = 3; // // btn_ok // @@ -130,7 +130,7 @@ this.btn_ok.Name = "btn_ok"; this.btn_ok.Size = new System.Drawing.Size(75, 23); this.btn_ok.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btn_ok.TabIndex = 2; + this.btn_ok.TabIndex = 4; this.btn_ok.Text = "确定"; this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); // diff --git a/FrmChangePassword.cs b/FrmChangePassword.cs index a78b93f..9e22417 100644 --- a/FrmChangePassword.cs +++ b/FrmChangePassword.cs @@ -1,6 +1,9 @@ using System; using System.Data; +using System.Data.OracleClient; +using System.Text.RegularExpressions; using System.Windows.Forms; +using Cyberpipe.SM4; using DevComponents.DotNetBar; namespace Cyberpipe @@ -28,22 +31,43 @@ MessageBox.Show("请确认要修改的密码!"); return; } - string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME='" + Utility.userName + "' and PASSWORD='" + Utility.MD5Encrypt2(txt_pwd_old.Text.Trim()) + "'"; - int count = int.Parse(OracleUtils.ExecuteScalar(OracleUtils.ConnectionString, CommandType.Text, sql).ToString()); + + // 验证密码的复杂度——大小写字母+数字+特殊字符,长度不低于8位 + bool regMatch = Regex.IsMatch(txt_pwd_new.Text.Trim(), "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$"); + if (regMatch == false) + { + MessageBox.Show("请确保密码强度:至少包含字母、数字和特殊字符,不少于8位!"); + return; + } + string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME=:username and PASSWORD=:passwordOld"; + + OracleParameter usernameParam = new OracleParameter(":username", Utility.userName); + OracleParameter passwordOldParam = new OracleParameter(":passwordOld", SM4Utils.SM4EncryptStr(txt_pwd_old.Text.Trim())); + + int count = int.Parse(OledbHelper.ExecuteScalar(sql, usernameParam, passwordOldParam).ToString()); if (count <= 0) { MessageBox.Show("密码错误!"); return; } - sql = "update casic_userinfotest set password='" + Utility.MD5Encrypt2(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; - OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); - MessageBox.Show("修改成功!"); + sql = "update casic_userinfotest set password='" + SM4Utils.SM4EncryptStr(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; + int rowCount = OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); + if (rowCount == 1) + { + MessageBox.Show("修改成功!请退出系统后重新登录"); + } else + { + MessageBox.Show("修改失败"); + } } catch (Exception ex) { MessageBox.Show("修改失败:" + ex); + this.Hide(); } + this.Hide(); + } private void FrmChangePassword_Load(object sender, EventArgs e) diff --git a/FrmChangePassword.resx b/FrmChangePassword.resx index 1af7de1..7eadc96 100644 --- a/FrmChangePassword.resx +++ b/FrmChangePassword.resx @@ -117,4 +117,25 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + 112, 17 + + + 207, 17 + + + 302, 17 + + + 425, 17 + + + 553, 17 + + + 679, 17 + \ No newline at end of file diff --git a/FrmLogin.cs b/FrmLogin.cs index fee6a16..5251170 100644 --- a/FrmLogin.cs +++ b/FrmLogin.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using System.Xml; using DevComponents.DotNetBar; +using Cyberpipe.SM4; namespace Cyberpipe { @@ -56,10 +57,14 @@ /// private bool ValidateUser() { - string passWord = Utility.MD5Encrypt2(textBoxPassWord.Text.Trim()); - string sql = "select * from casic_userinfotest where USERNAME='" + txtUser.Text.Trim() + "' and PASSWORD='" + passWord + "' and sysname='GHFX' "; + string passWord = SM4Utils.SM4EncryptStr(textBoxPassWord.Text.Trim()); + string sql = "select * from casic_userinfotest where USERNAME=:username and PASSWORD=:password and sysname='GHFX'"; + + OracleParameter usernameParam = new OracleParameter(":username", txtUser.Text.Trim()); + OracleParameter passwordParam = new OracleParameter(":password", passWord); + + DataTable dt = OledbHelper.ExecuteDataTable(sql, usernameParam, passwordParam); - DataTable dt = OledbHelper.QueryTable(sql); if (dt == null || dt.Rows.Count <= 0) return false; if (String.IsNullOrEmpty(dt.Rows[0]["rid"].ToString())) return true; sql = "select gid from casic_userroletest where id=" + dt.Rows[0]["rid"] + " and sysname='GHFX' "; diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/FrmChangePassword.Designer.cs b/FrmChangePassword.Designer.cs index 7e83f42..aa98573 100644 --- a/FrmChangePassword.Designer.cs +++ b/FrmChangePassword.Designer.cs @@ -51,7 +51,7 @@ this.labelX1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX1.Location = new System.Drawing.Point(23, 13); this.labelX1.Name = "labelX1"; - this.labelX1.Size = new System.Drawing.Size(50, 16); + this.labelX1.Size = new System.Drawing.Size(56, 18); this.labelX1.TabIndex = 0; this.labelX1.Text = "原始密码"; // @@ -65,7 +65,7 @@ this.labelX2.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX2.Location = new System.Drawing.Point(23, 49); this.labelX2.Name = "labelX2"; - this.labelX2.Size = new System.Drawing.Size(50, 16); + this.labelX2.Size = new System.Drawing.Size(56, 18); this.labelX2.TabIndex = 0; this.labelX2.Text = "最新密码"; // @@ -79,7 +79,7 @@ this.labelX3.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX3.Location = new System.Drawing.Point(23, 85); this.labelX3.Name = "labelX3"; - this.labelX3.Size = new System.Drawing.Size(50, 16); + this.labelX3.Size = new System.Drawing.Size(56, 18); this.labelX3.TabIndex = 0; this.labelX3.Text = "密码确认"; // @@ -107,7 +107,7 @@ this.txt_pwd_new.Name = "txt_pwd_new"; this.txt_pwd_new.PasswordChar = '*'; this.txt_pwd_new.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_new.TabIndex = 1; + this.txt_pwd_new.TabIndex = 2; // // txt_pwd_cfm // @@ -120,7 +120,7 @@ this.txt_pwd_cfm.Name = "txt_pwd_cfm"; this.txt_pwd_cfm.PasswordChar = '*'; this.txt_pwd_cfm.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_cfm.TabIndex = 1; + this.txt_pwd_cfm.TabIndex = 3; // // btn_ok // @@ -130,7 +130,7 @@ this.btn_ok.Name = "btn_ok"; this.btn_ok.Size = new System.Drawing.Size(75, 23); this.btn_ok.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btn_ok.TabIndex = 2; + this.btn_ok.TabIndex = 4; this.btn_ok.Text = "确定"; this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); // diff --git a/FrmChangePassword.cs b/FrmChangePassword.cs index a78b93f..9e22417 100644 --- a/FrmChangePassword.cs +++ b/FrmChangePassword.cs @@ -1,6 +1,9 @@ using System; using System.Data; +using System.Data.OracleClient; +using System.Text.RegularExpressions; using System.Windows.Forms; +using Cyberpipe.SM4; using DevComponents.DotNetBar; namespace Cyberpipe @@ -28,22 +31,43 @@ MessageBox.Show("请确认要修改的密码!"); return; } - string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME='" + Utility.userName + "' and PASSWORD='" + Utility.MD5Encrypt2(txt_pwd_old.Text.Trim()) + "'"; - int count = int.Parse(OracleUtils.ExecuteScalar(OracleUtils.ConnectionString, CommandType.Text, sql).ToString()); + + // 验证密码的复杂度——大小写字母+数字+特殊字符,长度不低于8位 + bool regMatch = Regex.IsMatch(txt_pwd_new.Text.Trim(), "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$"); + if (regMatch == false) + { + MessageBox.Show("请确保密码强度:至少包含字母、数字和特殊字符,不少于8位!"); + return; + } + string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME=:username and PASSWORD=:passwordOld"; + + OracleParameter usernameParam = new OracleParameter(":username", Utility.userName); + OracleParameter passwordOldParam = new OracleParameter(":passwordOld", SM4Utils.SM4EncryptStr(txt_pwd_old.Text.Trim())); + + int count = int.Parse(OledbHelper.ExecuteScalar(sql, usernameParam, passwordOldParam).ToString()); if (count <= 0) { MessageBox.Show("密码错误!"); return; } - sql = "update casic_userinfotest set password='" + Utility.MD5Encrypt2(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; - OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); - MessageBox.Show("修改成功!"); + sql = "update casic_userinfotest set password='" + SM4Utils.SM4EncryptStr(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; + int rowCount = OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); + if (rowCount == 1) + { + MessageBox.Show("修改成功!请退出系统后重新登录"); + } else + { + MessageBox.Show("修改失败"); + } } catch (Exception ex) { MessageBox.Show("修改失败:" + ex); + this.Hide(); } + this.Hide(); + } private void FrmChangePassword_Load(object sender, EventArgs e) diff --git a/FrmChangePassword.resx b/FrmChangePassword.resx index 1af7de1..7eadc96 100644 --- a/FrmChangePassword.resx +++ b/FrmChangePassword.resx @@ -117,4 +117,25 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + 112, 17 + + + 207, 17 + + + 302, 17 + + + 425, 17 + + + 553, 17 + + + 679, 17 + \ No newline at end of file diff --git a/FrmLogin.cs b/FrmLogin.cs index fee6a16..5251170 100644 --- a/FrmLogin.cs +++ b/FrmLogin.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using System.Xml; using DevComponents.DotNetBar; +using Cyberpipe.SM4; namespace Cyberpipe { @@ -56,10 +57,14 @@ /// private bool ValidateUser() { - string passWord = Utility.MD5Encrypt2(textBoxPassWord.Text.Trim()); - string sql = "select * from casic_userinfotest where USERNAME='" + txtUser.Text.Trim() + "' and PASSWORD='" + passWord + "' and sysname='GHFX' "; + string passWord = SM4Utils.SM4EncryptStr(textBoxPassWord.Text.Trim()); + string sql = "select * from casic_userinfotest where USERNAME=:username and PASSWORD=:password and sysname='GHFX'"; + + OracleParameter usernameParam = new OracleParameter(":username", txtUser.Text.Trim()); + OracleParameter passwordParam = new OracleParameter(":password", passWord); + + DataTable dt = OledbHelper.ExecuteDataTable(sql, usernameParam, passwordParam); - DataTable dt = OledbHelper.QueryTable(sql); if (dt == null || dt.Rows.Count <= 0) return false; if (String.IsNullOrEmpty(dt.Rows[0]["rid"].ToString())) return true; sql = "select gid from casic_userroletest where id=" + dt.Rows[0]["rid"] + " and sysname='GHFX' "; diff --git a/OracleHelper.cs b/OracleHelper.cs index 52f4248..475347d 100644 --- a/OracleHelper.cs +++ b/OracleHelper.cs @@ -182,6 +182,39 @@ return num; } + public static int ExecuteScalar(string sql, params OracleParameter[] ops) + { + string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer + + ")(PORT=1521))(CONNECT_DATA=(SID=" + Utility.dbdatabase + + ")));Persist Security Info=True;User Id=" + Utility.userID + + "; Password=" + Utility.DBPassword + ""; + conn = new OracleConnection(connectString); + oracleCmd = conn.CreateCommand(); + oracleCmd.CommandText = sql; + int num = 0; + try + { + conn.Open(); + foreach (OracleParameter op in ops) + { + oracleCmd.Parameters.Add(op); + } + num = Convert.ToInt32(oracleCmd.ExecuteScalar().ToString()); + } + catch (Exception ex) + { + num = -1; + } + finally + { + if (conn.State == ConnectionState.Open) + { + conn.Close(); + } + } + return num; + } + public static DataSet getDataSet(string SQLstr, string tableName) { string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/FrmChangePassword.Designer.cs b/FrmChangePassword.Designer.cs index 7e83f42..aa98573 100644 --- a/FrmChangePassword.Designer.cs +++ b/FrmChangePassword.Designer.cs @@ -51,7 +51,7 @@ this.labelX1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX1.Location = new System.Drawing.Point(23, 13); this.labelX1.Name = "labelX1"; - this.labelX1.Size = new System.Drawing.Size(50, 16); + this.labelX1.Size = new System.Drawing.Size(56, 18); this.labelX1.TabIndex = 0; this.labelX1.Text = "原始密码"; // @@ -65,7 +65,7 @@ this.labelX2.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX2.Location = new System.Drawing.Point(23, 49); this.labelX2.Name = "labelX2"; - this.labelX2.Size = new System.Drawing.Size(50, 16); + this.labelX2.Size = new System.Drawing.Size(56, 18); this.labelX2.TabIndex = 0; this.labelX2.Text = "最新密码"; // @@ -79,7 +79,7 @@ this.labelX3.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX3.Location = new System.Drawing.Point(23, 85); this.labelX3.Name = "labelX3"; - this.labelX3.Size = new System.Drawing.Size(50, 16); + this.labelX3.Size = new System.Drawing.Size(56, 18); this.labelX3.TabIndex = 0; this.labelX3.Text = "密码确认"; // @@ -107,7 +107,7 @@ this.txt_pwd_new.Name = "txt_pwd_new"; this.txt_pwd_new.PasswordChar = '*'; this.txt_pwd_new.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_new.TabIndex = 1; + this.txt_pwd_new.TabIndex = 2; // // txt_pwd_cfm // @@ -120,7 +120,7 @@ this.txt_pwd_cfm.Name = "txt_pwd_cfm"; this.txt_pwd_cfm.PasswordChar = '*'; this.txt_pwd_cfm.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_cfm.TabIndex = 1; + this.txt_pwd_cfm.TabIndex = 3; // // btn_ok // @@ -130,7 +130,7 @@ this.btn_ok.Name = "btn_ok"; this.btn_ok.Size = new System.Drawing.Size(75, 23); this.btn_ok.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btn_ok.TabIndex = 2; + this.btn_ok.TabIndex = 4; this.btn_ok.Text = "确定"; this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); // diff --git a/FrmChangePassword.cs b/FrmChangePassword.cs index a78b93f..9e22417 100644 --- a/FrmChangePassword.cs +++ b/FrmChangePassword.cs @@ -1,6 +1,9 @@ using System; using System.Data; +using System.Data.OracleClient; +using System.Text.RegularExpressions; using System.Windows.Forms; +using Cyberpipe.SM4; using DevComponents.DotNetBar; namespace Cyberpipe @@ -28,22 +31,43 @@ MessageBox.Show("请确认要修改的密码!"); return; } - string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME='" + Utility.userName + "' and PASSWORD='" + Utility.MD5Encrypt2(txt_pwd_old.Text.Trim()) + "'"; - int count = int.Parse(OracleUtils.ExecuteScalar(OracleUtils.ConnectionString, CommandType.Text, sql).ToString()); + + // 验证密码的复杂度——大小写字母+数字+特殊字符,长度不低于8位 + bool regMatch = Regex.IsMatch(txt_pwd_new.Text.Trim(), "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$"); + if (regMatch == false) + { + MessageBox.Show("请确保密码强度:至少包含字母、数字和特殊字符,不少于8位!"); + return; + } + string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME=:username and PASSWORD=:passwordOld"; + + OracleParameter usernameParam = new OracleParameter(":username", Utility.userName); + OracleParameter passwordOldParam = new OracleParameter(":passwordOld", SM4Utils.SM4EncryptStr(txt_pwd_old.Text.Trim())); + + int count = int.Parse(OledbHelper.ExecuteScalar(sql, usernameParam, passwordOldParam).ToString()); if (count <= 0) { MessageBox.Show("密码错误!"); return; } - sql = "update casic_userinfotest set password='" + Utility.MD5Encrypt2(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; - OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); - MessageBox.Show("修改成功!"); + sql = "update casic_userinfotest set password='" + SM4Utils.SM4EncryptStr(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; + int rowCount = OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); + if (rowCount == 1) + { + MessageBox.Show("修改成功!请退出系统后重新登录"); + } else + { + MessageBox.Show("修改失败"); + } } catch (Exception ex) { MessageBox.Show("修改失败:" + ex); + this.Hide(); } + this.Hide(); + } private void FrmChangePassword_Load(object sender, EventArgs e) diff --git a/FrmChangePassword.resx b/FrmChangePassword.resx index 1af7de1..7eadc96 100644 --- a/FrmChangePassword.resx +++ b/FrmChangePassword.resx @@ -117,4 +117,25 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + 112, 17 + + + 207, 17 + + + 302, 17 + + + 425, 17 + + + 553, 17 + + + 679, 17 + \ No newline at end of file diff --git a/FrmLogin.cs b/FrmLogin.cs index fee6a16..5251170 100644 --- a/FrmLogin.cs +++ b/FrmLogin.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using System.Xml; using DevComponents.DotNetBar; +using Cyberpipe.SM4; namespace Cyberpipe { @@ -56,10 +57,14 @@ /// private bool ValidateUser() { - string passWord = Utility.MD5Encrypt2(textBoxPassWord.Text.Trim()); - string sql = "select * from casic_userinfotest where USERNAME='" + txtUser.Text.Trim() + "' and PASSWORD='" + passWord + "' and sysname='GHFX' "; + string passWord = SM4Utils.SM4EncryptStr(textBoxPassWord.Text.Trim()); + string sql = "select * from casic_userinfotest where USERNAME=:username and PASSWORD=:password and sysname='GHFX'"; + + OracleParameter usernameParam = new OracleParameter(":username", txtUser.Text.Trim()); + OracleParameter passwordParam = new OracleParameter(":password", passWord); + + DataTable dt = OledbHelper.ExecuteDataTable(sql, usernameParam, passwordParam); - DataTable dt = OledbHelper.QueryTable(sql); if (dt == null || dt.Rows.Count <= 0) return false; if (String.IsNullOrEmpty(dt.Rows[0]["rid"].ToString())) return true; sql = "select gid from casic_userroletest where id=" + dt.Rows[0]["rid"] + " and sysname='GHFX' "; diff --git a/OracleHelper.cs b/OracleHelper.cs index 52f4248..475347d 100644 --- a/OracleHelper.cs +++ b/OracleHelper.cs @@ -182,6 +182,39 @@ return num; } + public static int ExecuteScalar(string sql, params OracleParameter[] ops) + { + string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer + + ")(PORT=1521))(CONNECT_DATA=(SID=" + Utility.dbdatabase + + ")));Persist Security Info=True;User Id=" + Utility.userID + + "; Password=" + Utility.DBPassword + ""; + conn = new OracleConnection(connectString); + oracleCmd = conn.CreateCommand(); + oracleCmd.CommandText = sql; + int num = 0; + try + { + conn.Open(); + foreach (OracleParameter op in ops) + { + oracleCmd.Parameters.Add(op); + } + num = Convert.ToInt32(oracleCmd.ExecuteScalar().ToString()); + } + catch (Exception ex) + { + num = -1; + } + finally + { + if (conn.State == ConnectionState.Open) + { + conn.Close(); + } + } + return num; + } + public static DataSet getDataSet(string SQLstr, string tableName) { string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer diff --git a/SM4/DesTools.cs b/SM4/DesTools.cs new file mode 100644 index 0000000..4f0ac27 --- /dev/null +++ b/SM4/DesTools.cs @@ -0,0 +1,121 @@ +using System; +using System.Reflection; +using System.Security.Cryptography; +using System.Text; + +namespace Cyberpipe.SM4 +{ + public class DesTools + { + #region 3des加密 + + /// + /// 3des ecb模式加密() + /// + /// 待加密的字符串 + /// 密钥 + /// 加密矢量:只有在CBC解密模式下才适用 + /// 运算模式 + /// 加密后的字符串 + public static string Encrypt3Des(string aStrString, string aStrKey) + { + byte[] str = strToHexByte(aStrString); + byte[] key = strToHexByte(aStrKey + aStrKey.Substring(0, 16)); + + TripleDESCryptoServiceProvider tdsc = new TripleDESCryptoServiceProvider(); + tdsc.Padding = PaddingMode.None; + + byte[] IV = { 0xB0, 0xA2, 0xB8, 0xA3, 0xDA, 0xCC, 0xDA, 0xCC }; + //指定密匙长度,默认为192位 + tdsc.KeySize = 128; + //使用指定的key和IV(加密向量) + Type t = Type.GetType("System.Security.Cryptography.CryptoAPITransformMode"); + object obj = t.GetField("Encrypt", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).GetValue(t); + MethodInfo mi = tdsc.GetType().GetMethod("_NewEncryptor", BindingFlags.Instance | BindingFlags.NonPublic); + ICryptoTransform desCrypt = (ICryptoTransform)mi.Invoke(tdsc, new object[] { key, CipherMode.ECB, null, 0, obj }); + tdsc.IV = IV; + //加密模式,偏移 + tdsc.Mode = CipherMode.ECB; + + //进行加密转换运算 + //ICryptoTransform ct = tdsc.CreateDecryptor(); + //8很关键,加密结果是8字节数组 + byte[] results = desCrypt.TransformFinalBlock(str, 0, str.Length); + + return byteToHexStr(results).ToUpper(); ; + + } + + #endregion + + + public static String generalStringToAscii(int length) + { + + int num = 1; + for (int i = 0; i < length; i++) + { + num *= 10; + } + + Random rand = new Random(); + String strRandom = (rand.Next(num).ToString()).PadLeft(length, '0'); + + StringBuilder sb = new StringBuilder(); + byte[] bytes = Encoding.ASCII.GetBytes(strRandom); + for (int i = 0; i < bytes.Length; i++) + { + sb.Append((int)bytes[i]); + } + + return sb.ToString(); + } + + public static String padding80(String data) + { + + int padlen = 8 - (data.Length / 2) % 8; + String padstr = ""; + for (int i = 0; i < padlen - 1; i++) + { + padstr += "00"; + } + data = data + "80" + padstr; + return data; + } + + /// + /// 字符串转16进制字节数组 + /// + /// + /// + public static byte[] strToHexByte(string hexString) + { + hexString = hexString.Replace(" ", ""); + if ((hexString.Length % 2) != 0) + hexString += "0"; + byte[] returnBytes = new byte[hexString.Length / 2]; + for (int i = 0; i < returnBytes.Length; i++) + returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + return returnBytes; + } + + /// + /// 字节数组转16进制字符串 + /// + /// + /// + public static string byteToHexStr(byte[] bytes) + { + string returnStr = ""; + if (bytes != null) + { + for (int i = 0; i < bytes.Length; i++) + { + returnStr += bytes[i].ToString("x2"); + } + } + return returnStr; + } + } +} diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/FrmChangePassword.Designer.cs b/FrmChangePassword.Designer.cs index 7e83f42..aa98573 100644 --- a/FrmChangePassword.Designer.cs +++ b/FrmChangePassword.Designer.cs @@ -51,7 +51,7 @@ this.labelX1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX1.Location = new System.Drawing.Point(23, 13); this.labelX1.Name = "labelX1"; - this.labelX1.Size = new System.Drawing.Size(50, 16); + this.labelX1.Size = new System.Drawing.Size(56, 18); this.labelX1.TabIndex = 0; this.labelX1.Text = "原始密码"; // @@ -65,7 +65,7 @@ this.labelX2.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX2.Location = new System.Drawing.Point(23, 49); this.labelX2.Name = "labelX2"; - this.labelX2.Size = new System.Drawing.Size(50, 16); + this.labelX2.Size = new System.Drawing.Size(56, 18); this.labelX2.TabIndex = 0; this.labelX2.Text = "最新密码"; // @@ -79,7 +79,7 @@ this.labelX3.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX3.Location = new System.Drawing.Point(23, 85); this.labelX3.Name = "labelX3"; - this.labelX3.Size = new System.Drawing.Size(50, 16); + this.labelX3.Size = new System.Drawing.Size(56, 18); this.labelX3.TabIndex = 0; this.labelX3.Text = "密码确认"; // @@ -107,7 +107,7 @@ this.txt_pwd_new.Name = "txt_pwd_new"; this.txt_pwd_new.PasswordChar = '*'; this.txt_pwd_new.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_new.TabIndex = 1; + this.txt_pwd_new.TabIndex = 2; // // txt_pwd_cfm // @@ -120,7 +120,7 @@ this.txt_pwd_cfm.Name = "txt_pwd_cfm"; this.txt_pwd_cfm.PasswordChar = '*'; this.txt_pwd_cfm.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_cfm.TabIndex = 1; + this.txt_pwd_cfm.TabIndex = 3; // // btn_ok // @@ -130,7 +130,7 @@ this.btn_ok.Name = "btn_ok"; this.btn_ok.Size = new System.Drawing.Size(75, 23); this.btn_ok.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btn_ok.TabIndex = 2; + this.btn_ok.TabIndex = 4; this.btn_ok.Text = "确定"; this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); // diff --git a/FrmChangePassword.cs b/FrmChangePassword.cs index a78b93f..9e22417 100644 --- a/FrmChangePassword.cs +++ b/FrmChangePassword.cs @@ -1,6 +1,9 @@ using System; using System.Data; +using System.Data.OracleClient; +using System.Text.RegularExpressions; using System.Windows.Forms; +using Cyberpipe.SM4; using DevComponents.DotNetBar; namespace Cyberpipe @@ -28,22 +31,43 @@ MessageBox.Show("请确认要修改的密码!"); return; } - string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME='" + Utility.userName + "' and PASSWORD='" + Utility.MD5Encrypt2(txt_pwd_old.Text.Trim()) + "'"; - int count = int.Parse(OracleUtils.ExecuteScalar(OracleUtils.ConnectionString, CommandType.Text, sql).ToString()); + + // 验证密码的复杂度——大小写字母+数字+特殊字符,长度不低于8位 + bool regMatch = Regex.IsMatch(txt_pwd_new.Text.Trim(), "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$"); + if (regMatch == false) + { + MessageBox.Show("请确保密码强度:至少包含字母、数字和特殊字符,不少于8位!"); + return; + } + string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME=:username and PASSWORD=:passwordOld"; + + OracleParameter usernameParam = new OracleParameter(":username", Utility.userName); + OracleParameter passwordOldParam = new OracleParameter(":passwordOld", SM4Utils.SM4EncryptStr(txt_pwd_old.Text.Trim())); + + int count = int.Parse(OledbHelper.ExecuteScalar(sql, usernameParam, passwordOldParam).ToString()); if (count <= 0) { MessageBox.Show("密码错误!"); return; } - sql = "update casic_userinfotest set password='" + Utility.MD5Encrypt2(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; - OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); - MessageBox.Show("修改成功!"); + sql = "update casic_userinfotest set password='" + SM4Utils.SM4EncryptStr(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; + int rowCount = OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); + if (rowCount == 1) + { + MessageBox.Show("修改成功!请退出系统后重新登录"); + } else + { + MessageBox.Show("修改失败"); + } } catch (Exception ex) { MessageBox.Show("修改失败:" + ex); + this.Hide(); } + this.Hide(); + } private void FrmChangePassword_Load(object sender, EventArgs e) diff --git a/FrmChangePassword.resx b/FrmChangePassword.resx index 1af7de1..7eadc96 100644 --- a/FrmChangePassword.resx +++ b/FrmChangePassword.resx @@ -117,4 +117,25 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + 112, 17 + + + 207, 17 + + + 302, 17 + + + 425, 17 + + + 553, 17 + + + 679, 17 + \ No newline at end of file diff --git a/FrmLogin.cs b/FrmLogin.cs index fee6a16..5251170 100644 --- a/FrmLogin.cs +++ b/FrmLogin.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using System.Xml; using DevComponents.DotNetBar; +using Cyberpipe.SM4; namespace Cyberpipe { @@ -56,10 +57,14 @@ /// private bool ValidateUser() { - string passWord = Utility.MD5Encrypt2(textBoxPassWord.Text.Trim()); - string sql = "select * from casic_userinfotest where USERNAME='" + txtUser.Text.Trim() + "' and PASSWORD='" + passWord + "' and sysname='GHFX' "; + string passWord = SM4Utils.SM4EncryptStr(textBoxPassWord.Text.Trim()); + string sql = "select * from casic_userinfotest where USERNAME=:username and PASSWORD=:password and sysname='GHFX'"; + + OracleParameter usernameParam = new OracleParameter(":username", txtUser.Text.Trim()); + OracleParameter passwordParam = new OracleParameter(":password", passWord); + + DataTable dt = OledbHelper.ExecuteDataTable(sql, usernameParam, passwordParam); - DataTable dt = OledbHelper.QueryTable(sql); if (dt == null || dt.Rows.Count <= 0) return false; if (String.IsNullOrEmpty(dt.Rows[0]["rid"].ToString())) return true; sql = "select gid from casic_userroletest where id=" + dt.Rows[0]["rid"] + " and sysname='GHFX' "; diff --git a/OracleHelper.cs b/OracleHelper.cs index 52f4248..475347d 100644 --- a/OracleHelper.cs +++ b/OracleHelper.cs @@ -182,6 +182,39 @@ return num; } + public static int ExecuteScalar(string sql, params OracleParameter[] ops) + { + string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer + + ")(PORT=1521))(CONNECT_DATA=(SID=" + Utility.dbdatabase + + ")));Persist Security Info=True;User Id=" + Utility.userID + + "; Password=" + Utility.DBPassword + ""; + conn = new OracleConnection(connectString); + oracleCmd = conn.CreateCommand(); + oracleCmd.CommandText = sql; + int num = 0; + try + { + conn.Open(); + foreach (OracleParameter op in ops) + { + oracleCmd.Parameters.Add(op); + } + num = Convert.ToInt32(oracleCmd.ExecuteScalar().ToString()); + } + catch (Exception ex) + { + num = -1; + } + finally + { + if (conn.State == ConnectionState.Open) + { + conn.Close(); + } + } + return num; + } + public static DataSet getDataSet(string SQLstr, string tableName) { string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer diff --git a/SM4/DesTools.cs b/SM4/DesTools.cs new file mode 100644 index 0000000..4f0ac27 --- /dev/null +++ b/SM4/DesTools.cs @@ -0,0 +1,121 @@ +using System; +using System.Reflection; +using System.Security.Cryptography; +using System.Text; + +namespace Cyberpipe.SM4 +{ + public class DesTools + { + #region 3des加密 + + /// + /// 3des ecb模式加密() + /// + /// 待加密的字符串 + /// 密钥 + /// 加密矢量:只有在CBC解密模式下才适用 + /// 运算模式 + /// 加密后的字符串 + public static string Encrypt3Des(string aStrString, string aStrKey) + { + byte[] str = strToHexByte(aStrString); + byte[] key = strToHexByte(aStrKey + aStrKey.Substring(0, 16)); + + TripleDESCryptoServiceProvider tdsc = new TripleDESCryptoServiceProvider(); + tdsc.Padding = PaddingMode.None; + + byte[] IV = { 0xB0, 0xA2, 0xB8, 0xA3, 0xDA, 0xCC, 0xDA, 0xCC }; + //指定密匙长度,默认为192位 + tdsc.KeySize = 128; + //使用指定的key和IV(加密向量) + Type t = Type.GetType("System.Security.Cryptography.CryptoAPITransformMode"); + object obj = t.GetField("Encrypt", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).GetValue(t); + MethodInfo mi = tdsc.GetType().GetMethod("_NewEncryptor", BindingFlags.Instance | BindingFlags.NonPublic); + ICryptoTransform desCrypt = (ICryptoTransform)mi.Invoke(tdsc, new object[] { key, CipherMode.ECB, null, 0, obj }); + tdsc.IV = IV; + //加密模式,偏移 + tdsc.Mode = CipherMode.ECB; + + //进行加密转换运算 + //ICryptoTransform ct = tdsc.CreateDecryptor(); + //8很关键,加密结果是8字节数组 + byte[] results = desCrypt.TransformFinalBlock(str, 0, str.Length); + + return byteToHexStr(results).ToUpper(); ; + + } + + #endregion + + + public static String generalStringToAscii(int length) + { + + int num = 1; + for (int i = 0; i < length; i++) + { + num *= 10; + } + + Random rand = new Random(); + String strRandom = (rand.Next(num).ToString()).PadLeft(length, '0'); + + StringBuilder sb = new StringBuilder(); + byte[] bytes = Encoding.ASCII.GetBytes(strRandom); + for (int i = 0; i < bytes.Length; i++) + { + sb.Append((int)bytes[i]); + } + + return sb.ToString(); + } + + public static String padding80(String data) + { + + int padlen = 8 - (data.Length / 2) % 8; + String padstr = ""; + for (int i = 0; i < padlen - 1; i++) + { + padstr += "00"; + } + data = data + "80" + padstr; + return data; + } + + /// + /// 字符串转16进制字节数组 + /// + /// + /// + public static byte[] strToHexByte(string hexString) + { + hexString = hexString.Replace(" ", ""); + if ((hexString.Length % 2) != 0) + hexString += "0"; + byte[] returnBytes = new byte[hexString.Length / 2]; + for (int i = 0; i < returnBytes.Length; i++) + returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + return returnBytes; + } + + /// + /// 字节数组转16进制字符串 + /// + /// + /// + public static string byteToHexStr(byte[] bytes) + { + string returnStr = ""; + if (bytes != null) + { + for (int i = 0; i < bytes.Length; i++) + { + returnStr += bytes[i].ToString("x2"); + } + } + return returnStr; + } + } +} diff --git a/SM4/SM4.cs b/SM4/SM4.cs new file mode 100644 index 0000000..6f19a84 --- /dev/null +++ b/SM4/SM4.cs @@ -0,0 +1,317 @@ +using System; +using System.Collections.Generic; + +namespace Cyberpipe.SM4 +{ + class SM4 + { + public const int SM4_ENCRYPT = 1; + public const int SM4_DECRYPT = 0; + + private long GET_ULONG_BE(byte[] b, int i) + { + long n = (long)(b[i] & 0xff) << 24 | (long)((b[i + 1] & 0xff) << 16) | (long)((b[i + 2] & 0xff) << 8) | (long)(b[i + 3] & 0xff) & 0xffffffffL; + return n; + } + + private void PUT_ULONG_BE(long n, byte[] b, int i) + { + b[i] = (byte)(int)(0xFF & n >> 24); + b[i + 1] = (byte)(int)(0xFF & n >> 16); + b[i + 2] = (byte)(int)(0xFF & n >> 8); + b[i + 3] = (byte)(int)(0xFF & n); + } + + private long SHL(long x, int n) + { + return (x & 0xFFFFFFFF) << n; + } + + private long ROTL(long x, int n) + { + return SHL(x, n) | x >> (32 - n); + } + + private void SWAP(long[] sk, int i) + { + long t = sk[i]; + sk[i] = sk[(31 - i)]; + sk[(31 - i)] = t; + } + + public byte[] SboxTable = new byte[] { (byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe, + (byte) 0xcc, (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6, + 0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b, 0x67, + (byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3, + (byte) 0xaa, 0x44, 0x13, 0x26, 0x49, (byte) 0x86, 0x06, + (byte) 0x99, (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91, + (byte) 0xef, (byte) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, + (byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62, (byte) 0xe4, + (byte) 0xb3, 0x1c, (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8, + (byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94, (byte) 0xfa, + 0x75, (byte) 0x8f, 0x3f, (byte) 0xa6, 0x47, 0x07, (byte) 0xa7, + (byte) 0xfc, (byte) 0xf3, 0x73, 0x17, (byte) 0xba, (byte) 0x83, + 0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8, + 0x68, 0x6b, (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda, + (byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70, 0x56, + (byte) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1, + (byte) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (byte) 0x87, + (byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27, + 0x52, 0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4, + (byte) 0xc8, (byte) 0x9e, (byte) 0xea, (byte) 0xbf, (byte) 0x8a, + (byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3, + (byte) 0xf7, (byte) 0xf2, (byte) 0xce, (byte) 0xf9, 0x61, 0x15, + (byte) 0xa1, (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4, + (byte) 0x9b, 0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32, + 0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3, 0x1d, + (byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca, + 0x60, (byte) 0xc0, 0x29, 0x23, (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f, + (byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd, + (byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, + 0x51, (byte) 0x8d, 0x1b, (byte) 0xaf, (byte) 0x92, (byte) 0xbb, + (byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41, + 0x1f, 0x10, 0x5a, (byte) 0xd8, 0x0a, (byte) 0xc1, 0x31, + (byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d, + 0x74, (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4, + (byte) 0xb0, (byte) 0x89, 0x69, (byte) 0x97, 0x4a, 0x0c, + (byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09, + (byte) 0xc5, 0x6e, (byte) 0xc6, (byte) 0x84, 0x18, (byte) 0xf0, + 0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79, + (byte) 0xee, 0x5f, 0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48 }; + + public uint[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc }; + + public uint[] CK = { 0x00070e15,0x1c232a31,0x383f464d,0x545b6269, + 0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9, + 0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249, + 0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9, + 0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229, + 0x30373e45,0x4c535a61,0x686f767d,0x848b9299, + 0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209, + 0x10171e25,0x2c333a41,0x484f565d,0x646b7279 }; + + private byte sm4Sbox(byte inch) + { + int i = inch & 0xFF; + byte retVal = SboxTable[i]; + return retVal; + } + + private long sm4Lt(long ka) + { + long bb = 0L; + long c = 0L; + byte[] a = new byte[4]; + byte[] b = new byte[4]; + PUT_ULONG_BE(ka, a, 0); + b[0] = sm4Sbox(a[0]); + b[1] = sm4Sbox(a[1]); + b[2] = sm4Sbox(a[2]); + b[3] = sm4Sbox(a[3]); + bb = GET_ULONG_BE(b, 0); + c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24); + return c; + } + + private long sm4F(long x0, long x1, long x2, long x3, long rk) + { + return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk); + } + + private long sm4CalciRK(long ka) + { + long bb = 0L; + long rk = 0L; + byte[] a = new byte[4]; + byte[] b = new byte[4]; + PUT_ULONG_BE(ka, a, 0); + b[0] = sm4Sbox(a[0]); + b[1] = sm4Sbox(a[1]); + b[2] = sm4Sbox(a[2]); + b[3] = sm4Sbox(a[3]); + bb = GET_ULONG_BE(b, 0); + rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23); + return rk; + } + + private void sm4_setkey(long[] SK, byte[] key) + { + long[] MK = new long[4]; + long[] k = new long[36]; + int i = 0; + MK[0] = GET_ULONG_BE(key, 0); + MK[1] = GET_ULONG_BE(key, 4); + MK[2] = GET_ULONG_BE(key, 8); + MK[3] = GET_ULONG_BE(key, 12); + k[0] = MK[0] ^ (long)FK[0]; + k[1] = MK[1] ^ (long)FK[1]; + k[2] = MK[2] ^ (long)FK[2]; + k[3] = MK[3] ^ (long)FK[3]; + for (; i < 32; i++) + { + k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long)CK[i])); + SK[i] = k[(i + 4)]; + } + } + + private void sm4_one_round(long[] sk, byte[] input, byte[] output) + { + int i = 0; + long[] ulbuf = new long[36]; + ulbuf[0] = GET_ULONG_BE(input, 0); + ulbuf[1] = GET_ULONG_BE(input, 4); + ulbuf[2] = GET_ULONG_BE(input, 8); + ulbuf[3] = GET_ULONG_BE(input, 12); + while (i < 32) + { + ulbuf[(i + 4)] = sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]); + i++; + } + PUT_ULONG_BE(ulbuf[35], output, 0); + PUT_ULONG_BE(ulbuf[34], output, 4); + PUT_ULONG_BE(ulbuf[33], output, 8); + PUT_ULONG_BE(ulbuf[32], output, 12); + } + + private byte[] padding(byte[] input, int mode) + { + if (input == null) + { + return null; + } + + byte[] ret = (byte[])null; + if (mode == SM4_ENCRYPT) + { + int p = (input.Length % 16 == 0) ? 0 : (16 - input.Length % 16); + ret = new byte[input.Length + p]; + Array.Copy(input, 0, ret, 0, input.Length); + for (int i = 0; i < p; i++) + { + ret[input.Length + i] = 0x00; + } + } + else + { + int p = input[input.Length - 1]; + ret = new byte[input.Length - p]; + Array.Copy(input, 0, ret, 0, input.Length - p); + } + return ret; + } + + public void sm4_setkey_enc(SM4_Context ctx, byte[] key) + { + ctx.mode = SM4_ENCRYPT; + sm4_setkey(ctx.sk, key); + } + + public void sm4_setkey_dec(SM4_Context ctx, byte[] key) + { + int i = 0; + ctx.mode = SM4_DECRYPT; + sm4_setkey(ctx.sk, key); + for (i = 0; i < 16; i++) + { + SWAP(ctx.sk, i); + } + } + + public byte[] sm4_crypt_ecb(SM4_Context ctx, byte[] input) + { + if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT)) + { + input = padding(input, SM4_ENCRYPT); + } + + int length = input.Length; + byte[] bins = new byte[length]; + Array.Copy(input, 0, bins, 0, length); + byte[] bous = new byte[length]; + for (int i = 0; length > 0; length -= 16, i++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + sm4_one_round(ctx.sk, inBytes, outBytes); + Array.Copy(outBytes, 0, bous, i * 16, length > 16 ? 16 : length); + } + + //if (ctx.isPadding && ctx.mode == SM4_DECRYPT) + //{ + // bous = padding(bous, SM4_DECRYPT); + //} + return bous; + } + + public byte[] sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input) + { + if (ctx.isPadding && ctx.mode == SM4_ENCRYPT) + { + input = padding(input, SM4_ENCRYPT); + } + + int i = 0; + int length = input.Length; + byte[] bins = new byte[length]; + Array.Copy(input, 0, bins, 0, length); + byte[] bous = null; + List bousList = new List(); + if (ctx.mode == SM4_ENCRYPT) + { + for (int j = 0; length > 0; length -= 16, j++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + byte[] out1 = new byte[16]; + + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + for (i = 0; i < 16; i++) + { + outBytes[i] = ((byte)(inBytes[i] ^ iv[i])); + } + sm4_one_round(ctx.sk, outBytes, out1); + Array.Copy(out1, 0, iv, 0, 16); + for (int k = 0; k < 16; k++) + { + bousList.Add(out1[k]); + } + } + } + else + { + byte[] temp = new byte[16]; + for (int j = 0; length > 0; length -= 16, j++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + byte[] out1 = new byte[16]; + + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + Array.Copy(inBytes, 0, temp, 0, 16); + sm4_one_round(ctx.sk, inBytes, outBytes); + for (i = 0; i < 16; i++) + { + out1[i] = ((byte)(outBytes[i] ^ iv[i])); + } + Array.Copy(temp, 0, iv, 0, 16); + for (int k = 0; k < 16; k++) + { + bousList.Add(out1[k]); + } + } + + } + + if (ctx.isPadding && ctx.mode == SM4_DECRYPT) + { + bous = padding(bousList.ToArray(), SM4_DECRYPT); + return bous; + } + else + { + return bousList.ToArray(); + } + } + } +} diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/FrmChangePassword.Designer.cs b/FrmChangePassword.Designer.cs index 7e83f42..aa98573 100644 --- a/FrmChangePassword.Designer.cs +++ b/FrmChangePassword.Designer.cs @@ -51,7 +51,7 @@ this.labelX1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX1.Location = new System.Drawing.Point(23, 13); this.labelX1.Name = "labelX1"; - this.labelX1.Size = new System.Drawing.Size(50, 16); + this.labelX1.Size = new System.Drawing.Size(56, 18); this.labelX1.TabIndex = 0; this.labelX1.Text = "原始密码"; // @@ -65,7 +65,7 @@ this.labelX2.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX2.Location = new System.Drawing.Point(23, 49); this.labelX2.Name = "labelX2"; - this.labelX2.Size = new System.Drawing.Size(50, 16); + this.labelX2.Size = new System.Drawing.Size(56, 18); this.labelX2.TabIndex = 0; this.labelX2.Text = "最新密码"; // @@ -79,7 +79,7 @@ this.labelX3.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX3.Location = new System.Drawing.Point(23, 85); this.labelX3.Name = "labelX3"; - this.labelX3.Size = new System.Drawing.Size(50, 16); + this.labelX3.Size = new System.Drawing.Size(56, 18); this.labelX3.TabIndex = 0; this.labelX3.Text = "密码确认"; // @@ -107,7 +107,7 @@ this.txt_pwd_new.Name = "txt_pwd_new"; this.txt_pwd_new.PasswordChar = '*'; this.txt_pwd_new.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_new.TabIndex = 1; + this.txt_pwd_new.TabIndex = 2; // // txt_pwd_cfm // @@ -120,7 +120,7 @@ this.txt_pwd_cfm.Name = "txt_pwd_cfm"; this.txt_pwd_cfm.PasswordChar = '*'; this.txt_pwd_cfm.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_cfm.TabIndex = 1; + this.txt_pwd_cfm.TabIndex = 3; // // btn_ok // @@ -130,7 +130,7 @@ this.btn_ok.Name = "btn_ok"; this.btn_ok.Size = new System.Drawing.Size(75, 23); this.btn_ok.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btn_ok.TabIndex = 2; + this.btn_ok.TabIndex = 4; this.btn_ok.Text = "确定"; this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); // diff --git a/FrmChangePassword.cs b/FrmChangePassword.cs index a78b93f..9e22417 100644 --- a/FrmChangePassword.cs +++ b/FrmChangePassword.cs @@ -1,6 +1,9 @@ using System; using System.Data; +using System.Data.OracleClient; +using System.Text.RegularExpressions; using System.Windows.Forms; +using Cyberpipe.SM4; using DevComponents.DotNetBar; namespace Cyberpipe @@ -28,22 +31,43 @@ MessageBox.Show("请确认要修改的密码!"); return; } - string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME='" + Utility.userName + "' and PASSWORD='" + Utility.MD5Encrypt2(txt_pwd_old.Text.Trim()) + "'"; - int count = int.Parse(OracleUtils.ExecuteScalar(OracleUtils.ConnectionString, CommandType.Text, sql).ToString()); + + // 验证密码的复杂度——大小写字母+数字+特殊字符,长度不低于8位 + bool regMatch = Regex.IsMatch(txt_pwd_new.Text.Trim(), "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$"); + if (regMatch == false) + { + MessageBox.Show("请确保密码强度:至少包含字母、数字和特殊字符,不少于8位!"); + return; + } + string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME=:username and PASSWORD=:passwordOld"; + + OracleParameter usernameParam = new OracleParameter(":username", Utility.userName); + OracleParameter passwordOldParam = new OracleParameter(":passwordOld", SM4Utils.SM4EncryptStr(txt_pwd_old.Text.Trim())); + + int count = int.Parse(OledbHelper.ExecuteScalar(sql, usernameParam, passwordOldParam).ToString()); if (count <= 0) { MessageBox.Show("密码错误!"); return; } - sql = "update casic_userinfotest set password='" + Utility.MD5Encrypt2(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; - OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); - MessageBox.Show("修改成功!"); + sql = "update casic_userinfotest set password='" + SM4Utils.SM4EncryptStr(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; + int rowCount = OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); + if (rowCount == 1) + { + MessageBox.Show("修改成功!请退出系统后重新登录"); + } else + { + MessageBox.Show("修改失败"); + } } catch (Exception ex) { MessageBox.Show("修改失败:" + ex); + this.Hide(); } + this.Hide(); + } private void FrmChangePassword_Load(object sender, EventArgs e) diff --git a/FrmChangePassword.resx b/FrmChangePassword.resx index 1af7de1..7eadc96 100644 --- a/FrmChangePassword.resx +++ b/FrmChangePassword.resx @@ -117,4 +117,25 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + 112, 17 + + + 207, 17 + + + 302, 17 + + + 425, 17 + + + 553, 17 + + + 679, 17 + \ No newline at end of file diff --git a/FrmLogin.cs b/FrmLogin.cs index fee6a16..5251170 100644 --- a/FrmLogin.cs +++ b/FrmLogin.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using System.Xml; using DevComponents.DotNetBar; +using Cyberpipe.SM4; namespace Cyberpipe { @@ -56,10 +57,14 @@ /// private bool ValidateUser() { - string passWord = Utility.MD5Encrypt2(textBoxPassWord.Text.Trim()); - string sql = "select * from casic_userinfotest where USERNAME='" + txtUser.Text.Trim() + "' and PASSWORD='" + passWord + "' and sysname='GHFX' "; + string passWord = SM4Utils.SM4EncryptStr(textBoxPassWord.Text.Trim()); + string sql = "select * from casic_userinfotest where USERNAME=:username and PASSWORD=:password and sysname='GHFX'"; + + OracleParameter usernameParam = new OracleParameter(":username", txtUser.Text.Trim()); + OracleParameter passwordParam = new OracleParameter(":password", passWord); + + DataTable dt = OledbHelper.ExecuteDataTable(sql, usernameParam, passwordParam); - DataTable dt = OledbHelper.QueryTable(sql); if (dt == null || dt.Rows.Count <= 0) return false; if (String.IsNullOrEmpty(dt.Rows[0]["rid"].ToString())) return true; sql = "select gid from casic_userroletest where id=" + dt.Rows[0]["rid"] + " and sysname='GHFX' "; diff --git a/OracleHelper.cs b/OracleHelper.cs index 52f4248..475347d 100644 --- a/OracleHelper.cs +++ b/OracleHelper.cs @@ -182,6 +182,39 @@ return num; } + public static int ExecuteScalar(string sql, params OracleParameter[] ops) + { + string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer + + ")(PORT=1521))(CONNECT_DATA=(SID=" + Utility.dbdatabase + + ")));Persist Security Info=True;User Id=" + Utility.userID + + "; Password=" + Utility.DBPassword + ""; + conn = new OracleConnection(connectString); + oracleCmd = conn.CreateCommand(); + oracleCmd.CommandText = sql; + int num = 0; + try + { + conn.Open(); + foreach (OracleParameter op in ops) + { + oracleCmd.Parameters.Add(op); + } + num = Convert.ToInt32(oracleCmd.ExecuteScalar().ToString()); + } + catch (Exception ex) + { + num = -1; + } + finally + { + if (conn.State == ConnectionState.Open) + { + conn.Close(); + } + } + return num; + } + public static DataSet getDataSet(string SQLstr, string tableName) { string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer diff --git a/SM4/DesTools.cs b/SM4/DesTools.cs new file mode 100644 index 0000000..4f0ac27 --- /dev/null +++ b/SM4/DesTools.cs @@ -0,0 +1,121 @@ +using System; +using System.Reflection; +using System.Security.Cryptography; +using System.Text; + +namespace Cyberpipe.SM4 +{ + public class DesTools + { + #region 3des加密 + + /// + /// 3des ecb模式加密() + /// + /// 待加密的字符串 + /// 密钥 + /// 加密矢量:只有在CBC解密模式下才适用 + /// 运算模式 + /// 加密后的字符串 + public static string Encrypt3Des(string aStrString, string aStrKey) + { + byte[] str = strToHexByte(aStrString); + byte[] key = strToHexByte(aStrKey + aStrKey.Substring(0, 16)); + + TripleDESCryptoServiceProvider tdsc = new TripleDESCryptoServiceProvider(); + tdsc.Padding = PaddingMode.None; + + byte[] IV = { 0xB0, 0xA2, 0xB8, 0xA3, 0xDA, 0xCC, 0xDA, 0xCC }; + //指定密匙长度,默认为192位 + tdsc.KeySize = 128; + //使用指定的key和IV(加密向量) + Type t = Type.GetType("System.Security.Cryptography.CryptoAPITransformMode"); + object obj = t.GetField("Encrypt", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).GetValue(t); + MethodInfo mi = tdsc.GetType().GetMethod("_NewEncryptor", BindingFlags.Instance | BindingFlags.NonPublic); + ICryptoTransform desCrypt = (ICryptoTransform)mi.Invoke(tdsc, new object[] { key, CipherMode.ECB, null, 0, obj }); + tdsc.IV = IV; + //加密模式,偏移 + tdsc.Mode = CipherMode.ECB; + + //进行加密转换运算 + //ICryptoTransform ct = tdsc.CreateDecryptor(); + //8很关键,加密结果是8字节数组 + byte[] results = desCrypt.TransformFinalBlock(str, 0, str.Length); + + return byteToHexStr(results).ToUpper(); ; + + } + + #endregion + + + public static String generalStringToAscii(int length) + { + + int num = 1; + for (int i = 0; i < length; i++) + { + num *= 10; + } + + Random rand = new Random(); + String strRandom = (rand.Next(num).ToString()).PadLeft(length, '0'); + + StringBuilder sb = new StringBuilder(); + byte[] bytes = Encoding.ASCII.GetBytes(strRandom); + for (int i = 0; i < bytes.Length; i++) + { + sb.Append((int)bytes[i]); + } + + return sb.ToString(); + } + + public static String padding80(String data) + { + + int padlen = 8 - (data.Length / 2) % 8; + String padstr = ""; + for (int i = 0; i < padlen - 1; i++) + { + padstr += "00"; + } + data = data + "80" + padstr; + return data; + } + + /// + /// 字符串转16进制字节数组 + /// + /// + /// + public static byte[] strToHexByte(string hexString) + { + hexString = hexString.Replace(" ", ""); + if ((hexString.Length % 2) != 0) + hexString += "0"; + byte[] returnBytes = new byte[hexString.Length / 2]; + for (int i = 0; i < returnBytes.Length; i++) + returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + return returnBytes; + } + + /// + /// 字节数组转16进制字符串 + /// + /// + /// + public static string byteToHexStr(byte[] bytes) + { + string returnStr = ""; + if (bytes != null) + { + for (int i = 0; i < bytes.Length; i++) + { + returnStr += bytes[i].ToString("x2"); + } + } + return returnStr; + } + } +} diff --git a/SM4/SM4.cs b/SM4/SM4.cs new file mode 100644 index 0000000..6f19a84 --- /dev/null +++ b/SM4/SM4.cs @@ -0,0 +1,317 @@ +using System; +using System.Collections.Generic; + +namespace Cyberpipe.SM4 +{ + class SM4 + { + public const int SM4_ENCRYPT = 1; + public const int SM4_DECRYPT = 0; + + private long GET_ULONG_BE(byte[] b, int i) + { + long n = (long)(b[i] & 0xff) << 24 | (long)((b[i + 1] & 0xff) << 16) | (long)((b[i + 2] & 0xff) << 8) | (long)(b[i + 3] & 0xff) & 0xffffffffL; + return n; + } + + private void PUT_ULONG_BE(long n, byte[] b, int i) + { + b[i] = (byte)(int)(0xFF & n >> 24); + b[i + 1] = (byte)(int)(0xFF & n >> 16); + b[i + 2] = (byte)(int)(0xFF & n >> 8); + b[i + 3] = (byte)(int)(0xFF & n); + } + + private long SHL(long x, int n) + { + return (x & 0xFFFFFFFF) << n; + } + + private long ROTL(long x, int n) + { + return SHL(x, n) | x >> (32 - n); + } + + private void SWAP(long[] sk, int i) + { + long t = sk[i]; + sk[i] = sk[(31 - i)]; + sk[(31 - i)] = t; + } + + public byte[] SboxTable = new byte[] { (byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe, + (byte) 0xcc, (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6, + 0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b, 0x67, + (byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3, + (byte) 0xaa, 0x44, 0x13, 0x26, 0x49, (byte) 0x86, 0x06, + (byte) 0x99, (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91, + (byte) 0xef, (byte) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, + (byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62, (byte) 0xe4, + (byte) 0xb3, 0x1c, (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8, + (byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94, (byte) 0xfa, + 0x75, (byte) 0x8f, 0x3f, (byte) 0xa6, 0x47, 0x07, (byte) 0xa7, + (byte) 0xfc, (byte) 0xf3, 0x73, 0x17, (byte) 0xba, (byte) 0x83, + 0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8, + 0x68, 0x6b, (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda, + (byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70, 0x56, + (byte) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1, + (byte) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (byte) 0x87, + (byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27, + 0x52, 0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4, + (byte) 0xc8, (byte) 0x9e, (byte) 0xea, (byte) 0xbf, (byte) 0x8a, + (byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3, + (byte) 0xf7, (byte) 0xf2, (byte) 0xce, (byte) 0xf9, 0x61, 0x15, + (byte) 0xa1, (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4, + (byte) 0x9b, 0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32, + 0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3, 0x1d, + (byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca, + 0x60, (byte) 0xc0, 0x29, 0x23, (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f, + (byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd, + (byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, + 0x51, (byte) 0x8d, 0x1b, (byte) 0xaf, (byte) 0x92, (byte) 0xbb, + (byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41, + 0x1f, 0x10, 0x5a, (byte) 0xd8, 0x0a, (byte) 0xc1, 0x31, + (byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d, + 0x74, (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4, + (byte) 0xb0, (byte) 0x89, 0x69, (byte) 0x97, 0x4a, 0x0c, + (byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09, + (byte) 0xc5, 0x6e, (byte) 0xc6, (byte) 0x84, 0x18, (byte) 0xf0, + 0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79, + (byte) 0xee, 0x5f, 0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48 }; + + public uint[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc }; + + public uint[] CK = { 0x00070e15,0x1c232a31,0x383f464d,0x545b6269, + 0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9, + 0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249, + 0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9, + 0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229, + 0x30373e45,0x4c535a61,0x686f767d,0x848b9299, + 0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209, + 0x10171e25,0x2c333a41,0x484f565d,0x646b7279 }; + + private byte sm4Sbox(byte inch) + { + int i = inch & 0xFF; + byte retVal = SboxTable[i]; + return retVal; + } + + private long sm4Lt(long ka) + { + long bb = 0L; + long c = 0L; + byte[] a = new byte[4]; + byte[] b = new byte[4]; + PUT_ULONG_BE(ka, a, 0); + b[0] = sm4Sbox(a[0]); + b[1] = sm4Sbox(a[1]); + b[2] = sm4Sbox(a[2]); + b[3] = sm4Sbox(a[3]); + bb = GET_ULONG_BE(b, 0); + c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24); + return c; + } + + private long sm4F(long x0, long x1, long x2, long x3, long rk) + { + return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk); + } + + private long sm4CalciRK(long ka) + { + long bb = 0L; + long rk = 0L; + byte[] a = new byte[4]; + byte[] b = new byte[4]; + PUT_ULONG_BE(ka, a, 0); + b[0] = sm4Sbox(a[0]); + b[1] = sm4Sbox(a[1]); + b[2] = sm4Sbox(a[2]); + b[3] = sm4Sbox(a[3]); + bb = GET_ULONG_BE(b, 0); + rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23); + return rk; + } + + private void sm4_setkey(long[] SK, byte[] key) + { + long[] MK = new long[4]; + long[] k = new long[36]; + int i = 0; + MK[0] = GET_ULONG_BE(key, 0); + MK[1] = GET_ULONG_BE(key, 4); + MK[2] = GET_ULONG_BE(key, 8); + MK[3] = GET_ULONG_BE(key, 12); + k[0] = MK[0] ^ (long)FK[0]; + k[1] = MK[1] ^ (long)FK[1]; + k[2] = MK[2] ^ (long)FK[2]; + k[3] = MK[3] ^ (long)FK[3]; + for (; i < 32; i++) + { + k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long)CK[i])); + SK[i] = k[(i + 4)]; + } + } + + private void sm4_one_round(long[] sk, byte[] input, byte[] output) + { + int i = 0; + long[] ulbuf = new long[36]; + ulbuf[0] = GET_ULONG_BE(input, 0); + ulbuf[1] = GET_ULONG_BE(input, 4); + ulbuf[2] = GET_ULONG_BE(input, 8); + ulbuf[3] = GET_ULONG_BE(input, 12); + while (i < 32) + { + ulbuf[(i + 4)] = sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]); + i++; + } + PUT_ULONG_BE(ulbuf[35], output, 0); + PUT_ULONG_BE(ulbuf[34], output, 4); + PUT_ULONG_BE(ulbuf[33], output, 8); + PUT_ULONG_BE(ulbuf[32], output, 12); + } + + private byte[] padding(byte[] input, int mode) + { + if (input == null) + { + return null; + } + + byte[] ret = (byte[])null; + if (mode == SM4_ENCRYPT) + { + int p = (input.Length % 16 == 0) ? 0 : (16 - input.Length % 16); + ret = new byte[input.Length + p]; + Array.Copy(input, 0, ret, 0, input.Length); + for (int i = 0; i < p; i++) + { + ret[input.Length + i] = 0x00; + } + } + else + { + int p = input[input.Length - 1]; + ret = new byte[input.Length - p]; + Array.Copy(input, 0, ret, 0, input.Length - p); + } + return ret; + } + + public void sm4_setkey_enc(SM4_Context ctx, byte[] key) + { + ctx.mode = SM4_ENCRYPT; + sm4_setkey(ctx.sk, key); + } + + public void sm4_setkey_dec(SM4_Context ctx, byte[] key) + { + int i = 0; + ctx.mode = SM4_DECRYPT; + sm4_setkey(ctx.sk, key); + for (i = 0; i < 16; i++) + { + SWAP(ctx.sk, i); + } + } + + public byte[] sm4_crypt_ecb(SM4_Context ctx, byte[] input) + { + if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT)) + { + input = padding(input, SM4_ENCRYPT); + } + + int length = input.Length; + byte[] bins = new byte[length]; + Array.Copy(input, 0, bins, 0, length); + byte[] bous = new byte[length]; + for (int i = 0; length > 0; length -= 16, i++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + sm4_one_round(ctx.sk, inBytes, outBytes); + Array.Copy(outBytes, 0, bous, i * 16, length > 16 ? 16 : length); + } + + //if (ctx.isPadding && ctx.mode == SM4_DECRYPT) + //{ + // bous = padding(bous, SM4_DECRYPT); + //} + return bous; + } + + public byte[] sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input) + { + if (ctx.isPadding && ctx.mode == SM4_ENCRYPT) + { + input = padding(input, SM4_ENCRYPT); + } + + int i = 0; + int length = input.Length; + byte[] bins = new byte[length]; + Array.Copy(input, 0, bins, 0, length); + byte[] bous = null; + List bousList = new List(); + if (ctx.mode == SM4_ENCRYPT) + { + for (int j = 0; length > 0; length -= 16, j++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + byte[] out1 = new byte[16]; + + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + for (i = 0; i < 16; i++) + { + outBytes[i] = ((byte)(inBytes[i] ^ iv[i])); + } + sm4_one_round(ctx.sk, outBytes, out1); + Array.Copy(out1, 0, iv, 0, 16); + for (int k = 0; k < 16; k++) + { + bousList.Add(out1[k]); + } + } + } + else + { + byte[] temp = new byte[16]; + for (int j = 0; length > 0; length -= 16, j++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + byte[] out1 = new byte[16]; + + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + Array.Copy(inBytes, 0, temp, 0, 16); + sm4_one_round(ctx.sk, inBytes, outBytes); + for (i = 0; i < 16; i++) + { + out1[i] = ((byte)(outBytes[i] ^ iv[i])); + } + Array.Copy(temp, 0, iv, 0, 16); + for (int k = 0; k < 16; k++) + { + bousList.Add(out1[k]); + } + } + + } + + if (ctx.isPadding && ctx.mode == SM4_DECRYPT) + { + bous = padding(bousList.ToArray(), SM4_DECRYPT); + return bous; + } + else + { + return bousList.ToArray(); + } + } + } +} diff --git a/SM4/SM4Utils.cs b/SM4/SM4Utils.cs new file mode 100644 index 0000000..ef19172 --- /dev/null +++ b/SM4/SM4Utils.cs @@ -0,0 +1,44 @@ +using Org.BouncyCastle.Utilities.Encoders; +using System; + +namespace Cyberpipe.SM4 +{ + public class SM4Utils + { + private static string secretKey = "45f3fabdf725985ba451b9640ea46ea7"; + public static byte[] SM4Encrypt(byte[] plainBytes) + { + SM4_Context ctx = new SM4_Context(); + ctx.isPadding = true; + ctx.mode = SM4.SM4_ENCRYPT; + + byte[] keyBytes = Hex.Decode(secretKey); + + SM4 sm4 = new SM4(); + sm4.sm4_setkey_enc(ctx, keyBytes); + byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainBytes); + + return encrypted; + } + + public static string SM4EncryptStr(string asciiStr) + { + byte[] encrypted = SM4Utils.SM4Encrypt(System.Text.Encoding.ASCII.GetBytes(asciiStr)); + return Hex.ToHexString(encrypted); + } + + public static string SM4Decrypt(byte[] cipherBytes) + { + SM4_Context ctx = new SM4_Context(); + ctx.isPadding = true; + ctx.mode = SM4.SM4_DECRYPT; + + byte[] keyBytes = Hex.Decode(secretKey); + + SM4 sm4 = new SM4(); + sm4.sm4_setkey_dec(ctx, keyBytes); + byte[] decrypted = sm4.sm4_crypt_ecb(ctx, cipherBytes); + return Hex.ToHexString(decrypted); + } + } +} diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/FrmChangePassword.Designer.cs b/FrmChangePassword.Designer.cs index 7e83f42..aa98573 100644 --- a/FrmChangePassword.Designer.cs +++ b/FrmChangePassword.Designer.cs @@ -51,7 +51,7 @@ this.labelX1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX1.Location = new System.Drawing.Point(23, 13); this.labelX1.Name = "labelX1"; - this.labelX1.Size = new System.Drawing.Size(50, 16); + this.labelX1.Size = new System.Drawing.Size(56, 18); this.labelX1.TabIndex = 0; this.labelX1.Text = "原始密码"; // @@ -65,7 +65,7 @@ this.labelX2.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX2.Location = new System.Drawing.Point(23, 49); this.labelX2.Name = "labelX2"; - this.labelX2.Size = new System.Drawing.Size(50, 16); + this.labelX2.Size = new System.Drawing.Size(56, 18); this.labelX2.TabIndex = 0; this.labelX2.Text = "最新密码"; // @@ -79,7 +79,7 @@ this.labelX3.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX3.Location = new System.Drawing.Point(23, 85); this.labelX3.Name = "labelX3"; - this.labelX3.Size = new System.Drawing.Size(50, 16); + this.labelX3.Size = new System.Drawing.Size(56, 18); this.labelX3.TabIndex = 0; this.labelX3.Text = "密码确认"; // @@ -107,7 +107,7 @@ this.txt_pwd_new.Name = "txt_pwd_new"; this.txt_pwd_new.PasswordChar = '*'; this.txt_pwd_new.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_new.TabIndex = 1; + this.txt_pwd_new.TabIndex = 2; // // txt_pwd_cfm // @@ -120,7 +120,7 @@ this.txt_pwd_cfm.Name = "txt_pwd_cfm"; this.txt_pwd_cfm.PasswordChar = '*'; this.txt_pwd_cfm.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_cfm.TabIndex = 1; + this.txt_pwd_cfm.TabIndex = 3; // // btn_ok // @@ -130,7 +130,7 @@ this.btn_ok.Name = "btn_ok"; this.btn_ok.Size = new System.Drawing.Size(75, 23); this.btn_ok.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btn_ok.TabIndex = 2; + this.btn_ok.TabIndex = 4; this.btn_ok.Text = "确定"; this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); // diff --git a/FrmChangePassword.cs b/FrmChangePassword.cs index a78b93f..9e22417 100644 --- a/FrmChangePassword.cs +++ b/FrmChangePassword.cs @@ -1,6 +1,9 @@ using System; using System.Data; +using System.Data.OracleClient; +using System.Text.RegularExpressions; using System.Windows.Forms; +using Cyberpipe.SM4; using DevComponents.DotNetBar; namespace Cyberpipe @@ -28,22 +31,43 @@ MessageBox.Show("请确认要修改的密码!"); return; } - string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME='" + Utility.userName + "' and PASSWORD='" + Utility.MD5Encrypt2(txt_pwd_old.Text.Trim()) + "'"; - int count = int.Parse(OracleUtils.ExecuteScalar(OracleUtils.ConnectionString, CommandType.Text, sql).ToString()); + + // 验证密码的复杂度——大小写字母+数字+特殊字符,长度不低于8位 + bool regMatch = Regex.IsMatch(txt_pwd_new.Text.Trim(), "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$"); + if (regMatch == false) + { + MessageBox.Show("请确保密码强度:至少包含字母、数字和特殊字符,不少于8位!"); + return; + } + string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME=:username and PASSWORD=:passwordOld"; + + OracleParameter usernameParam = new OracleParameter(":username", Utility.userName); + OracleParameter passwordOldParam = new OracleParameter(":passwordOld", SM4Utils.SM4EncryptStr(txt_pwd_old.Text.Trim())); + + int count = int.Parse(OledbHelper.ExecuteScalar(sql, usernameParam, passwordOldParam).ToString()); if (count <= 0) { MessageBox.Show("密码错误!"); return; } - sql = "update casic_userinfotest set password='" + Utility.MD5Encrypt2(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; - OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); - MessageBox.Show("修改成功!"); + sql = "update casic_userinfotest set password='" + SM4Utils.SM4EncryptStr(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; + int rowCount = OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); + if (rowCount == 1) + { + MessageBox.Show("修改成功!请退出系统后重新登录"); + } else + { + MessageBox.Show("修改失败"); + } } catch (Exception ex) { MessageBox.Show("修改失败:" + ex); + this.Hide(); } + this.Hide(); + } private void FrmChangePassword_Load(object sender, EventArgs e) diff --git a/FrmChangePassword.resx b/FrmChangePassword.resx index 1af7de1..7eadc96 100644 --- a/FrmChangePassword.resx +++ b/FrmChangePassword.resx @@ -117,4 +117,25 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + 112, 17 + + + 207, 17 + + + 302, 17 + + + 425, 17 + + + 553, 17 + + + 679, 17 + \ No newline at end of file diff --git a/FrmLogin.cs b/FrmLogin.cs index fee6a16..5251170 100644 --- a/FrmLogin.cs +++ b/FrmLogin.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using System.Xml; using DevComponents.DotNetBar; +using Cyberpipe.SM4; namespace Cyberpipe { @@ -56,10 +57,14 @@ /// private bool ValidateUser() { - string passWord = Utility.MD5Encrypt2(textBoxPassWord.Text.Trim()); - string sql = "select * from casic_userinfotest where USERNAME='" + txtUser.Text.Trim() + "' and PASSWORD='" + passWord + "' and sysname='GHFX' "; + string passWord = SM4Utils.SM4EncryptStr(textBoxPassWord.Text.Trim()); + string sql = "select * from casic_userinfotest where USERNAME=:username and PASSWORD=:password and sysname='GHFX'"; + + OracleParameter usernameParam = new OracleParameter(":username", txtUser.Text.Trim()); + OracleParameter passwordParam = new OracleParameter(":password", passWord); + + DataTable dt = OledbHelper.ExecuteDataTable(sql, usernameParam, passwordParam); - DataTable dt = OledbHelper.QueryTable(sql); if (dt == null || dt.Rows.Count <= 0) return false; if (String.IsNullOrEmpty(dt.Rows[0]["rid"].ToString())) return true; sql = "select gid from casic_userroletest where id=" + dt.Rows[0]["rid"] + " and sysname='GHFX' "; diff --git a/OracleHelper.cs b/OracleHelper.cs index 52f4248..475347d 100644 --- a/OracleHelper.cs +++ b/OracleHelper.cs @@ -182,6 +182,39 @@ return num; } + public static int ExecuteScalar(string sql, params OracleParameter[] ops) + { + string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer + + ")(PORT=1521))(CONNECT_DATA=(SID=" + Utility.dbdatabase + + ")));Persist Security Info=True;User Id=" + Utility.userID + + "; Password=" + Utility.DBPassword + ""; + conn = new OracleConnection(connectString); + oracleCmd = conn.CreateCommand(); + oracleCmd.CommandText = sql; + int num = 0; + try + { + conn.Open(); + foreach (OracleParameter op in ops) + { + oracleCmd.Parameters.Add(op); + } + num = Convert.ToInt32(oracleCmd.ExecuteScalar().ToString()); + } + catch (Exception ex) + { + num = -1; + } + finally + { + if (conn.State == ConnectionState.Open) + { + conn.Close(); + } + } + return num; + } + public static DataSet getDataSet(string SQLstr, string tableName) { string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer diff --git a/SM4/DesTools.cs b/SM4/DesTools.cs new file mode 100644 index 0000000..4f0ac27 --- /dev/null +++ b/SM4/DesTools.cs @@ -0,0 +1,121 @@ +using System; +using System.Reflection; +using System.Security.Cryptography; +using System.Text; + +namespace Cyberpipe.SM4 +{ + public class DesTools + { + #region 3des加密 + + /// + /// 3des ecb模式加密() + /// + /// 待加密的字符串 + /// 密钥 + /// 加密矢量:只有在CBC解密模式下才适用 + /// 运算模式 + /// 加密后的字符串 + public static string Encrypt3Des(string aStrString, string aStrKey) + { + byte[] str = strToHexByte(aStrString); + byte[] key = strToHexByte(aStrKey + aStrKey.Substring(0, 16)); + + TripleDESCryptoServiceProvider tdsc = new TripleDESCryptoServiceProvider(); + tdsc.Padding = PaddingMode.None; + + byte[] IV = { 0xB0, 0xA2, 0xB8, 0xA3, 0xDA, 0xCC, 0xDA, 0xCC }; + //指定密匙长度,默认为192位 + tdsc.KeySize = 128; + //使用指定的key和IV(加密向量) + Type t = Type.GetType("System.Security.Cryptography.CryptoAPITransformMode"); + object obj = t.GetField("Encrypt", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).GetValue(t); + MethodInfo mi = tdsc.GetType().GetMethod("_NewEncryptor", BindingFlags.Instance | BindingFlags.NonPublic); + ICryptoTransform desCrypt = (ICryptoTransform)mi.Invoke(tdsc, new object[] { key, CipherMode.ECB, null, 0, obj }); + tdsc.IV = IV; + //加密模式,偏移 + tdsc.Mode = CipherMode.ECB; + + //进行加密转换运算 + //ICryptoTransform ct = tdsc.CreateDecryptor(); + //8很关键,加密结果是8字节数组 + byte[] results = desCrypt.TransformFinalBlock(str, 0, str.Length); + + return byteToHexStr(results).ToUpper(); ; + + } + + #endregion + + + public static String generalStringToAscii(int length) + { + + int num = 1; + for (int i = 0; i < length; i++) + { + num *= 10; + } + + Random rand = new Random(); + String strRandom = (rand.Next(num).ToString()).PadLeft(length, '0'); + + StringBuilder sb = new StringBuilder(); + byte[] bytes = Encoding.ASCII.GetBytes(strRandom); + for (int i = 0; i < bytes.Length; i++) + { + sb.Append((int)bytes[i]); + } + + return sb.ToString(); + } + + public static String padding80(String data) + { + + int padlen = 8 - (data.Length / 2) % 8; + String padstr = ""; + for (int i = 0; i < padlen - 1; i++) + { + padstr += "00"; + } + data = data + "80" + padstr; + return data; + } + + /// + /// 字符串转16进制字节数组 + /// + /// + /// + public static byte[] strToHexByte(string hexString) + { + hexString = hexString.Replace(" ", ""); + if ((hexString.Length % 2) != 0) + hexString += "0"; + byte[] returnBytes = new byte[hexString.Length / 2]; + for (int i = 0; i < returnBytes.Length; i++) + returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + return returnBytes; + } + + /// + /// 字节数组转16进制字符串 + /// + /// + /// + public static string byteToHexStr(byte[] bytes) + { + string returnStr = ""; + if (bytes != null) + { + for (int i = 0; i < bytes.Length; i++) + { + returnStr += bytes[i].ToString("x2"); + } + } + return returnStr; + } + } +} diff --git a/SM4/SM4.cs b/SM4/SM4.cs new file mode 100644 index 0000000..6f19a84 --- /dev/null +++ b/SM4/SM4.cs @@ -0,0 +1,317 @@ +using System; +using System.Collections.Generic; + +namespace Cyberpipe.SM4 +{ + class SM4 + { + public const int SM4_ENCRYPT = 1; + public const int SM4_DECRYPT = 0; + + private long GET_ULONG_BE(byte[] b, int i) + { + long n = (long)(b[i] & 0xff) << 24 | (long)((b[i + 1] & 0xff) << 16) | (long)((b[i + 2] & 0xff) << 8) | (long)(b[i + 3] & 0xff) & 0xffffffffL; + return n; + } + + private void PUT_ULONG_BE(long n, byte[] b, int i) + { + b[i] = (byte)(int)(0xFF & n >> 24); + b[i + 1] = (byte)(int)(0xFF & n >> 16); + b[i + 2] = (byte)(int)(0xFF & n >> 8); + b[i + 3] = (byte)(int)(0xFF & n); + } + + private long SHL(long x, int n) + { + return (x & 0xFFFFFFFF) << n; + } + + private long ROTL(long x, int n) + { + return SHL(x, n) | x >> (32 - n); + } + + private void SWAP(long[] sk, int i) + { + long t = sk[i]; + sk[i] = sk[(31 - i)]; + sk[(31 - i)] = t; + } + + public byte[] SboxTable = new byte[] { (byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe, + (byte) 0xcc, (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6, + 0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b, 0x67, + (byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3, + (byte) 0xaa, 0x44, 0x13, 0x26, 0x49, (byte) 0x86, 0x06, + (byte) 0x99, (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91, + (byte) 0xef, (byte) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, + (byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62, (byte) 0xe4, + (byte) 0xb3, 0x1c, (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8, + (byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94, (byte) 0xfa, + 0x75, (byte) 0x8f, 0x3f, (byte) 0xa6, 0x47, 0x07, (byte) 0xa7, + (byte) 0xfc, (byte) 0xf3, 0x73, 0x17, (byte) 0xba, (byte) 0x83, + 0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8, + 0x68, 0x6b, (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda, + (byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70, 0x56, + (byte) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1, + (byte) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (byte) 0x87, + (byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27, + 0x52, 0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4, + (byte) 0xc8, (byte) 0x9e, (byte) 0xea, (byte) 0xbf, (byte) 0x8a, + (byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3, + (byte) 0xf7, (byte) 0xf2, (byte) 0xce, (byte) 0xf9, 0x61, 0x15, + (byte) 0xa1, (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4, + (byte) 0x9b, 0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32, + 0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3, 0x1d, + (byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca, + 0x60, (byte) 0xc0, 0x29, 0x23, (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f, + (byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd, + (byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, + 0x51, (byte) 0x8d, 0x1b, (byte) 0xaf, (byte) 0x92, (byte) 0xbb, + (byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41, + 0x1f, 0x10, 0x5a, (byte) 0xd8, 0x0a, (byte) 0xc1, 0x31, + (byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d, + 0x74, (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4, + (byte) 0xb0, (byte) 0x89, 0x69, (byte) 0x97, 0x4a, 0x0c, + (byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09, + (byte) 0xc5, 0x6e, (byte) 0xc6, (byte) 0x84, 0x18, (byte) 0xf0, + 0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79, + (byte) 0xee, 0x5f, 0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48 }; + + public uint[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc }; + + public uint[] CK = { 0x00070e15,0x1c232a31,0x383f464d,0x545b6269, + 0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9, + 0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249, + 0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9, + 0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229, + 0x30373e45,0x4c535a61,0x686f767d,0x848b9299, + 0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209, + 0x10171e25,0x2c333a41,0x484f565d,0x646b7279 }; + + private byte sm4Sbox(byte inch) + { + int i = inch & 0xFF; + byte retVal = SboxTable[i]; + return retVal; + } + + private long sm4Lt(long ka) + { + long bb = 0L; + long c = 0L; + byte[] a = new byte[4]; + byte[] b = new byte[4]; + PUT_ULONG_BE(ka, a, 0); + b[0] = sm4Sbox(a[0]); + b[1] = sm4Sbox(a[1]); + b[2] = sm4Sbox(a[2]); + b[3] = sm4Sbox(a[3]); + bb = GET_ULONG_BE(b, 0); + c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24); + return c; + } + + private long sm4F(long x0, long x1, long x2, long x3, long rk) + { + return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk); + } + + private long sm4CalciRK(long ka) + { + long bb = 0L; + long rk = 0L; + byte[] a = new byte[4]; + byte[] b = new byte[4]; + PUT_ULONG_BE(ka, a, 0); + b[0] = sm4Sbox(a[0]); + b[1] = sm4Sbox(a[1]); + b[2] = sm4Sbox(a[2]); + b[3] = sm4Sbox(a[3]); + bb = GET_ULONG_BE(b, 0); + rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23); + return rk; + } + + private void sm4_setkey(long[] SK, byte[] key) + { + long[] MK = new long[4]; + long[] k = new long[36]; + int i = 0; + MK[0] = GET_ULONG_BE(key, 0); + MK[1] = GET_ULONG_BE(key, 4); + MK[2] = GET_ULONG_BE(key, 8); + MK[3] = GET_ULONG_BE(key, 12); + k[0] = MK[0] ^ (long)FK[0]; + k[1] = MK[1] ^ (long)FK[1]; + k[2] = MK[2] ^ (long)FK[2]; + k[3] = MK[3] ^ (long)FK[3]; + for (; i < 32; i++) + { + k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long)CK[i])); + SK[i] = k[(i + 4)]; + } + } + + private void sm4_one_round(long[] sk, byte[] input, byte[] output) + { + int i = 0; + long[] ulbuf = new long[36]; + ulbuf[0] = GET_ULONG_BE(input, 0); + ulbuf[1] = GET_ULONG_BE(input, 4); + ulbuf[2] = GET_ULONG_BE(input, 8); + ulbuf[3] = GET_ULONG_BE(input, 12); + while (i < 32) + { + ulbuf[(i + 4)] = sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]); + i++; + } + PUT_ULONG_BE(ulbuf[35], output, 0); + PUT_ULONG_BE(ulbuf[34], output, 4); + PUT_ULONG_BE(ulbuf[33], output, 8); + PUT_ULONG_BE(ulbuf[32], output, 12); + } + + private byte[] padding(byte[] input, int mode) + { + if (input == null) + { + return null; + } + + byte[] ret = (byte[])null; + if (mode == SM4_ENCRYPT) + { + int p = (input.Length % 16 == 0) ? 0 : (16 - input.Length % 16); + ret = new byte[input.Length + p]; + Array.Copy(input, 0, ret, 0, input.Length); + for (int i = 0; i < p; i++) + { + ret[input.Length + i] = 0x00; + } + } + else + { + int p = input[input.Length - 1]; + ret = new byte[input.Length - p]; + Array.Copy(input, 0, ret, 0, input.Length - p); + } + return ret; + } + + public void sm4_setkey_enc(SM4_Context ctx, byte[] key) + { + ctx.mode = SM4_ENCRYPT; + sm4_setkey(ctx.sk, key); + } + + public void sm4_setkey_dec(SM4_Context ctx, byte[] key) + { + int i = 0; + ctx.mode = SM4_DECRYPT; + sm4_setkey(ctx.sk, key); + for (i = 0; i < 16; i++) + { + SWAP(ctx.sk, i); + } + } + + public byte[] sm4_crypt_ecb(SM4_Context ctx, byte[] input) + { + if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT)) + { + input = padding(input, SM4_ENCRYPT); + } + + int length = input.Length; + byte[] bins = new byte[length]; + Array.Copy(input, 0, bins, 0, length); + byte[] bous = new byte[length]; + for (int i = 0; length > 0; length -= 16, i++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + sm4_one_round(ctx.sk, inBytes, outBytes); + Array.Copy(outBytes, 0, bous, i * 16, length > 16 ? 16 : length); + } + + //if (ctx.isPadding && ctx.mode == SM4_DECRYPT) + //{ + // bous = padding(bous, SM4_DECRYPT); + //} + return bous; + } + + public byte[] sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input) + { + if (ctx.isPadding && ctx.mode == SM4_ENCRYPT) + { + input = padding(input, SM4_ENCRYPT); + } + + int i = 0; + int length = input.Length; + byte[] bins = new byte[length]; + Array.Copy(input, 0, bins, 0, length); + byte[] bous = null; + List bousList = new List(); + if (ctx.mode == SM4_ENCRYPT) + { + for (int j = 0; length > 0; length -= 16, j++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + byte[] out1 = new byte[16]; + + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + for (i = 0; i < 16; i++) + { + outBytes[i] = ((byte)(inBytes[i] ^ iv[i])); + } + sm4_one_round(ctx.sk, outBytes, out1); + Array.Copy(out1, 0, iv, 0, 16); + for (int k = 0; k < 16; k++) + { + bousList.Add(out1[k]); + } + } + } + else + { + byte[] temp = new byte[16]; + for (int j = 0; length > 0; length -= 16, j++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + byte[] out1 = new byte[16]; + + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + Array.Copy(inBytes, 0, temp, 0, 16); + sm4_one_round(ctx.sk, inBytes, outBytes); + for (i = 0; i < 16; i++) + { + out1[i] = ((byte)(outBytes[i] ^ iv[i])); + } + Array.Copy(temp, 0, iv, 0, 16); + for (int k = 0; k < 16; k++) + { + bousList.Add(out1[k]); + } + } + + } + + if (ctx.isPadding && ctx.mode == SM4_DECRYPT) + { + bous = padding(bousList.ToArray(), SM4_DECRYPT); + return bous; + } + else + { + return bousList.ToArray(); + } + } + } +} diff --git a/SM4/SM4Utils.cs b/SM4/SM4Utils.cs new file mode 100644 index 0000000..ef19172 --- /dev/null +++ b/SM4/SM4Utils.cs @@ -0,0 +1,44 @@ +using Org.BouncyCastle.Utilities.Encoders; +using System; + +namespace Cyberpipe.SM4 +{ + public class SM4Utils + { + private static string secretKey = "45f3fabdf725985ba451b9640ea46ea7"; + public static byte[] SM4Encrypt(byte[] plainBytes) + { + SM4_Context ctx = new SM4_Context(); + ctx.isPadding = true; + ctx.mode = SM4.SM4_ENCRYPT; + + byte[] keyBytes = Hex.Decode(secretKey); + + SM4 sm4 = new SM4(); + sm4.sm4_setkey_enc(ctx, keyBytes); + byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainBytes); + + return encrypted; + } + + public static string SM4EncryptStr(string asciiStr) + { + byte[] encrypted = SM4Utils.SM4Encrypt(System.Text.Encoding.ASCII.GetBytes(asciiStr)); + return Hex.ToHexString(encrypted); + } + + public static string SM4Decrypt(byte[] cipherBytes) + { + SM4_Context ctx = new SM4_Context(); + ctx.isPadding = true; + ctx.mode = SM4.SM4_DECRYPT; + + byte[] keyBytes = Hex.Decode(secretKey); + + SM4 sm4 = new SM4(); + sm4.sm4_setkey_dec(ctx, keyBytes); + byte[] decrypted = sm4.sm4_crypt_ecb(ctx, cipherBytes); + return Hex.ToHexString(decrypted); + } + } +} diff --git a/SM4/SM4_Context.cs b/SM4/SM4_Context.cs new file mode 100644 index 0000000..d82660c --- /dev/null +++ b/SM4/SM4_Context.cs @@ -0,0 +1,19 @@ + +namespace Cyberpipe.SM4 +{ + class SM4_Context + { + public int mode; + + public long[] sk; + + public bool isPadding; + + public SM4_Context() + { + this.mode = 1; + this.isPadding = true; + this.sk = new long[32]; + } + } +} diff --git a/Cyberpipe.csproj b/Cyberpipe.csproj index 6896ecd..60a6807 100644 --- a/Cyberpipe.csproj +++ b/Cyberpipe.csproj @@ -115,6 +115,10 @@ False bin\x86\Debug\Aspose.Cells.dll + + False + SM4\BouncyCastle.Crypto.dll + False bin\x86\Debug\DevComponents.DotNetBar2.dll @@ -1255,6 +1259,11 @@ + + + + + Form diff --git a/FrmChangePassword.Designer.cs b/FrmChangePassword.Designer.cs index 7e83f42..aa98573 100644 --- a/FrmChangePassword.Designer.cs +++ b/FrmChangePassword.Designer.cs @@ -51,7 +51,7 @@ this.labelX1.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX1.Location = new System.Drawing.Point(23, 13); this.labelX1.Name = "labelX1"; - this.labelX1.Size = new System.Drawing.Size(50, 16); + this.labelX1.Size = new System.Drawing.Size(56, 18); this.labelX1.TabIndex = 0; this.labelX1.Text = "原始密码"; // @@ -65,7 +65,7 @@ this.labelX2.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX2.Location = new System.Drawing.Point(23, 49); this.labelX2.Name = "labelX2"; - this.labelX2.Size = new System.Drawing.Size(50, 16); + this.labelX2.Size = new System.Drawing.Size(56, 18); this.labelX2.TabIndex = 0; this.labelX2.Text = "最新密码"; // @@ -79,7 +79,7 @@ this.labelX3.BackgroundStyle.CornerType = DevComponents.DotNetBar.eCornerType.Square; this.labelX3.Location = new System.Drawing.Point(23, 85); this.labelX3.Name = "labelX3"; - this.labelX3.Size = new System.Drawing.Size(50, 16); + this.labelX3.Size = new System.Drawing.Size(56, 18); this.labelX3.TabIndex = 0; this.labelX3.Text = "密码确认"; // @@ -107,7 +107,7 @@ this.txt_pwd_new.Name = "txt_pwd_new"; this.txt_pwd_new.PasswordChar = '*'; this.txt_pwd_new.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_new.TabIndex = 1; + this.txt_pwd_new.TabIndex = 2; // // txt_pwd_cfm // @@ -120,7 +120,7 @@ this.txt_pwd_cfm.Name = "txt_pwd_cfm"; this.txt_pwd_cfm.PasswordChar = '*'; this.txt_pwd_cfm.Size = new System.Drawing.Size(169, 21); - this.txt_pwd_cfm.TabIndex = 1; + this.txt_pwd_cfm.TabIndex = 3; // // btn_ok // @@ -130,7 +130,7 @@ this.btn_ok.Name = "btn_ok"; this.btn_ok.Size = new System.Drawing.Size(75, 23); this.btn_ok.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled; - this.btn_ok.TabIndex = 2; + this.btn_ok.TabIndex = 4; this.btn_ok.Text = "确定"; this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click); // diff --git a/FrmChangePassword.cs b/FrmChangePassword.cs index a78b93f..9e22417 100644 --- a/FrmChangePassword.cs +++ b/FrmChangePassword.cs @@ -1,6 +1,9 @@ using System; using System.Data; +using System.Data.OracleClient; +using System.Text.RegularExpressions; using System.Windows.Forms; +using Cyberpipe.SM4; using DevComponents.DotNetBar; namespace Cyberpipe @@ -28,22 +31,43 @@ MessageBox.Show("请确认要修改的密码!"); return; } - string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME='" + Utility.userName + "' and PASSWORD='" + Utility.MD5Encrypt2(txt_pwd_old.Text.Trim()) + "'"; - int count = int.Parse(OracleUtils.ExecuteScalar(OracleUtils.ConnectionString, CommandType.Text, sql).ToString()); + + // 验证密码的复杂度——大小写字母+数字+特殊字符,长度不低于8位 + bool regMatch = Regex.IsMatch(txt_pwd_new.Text.Trim(), "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$"); + if (regMatch == false) + { + MessageBox.Show("请确保密码强度:至少包含字母、数字和特殊字符,不少于8位!"); + return; + } + string sql = "select count(*) from casic_userinfotest where SYSNAME='GHFX' and USERNAME=:username and PASSWORD=:passwordOld"; + + OracleParameter usernameParam = new OracleParameter(":username", Utility.userName); + OracleParameter passwordOldParam = new OracleParameter(":passwordOld", SM4Utils.SM4EncryptStr(txt_pwd_old.Text.Trim())); + + int count = int.Parse(OledbHelper.ExecuteScalar(sql, usernameParam, passwordOldParam).ToString()); if (count <= 0) { MessageBox.Show("密码错误!"); return; } - sql = "update casic_userinfotest set password='" + Utility.MD5Encrypt2(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; - OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); - MessageBox.Show("修改成功!"); + sql = "update casic_userinfotest set password='" + SM4Utils.SM4EncryptStr(txt_pwd_new.Text.Trim()) + "' where sysname='GHFX' and username='" + Utility.userName + "'"; + int rowCount = OracleUtils.ExecuteNonQuery(OracleUtils.ConnectionString, CommandType.Text, sql); + if (rowCount == 1) + { + MessageBox.Show("修改成功!请退出系统后重新登录"); + } else + { + MessageBox.Show("修改失败"); + } } catch (Exception ex) { MessageBox.Show("修改失败:" + ex); + this.Hide(); } + this.Hide(); + } private void FrmChangePassword_Load(object sender, EventArgs e) diff --git a/FrmChangePassword.resx b/FrmChangePassword.resx index 1af7de1..7eadc96 100644 --- a/FrmChangePassword.resx +++ b/FrmChangePassword.resx @@ -117,4 +117,25 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + 112, 17 + + + 207, 17 + + + 302, 17 + + + 425, 17 + + + 553, 17 + + + 679, 17 + \ No newline at end of file diff --git a/FrmLogin.cs b/FrmLogin.cs index fee6a16..5251170 100644 --- a/FrmLogin.cs +++ b/FrmLogin.cs @@ -8,6 +8,7 @@ using System.Windows.Forms; using System.Xml; using DevComponents.DotNetBar; +using Cyberpipe.SM4; namespace Cyberpipe { @@ -56,10 +57,14 @@ /// private bool ValidateUser() { - string passWord = Utility.MD5Encrypt2(textBoxPassWord.Text.Trim()); - string sql = "select * from casic_userinfotest where USERNAME='" + txtUser.Text.Trim() + "' and PASSWORD='" + passWord + "' and sysname='GHFX' "; + string passWord = SM4Utils.SM4EncryptStr(textBoxPassWord.Text.Trim()); + string sql = "select * from casic_userinfotest where USERNAME=:username and PASSWORD=:password and sysname='GHFX'"; + + OracleParameter usernameParam = new OracleParameter(":username", txtUser.Text.Trim()); + OracleParameter passwordParam = new OracleParameter(":password", passWord); + + DataTable dt = OledbHelper.ExecuteDataTable(sql, usernameParam, passwordParam); - DataTable dt = OledbHelper.QueryTable(sql); if (dt == null || dt.Rows.Count <= 0) return false; if (String.IsNullOrEmpty(dt.Rows[0]["rid"].ToString())) return true; sql = "select gid from casic_userroletest where id=" + dt.Rows[0]["rid"] + " and sysname='GHFX' "; diff --git a/OracleHelper.cs b/OracleHelper.cs index 52f4248..475347d 100644 --- a/OracleHelper.cs +++ b/OracleHelper.cs @@ -182,6 +182,39 @@ return num; } + public static int ExecuteScalar(string sql, params OracleParameter[] ops) + { + string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer + + ")(PORT=1521))(CONNECT_DATA=(SID=" + Utility.dbdatabase + + ")));Persist Security Info=True;User Id=" + Utility.userID + + "; Password=" + Utility.DBPassword + ""; + conn = new OracleConnection(connectString); + oracleCmd = conn.CreateCommand(); + oracleCmd.CommandText = sql; + int num = 0; + try + { + conn.Open(); + foreach (OracleParameter op in ops) + { + oracleCmd.Parameters.Add(op); + } + num = Convert.ToInt32(oracleCmd.ExecuteScalar().ToString()); + } + catch (Exception ex) + { + num = -1; + } + finally + { + if (conn.State == ConnectionState.Open) + { + conn.Close(); + } + } + return num; + } + public static DataSet getDataSet(string SQLstr, string tableName) { string connectString = @"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + Utility.DBServer diff --git a/SM4/DesTools.cs b/SM4/DesTools.cs new file mode 100644 index 0000000..4f0ac27 --- /dev/null +++ b/SM4/DesTools.cs @@ -0,0 +1,121 @@ +using System; +using System.Reflection; +using System.Security.Cryptography; +using System.Text; + +namespace Cyberpipe.SM4 +{ + public class DesTools + { + #region 3des加密 + + /// + /// 3des ecb模式加密() + /// + /// 待加密的字符串 + /// 密钥 + /// 加密矢量:只有在CBC解密模式下才适用 + /// 运算模式 + /// 加密后的字符串 + public static string Encrypt3Des(string aStrString, string aStrKey) + { + byte[] str = strToHexByte(aStrString); + byte[] key = strToHexByte(aStrKey + aStrKey.Substring(0, 16)); + + TripleDESCryptoServiceProvider tdsc = new TripleDESCryptoServiceProvider(); + tdsc.Padding = PaddingMode.None; + + byte[] IV = { 0xB0, 0xA2, 0xB8, 0xA3, 0xDA, 0xCC, 0xDA, 0xCC }; + //指定密匙长度,默认为192位 + tdsc.KeySize = 128; + //使用指定的key和IV(加密向量) + Type t = Type.GetType("System.Security.Cryptography.CryptoAPITransformMode"); + object obj = t.GetField("Encrypt", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).GetValue(t); + MethodInfo mi = tdsc.GetType().GetMethod("_NewEncryptor", BindingFlags.Instance | BindingFlags.NonPublic); + ICryptoTransform desCrypt = (ICryptoTransform)mi.Invoke(tdsc, new object[] { key, CipherMode.ECB, null, 0, obj }); + tdsc.IV = IV; + //加密模式,偏移 + tdsc.Mode = CipherMode.ECB; + + //进行加密转换运算 + //ICryptoTransform ct = tdsc.CreateDecryptor(); + //8很关键,加密结果是8字节数组 + byte[] results = desCrypt.TransformFinalBlock(str, 0, str.Length); + + return byteToHexStr(results).ToUpper(); ; + + } + + #endregion + + + public static String generalStringToAscii(int length) + { + + int num = 1; + for (int i = 0; i < length; i++) + { + num *= 10; + } + + Random rand = new Random(); + String strRandom = (rand.Next(num).ToString()).PadLeft(length, '0'); + + StringBuilder sb = new StringBuilder(); + byte[] bytes = Encoding.ASCII.GetBytes(strRandom); + for (int i = 0; i < bytes.Length; i++) + { + sb.Append((int)bytes[i]); + } + + return sb.ToString(); + } + + public static String padding80(String data) + { + + int padlen = 8 - (data.Length / 2) % 8; + String padstr = ""; + for (int i = 0; i < padlen - 1; i++) + { + padstr += "00"; + } + data = data + "80" + padstr; + return data; + } + + /// + /// 字符串转16进制字节数组 + /// + /// + /// + public static byte[] strToHexByte(string hexString) + { + hexString = hexString.Replace(" ", ""); + if ((hexString.Length % 2) != 0) + hexString += "0"; + byte[] returnBytes = new byte[hexString.Length / 2]; + for (int i = 0; i < returnBytes.Length; i++) + returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + return returnBytes; + } + + /// + /// 字节数组转16进制字符串 + /// + /// + /// + public static string byteToHexStr(byte[] bytes) + { + string returnStr = ""; + if (bytes != null) + { + for (int i = 0; i < bytes.Length; i++) + { + returnStr += bytes[i].ToString("x2"); + } + } + return returnStr; + } + } +} diff --git a/SM4/SM4.cs b/SM4/SM4.cs new file mode 100644 index 0000000..6f19a84 --- /dev/null +++ b/SM4/SM4.cs @@ -0,0 +1,317 @@ +using System; +using System.Collections.Generic; + +namespace Cyberpipe.SM4 +{ + class SM4 + { + public const int SM4_ENCRYPT = 1; + public const int SM4_DECRYPT = 0; + + private long GET_ULONG_BE(byte[] b, int i) + { + long n = (long)(b[i] & 0xff) << 24 | (long)((b[i + 1] & 0xff) << 16) | (long)((b[i + 2] & 0xff) << 8) | (long)(b[i + 3] & 0xff) & 0xffffffffL; + return n; + } + + private void PUT_ULONG_BE(long n, byte[] b, int i) + { + b[i] = (byte)(int)(0xFF & n >> 24); + b[i + 1] = (byte)(int)(0xFF & n >> 16); + b[i + 2] = (byte)(int)(0xFF & n >> 8); + b[i + 3] = (byte)(int)(0xFF & n); + } + + private long SHL(long x, int n) + { + return (x & 0xFFFFFFFF) << n; + } + + private long ROTL(long x, int n) + { + return SHL(x, n) | x >> (32 - n); + } + + private void SWAP(long[] sk, int i) + { + long t = sk[i]; + sk[i] = sk[(31 - i)]; + sk[(31 - i)] = t; + } + + public byte[] SboxTable = new byte[] { (byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe, + (byte) 0xcc, (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6, + 0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b, 0x67, + (byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3, + (byte) 0xaa, 0x44, 0x13, 0x26, 0x49, (byte) 0x86, 0x06, + (byte) 0x99, (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91, + (byte) 0xef, (byte) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, + (byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62, (byte) 0xe4, + (byte) 0xb3, 0x1c, (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8, + (byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94, (byte) 0xfa, + 0x75, (byte) 0x8f, 0x3f, (byte) 0xa6, 0x47, 0x07, (byte) 0xa7, + (byte) 0xfc, (byte) 0xf3, 0x73, 0x17, (byte) 0xba, (byte) 0x83, + 0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8, + 0x68, 0x6b, (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda, + (byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70, 0x56, + (byte) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1, + (byte) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (byte) 0x87, + (byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27, + 0x52, 0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4, + (byte) 0xc8, (byte) 0x9e, (byte) 0xea, (byte) 0xbf, (byte) 0x8a, + (byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3, + (byte) 0xf7, (byte) 0xf2, (byte) 0xce, (byte) 0xf9, 0x61, 0x15, + (byte) 0xa1, (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4, + (byte) 0x9b, 0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32, + 0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3, 0x1d, + (byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca, + 0x60, (byte) 0xc0, 0x29, 0x23, (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f, + (byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd, + (byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, + 0x51, (byte) 0x8d, 0x1b, (byte) 0xaf, (byte) 0x92, (byte) 0xbb, + (byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41, + 0x1f, 0x10, 0x5a, (byte) 0xd8, 0x0a, (byte) 0xc1, 0x31, + (byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d, + 0x74, (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4, + (byte) 0xb0, (byte) 0x89, 0x69, (byte) 0x97, 0x4a, 0x0c, + (byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09, + (byte) 0xc5, 0x6e, (byte) 0xc6, (byte) 0x84, 0x18, (byte) 0xf0, + 0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79, + (byte) 0xee, 0x5f, 0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48 }; + + public uint[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc }; + + public uint[] CK = { 0x00070e15,0x1c232a31,0x383f464d,0x545b6269, + 0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9, + 0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249, + 0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9, + 0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229, + 0x30373e45,0x4c535a61,0x686f767d,0x848b9299, + 0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209, + 0x10171e25,0x2c333a41,0x484f565d,0x646b7279 }; + + private byte sm4Sbox(byte inch) + { + int i = inch & 0xFF; + byte retVal = SboxTable[i]; + return retVal; + } + + private long sm4Lt(long ka) + { + long bb = 0L; + long c = 0L; + byte[] a = new byte[4]; + byte[] b = new byte[4]; + PUT_ULONG_BE(ka, a, 0); + b[0] = sm4Sbox(a[0]); + b[1] = sm4Sbox(a[1]); + b[2] = sm4Sbox(a[2]); + b[3] = sm4Sbox(a[3]); + bb = GET_ULONG_BE(b, 0); + c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24); + return c; + } + + private long sm4F(long x0, long x1, long x2, long x3, long rk) + { + return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk); + } + + private long sm4CalciRK(long ka) + { + long bb = 0L; + long rk = 0L; + byte[] a = new byte[4]; + byte[] b = new byte[4]; + PUT_ULONG_BE(ka, a, 0); + b[0] = sm4Sbox(a[0]); + b[1] = sm4Sbox(a[1]); + b[2] = sm4Sbox(a[2]); + b[3] = sm4Sbox(a[3]); + bb = GET_ULONG_BE(b, 0); + rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23); + return rk; + } + + private void sm4_setkey(long[] SK, byte[] key) + { + long[] MK = new long[4]; + long[] k = new long[36]; + int i = 0; + MK[0] = GET_ULONG_BE(key, 0); + MK[1] = GET_ULONG_BE(key, 4); + MK[2] = GET_ULONG_BE(key, 8); + MK[3] = GET_ULONG_BE(key, 12); + k[0] = MK[0] ^ (long)FK[0]; + k[1] = MK[1] ^ (long)FK[1]; + k[2] = MK[2] ^ (long)FK[2]; + k[3] = MK[3] ^ (long)FK[3]; + for (; i < 32; i++) + { + k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long)CK[i])); + SK[i] = k[(i + 4)]; + } + } + + private void sm4_one_round(long[] sk, byte[] input, byte[] output) + { + int i = 0; + long[] ulbuf = new long[36]; + ulbuf[0] = GET_ULONG_BE(input, 0); + ulbuf[1] = GET_ULONG_BE(input, 4); + ulbuf[2] = GET_ULONG_BE(input, 8); + ulbuf[3] = GET_ULONG_BE(input, 12); + while (i < 32) + { + ulbuf[(i + 4)] = sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]); + i++; + } + PUT_ULONG_BE(ulbuf[35], output, 0); + PUT_ULONG_BE(ulbuf[34], output, 4); + PUT_ULONG_BE(ulbuf[33], output, 8); + PUT_ULONG_BE(ulbuf[32], output, 12); + } + + private byte[] padding(byte[] input, int mode) + { + if (input == null) + { + return null; + } + + byte[] ret = (byte[])null; + if (mode == SM4_ENCRYPT) + { + int p = (input.Length % 16 == 0) ? 0 : (16 - input.Length % 16); + ret = new byte[input.Length + p]; + Array.Copy(input, 0, ret, 0, input.Length); + for (int i = 0; i < p; i++) + { + ret[input.Length + i] = 0x00; + } + } + else + { + int p = input[input.Length - 1]; + ret = new byte[input.Length - p]; + Array.Copy(input, 0, ret, 0, input.Length - p); + } + return ret; + } + + public void sm4_setkey_enc(SM4_Context ctx, byte[] key) + { + ctx.mode = SM4_ENCRYPT; + sm4_setkey(ctx.sk, key); + } + + public void sm4_setkey_dec(SM4_Context ctx, byte[] key) + { + int i = 0; + ctx.mode = SM4_DECRYPT; + sm4_setkey(ctx.sk, key); + for (i = 0; i < 16; i++) + { + SWAP(ctx.sk, i); + } + } + + public byte[] sm4_crypt_ecb(SM4_Context ctx, byte[] input) + { + if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT)) + { + input = padding(input, SM4_ENCRYPT); + } + + int length = input.Length; + byte[] bins = new byte[length]; + Array.Copy(input, 0, bins, 0, length); + byte[] bous = new byte[length]; + for (int i = 0; length > 0; length -= 16, i++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + sm4_one_round(ctx.sk, inBytes, outBytes); + Array.Copy(outBytes, 0, bous, i * 16, length > 16 ? 16 : length); + } + + //if (ctx.isPadding && ctx.mode == SM4_DECRYPT) + //{ + // bous = padding(bous, SM4_DECRYPT); + //} + return bous; + } + + public byte[] sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input) + { + if (ctx.isPadding && ctx.mode == SM4_ENCRYPT) + { + input = padding(input, SM4_ENCRYPT); + } + + int i = 0; + int length = input.Length; + byte[] bins = new byte[length]; + Array.Copy(input, 0, bins, 0, length); + byte[] bous = null; + List bousList = new List(); + if (ctx.mode == SM4_ENCRYPT) + { + for (int j = 0; length > 0; length -= 16, j++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + byte[] out1 = new byte[16]; + + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + for (i = 0; i < 16; i++) + { + outBytes[i] = ((byte)(inBytes[i] ^ iv[i])); + } + sm4_one_round(ctx.sk, outBytes, out1); + Array.Copy(out1, 0, iv, 0, 16); + for (int k = 0; k < 16; k++) + { + bousList.Add(out1[k]); + } + } + } + else + { + byte[] temp = new byte[16]; + for (int j = 0; length > 0; length -= 16, j++) + { + byte[] inBytes = new byte[16]; + byte[] outBytes = new byte[16]; + byte[] out1 = new byte[16]; + + Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length); + Array.Copy(inBytes, 0, temp, 0, 16); + sm4_one_round(ctx.sk, inBytes, outBytes); + for (i = 0; i < 16; i++) + { + out1[i] = ((byte)(outBytes[i] ^ iv[i])); + } + Array.Copy(temp, 0, iv, 0, 16); + for (int k = 0; k < 16; k++) + { + bousList.Add(out1[k]); + } + } + + } + + if (ctx.isPadding && ctx.mode == SM4_DECRYPT) + { + bous = padding(bousList.ToArray(), SM4_DECRYPT); + return bous; + } + else + { + return bousList.ToArray(); + } + } + } +} diff --git a/SM4/SM4Utils.cs b/SM4/SM4Utils.cs new file mode 100644 index 0000000..ef19172 --- /dev/null +++ b/SM4/SM4Utils.cs @@ -0,0 +1,44 @@ +using Org.BouncyCastle.Utilities.Encoders; +using System; + +namespace Cyberpipe.SM4 +{ + public class SM4Utils + { + private static string secretKey = "45f3fabdf725985ba451b9640ea46ea7"; + public static byte[] SM4Encrypt(byte[] plainBytes) + { + SM4_Context ctx = new SM4_Context(); + ctx.isPadding = true; + ctx.mode = SM4.SM4_ENCRYPT; + + byte[] keyBytes = Hex.Decode(secretKey); + + SM4 sm4 = new SM4(); + sm4.sm4_setkey_enc(ctx, keyBytes); + byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainBytes); + + return encrypted; + } + + public static string SM4EncryptStr(string asciiStr) + { + byte[] encrypted = SM4Utils.SM4Encrypt(System.Text.Encoding.ASCII.GetBytes(asciiStr)); + return Hex.ToHexString(encrypted); + } + + public static string SM4Decrypt(byte[] cipherBytes) + { + SM4_Context ctx = new SM4_Context(); + ctx.isPadding = true; + ctx.mode = SM4.SM4_DECRYPT; + + byte[] keyBytes = Hex.Decode(secretKey); + + SM4 sm4 = new SM4(); + sm4.sm4_setkey_dec(ctx, keyBytes); + byte[] decrypted = sm4.sm4_crypt_ecb(ctx, cipherBytes); + return Hex.ToHexString(decrypted); + } + } +} diff --git a/SM4/SM4_Context.cs b/SM4/SM4_Context.cs new file mode 100644 index 0000000..d82660c --- /dev/null +++ b/SM4/SM4_Context.cs @@ -0,0 +1,19 @@ + +namespace Cyberpipe.SM4 +{ + class SM4_Context + { + public int mode; + + public long[] sk; + + public bool isPadding; + + public SM4_Context() + { + this.mode = 1; + this.isPadding = true; + this.sk = new long[32]; + } + } +} diff --git a/SM4/SecurityUtils.cs b/SM4/SecurityUtils.cs new file mode 100644 index 0000000..5093004 --- /dev/null +++ b/SM4/SecurityUtils.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Text; + +namespace Cyberpipe.SM4 +{ + class SecurityUtils + { + /// + /// 加密响应 + /// + /// + /// + /// + public static String encodeResponse(String actionInfo, String appSecret) + { + try + { + Console.WriteLine("明文:{0}", actionInfo); + //1.生成随机数 + String random = DesTools.generalStringToAscii(8) + DesTools.generalStringToAscii(8); + Console.WriteLine("随机数:{0}", random); + + //2.生成过程密钥 + String processKey = DesTools.Encrypt3Des(random, appSecret); + Console.WriteLine("过程秘钥:{0}", processKey); + + //3. 将actionInfo转换16进制后,补80 + String ciphertext = DesTools.padding80(DesTools.byteToHexStr(Encoding.UTF8.GetBytes(actionInfo))); + Console.WriteLine("转换16进制后补80: {0}", ciphertext); + + //4. 将字符串编码成16进制数字,适用于所有字符(包括中文) + byte[] bytes = Encoding.ASCII.GetBytes(ciphertext); + ciphertext = BitConverter.ToString(bytes, 0, bytes.Length).Replace("-", ""); + Console.WriteLine("16进制字符串: {0}", ciphertext); + // 加密 + ciphertext = DesTools.Encrypt3Des(ciphertext, processKey); + Console.WriteLine("密文: {0}", ciphertext); + // 最终生成密文 + ciphertext = random + ciphertext; + Console.WriteLine("带随机数的密文: {0}", ciphertext); + return ciphertext; + } + catch (Exception e) + { + Console.WriteLine("加密错误. ", e); + return null; + } + } + + + /// + /// 创建签名 + /// + /// + /// + /// + public static String createSignature(String appSecret, Dictionary parameters) + { + SortedDictionary sortedMap = new SortedDictionary(parameters); + StringBuilder sb = new StringBuilder(); + foreach (var map in sortedMap) + { + if (map.Value != null && !"sign".Equals(map.Key)) + { + sb.Append(map.Key).Append("=").Append(map.Value).Append("&"); + } + } + + sb.Append("key=").Append(appSecret); + //算出摘要 + Console.WriteLine("签名原数据:{0}", sb.ToString());//.Replace(" ", "")); + + MD5 md5 = MD5.Create(); + byte[] s = md5.ComputeHash(Encoding.ASCII.GetBytes(sb.ToString())); + + String signature = DesTools.byteToHexStr(s).ToUpper(); + Console.WriteLine("签名:{0}", signature); + return signature; + } + + + //public static void Main() + //{ + // //请求报文体数据 + // String s = "{\n" + + // " \"deviceType\": \"gasjc01\",\n" + + // " \"tid\": \"312021160001\",\n" + + // " \"imei\": \"864831053786797\",\n" + + // " \"iccid\": \"89861119257011752675\",\n" + + // " \"cnt\": \"1234567890123456\",\n" + + // " \"mac\": \"5e33a6376025d3a87fcb49bb12ace534\"\n" + + // " }"; + + // Console.WriteLine("s:" + s); + // //加密报文体 + // String s1 = SecurityUtils.encodeResponse(s, "dc43576cd2a045dfb48c93212fdbfdff"); + // Console.WriteLine("s1:" + s1); + + + + // //签名数据 + // Dictionary hashMap = new Dictionary(); + // hashMap.Add("appId", "a9c92d1b8b72417285744962d06e145b"); + // hashMap.Add("body", s1); + // hashMap.Add("msgId", "22222222222222"); + // hashMap.Add("encodeMethod", "md5"); + // hashMap.Add("signMethod", "md5"); + // String s2 = SecurityUtils + // .createSignature("dc43576cd2a045dfb48c93212fdbfdff", hashMap); + // Console.WriteLine("s2:" + s2); + + // Console.ReadKey(); + //} + + } +}