当前位置: 首页 > wzjs >正文

绵阳建网站医疗网站怎么做优化

绵阳建网站,医疗网站怎么做优化,上海传媒公司名字,郑州服装设计公司老项目,用户在使用时修改密码不成功。通过查看是因为密码修改时,根本匹配不到用户名;由于用户名通过RSA加密后每次输出都不一样,与原始数据库中存储的用户不匹配。解决办法为向用户表中添加字段UserNameHash(用户名has…

老项目,用户在使用时修改密码不成功。通过查看是因为密码修改时,根本匹配不到用户名;由于用户名通过RSA加密后每次输出都不一样,与原始数据库中存储的用户不匹配。解决办法为向用户表中添加字段UserNameHash(用户名hash值),更新匹配用户名时使用UserNameHash进行匹配。

问题现象

某老项目,在使用时被用户发现不能正常修改密码。反馈到软件部后,被分配到去修改此bug。

开发环境

VS2022

SqLite3

排查过程

不能修改密码?download源码后,试了下,确实有这个问题。但为什么呢?在UI上明明显示已经修改成功了啊;但是为什么用新密码登陆却显示密码错误,必须用原来的密码才能登陆成功。

猜想:应该是密码未成功修改进数据库中,UI上仅仅是显示的VM绑定的数据而已。

看了下更新进sqlite数据库的代码,如下所示:

/// <summary>
/// 更新用户密码
/// </summary>
/// <param name="userName"></param>
/// <param name="newPassword"></param>
public void UpdatePassword(string userName, string newPassword)
{string encryptionAccount = RSA.EncryptByRSA(userName);string encryptionPassword = RSA.EncryptByRSA(newPassword);string cmd = "UPDATE UserInfoTable SET Password = '" + encryptionPassword + "' WHERE UserName = '" + encryptionAccount + "'";object lockThis = new object();lock (lockThis){using (SQLiteConnection conn = new SQLiteConnection("Data Source=" + PathCfg.Database + ";Version=3;")){conn.Open();using (SQLiteCommand command = new SQLiteCommand(cmd, conn)){try{command.ExecuteNonQuery();command.Dispose();conn.Close();}catch (Exception){}}}}
}

在上述代码的 command.ExecuteNonQuery();  将其更改下述代码后,测试了下,影响的行数为0;也就说根本就没有匹配到任何用户,当然也就更改不成功了。

var rows= command.ExecuteNonQuery(); 

仔细看了更新代码,同时确认用户名输入没有问题,那么问题只可能是最终的用户名匹配不到,而之所以匹配不到,反推回来,只有中间使用 RSA.EncryptByRSA(userName) 加密,在加密后导致密文与最初的密文不匹配造成的。

经验证,确实如前述所说:加密后的密文与原始数据库中的用户名密文不一样。

也就是说加密模块可能是有问题。

加密RSA类EncryptByRSA加密方法源码如下:

        /// <summary>/// RSA加密/// </summary>/// <param name="plaintext">明文字符串</param>/// <returns>密文字符串</returns>public static string EncryptByRSA(string plaintext){UnicodeEncoding ByteConverter = new UnicodeEncoding();byte[] dataToEncrypt = ByteConverter.GetBytes(plaintext);using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()){rsa.FromXmlString(publicKey);byte[] encryptedData = rsa.Encrypt(dataToEncrypt, true);return Convert.ToBase64String(encryptedData);}}

解密方法源码如下:

 /// <summary>/// RSA解密/// </summary>/// <param name="ciphertext">加密字符串</param>/// <returns>明文字符串</returns>public static string DecryptByRSA(string ciphertext){UnicodeEncoding byteConverter = new UnicodeEncoding();using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()){rsa.FromXmlString(privateKey);byte[] encryptedData = Convert.FromBase64String(ciphertext);byte[] decryptedData = rsa.Decrypt(encryptedData, true);return byteConverter.GetString(decryptedData);}}

通过在加密模块中添加测试代码后发现,用户名每次加密后的密文都不一样,但还是能解密为输入的用户名。自然每次更新用户名密码时肯定不会成功了。

以下为测试用户名加密解密时使用的代码:

public static string EncryptByRSA(string plaintext)
{UnicodeEncoding ByteConverter = new UnicodeEncoding();byte[] dataToEncrypt = ByteConverter.GetBytes(plaintext);using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()){rsa.FromXmlString(publicKey);byte[] encryptedData = rsa.Encrypt(dataToEncrypt, true);var test = Convert.ToBase64String(encryptedData);var deResult = DecryptByRSA(test);return Convert.ToBase64String(encryptedData);}
}

原因分析

为什么相同输入会产生不同密文?​​

1. ​​PKCS#1 OAEP填充模式的作用​​

代码中rsa.Encrypt(dataToEncrypt, true)的第二个参数true表示:

  • 使用 ​​OAEP (Optimal Asymmetric Encryption Padding)​​ 填充模式
  • 该模式会​​自动添加随机盐值(salt)​​到明文数据前,导致每次加密结果不同
2. ​​安全设计原理​​
特性说明
​​防止重放攻击​​相同明文不同密文,使攻击者无法通过重复发送密文破解
​​隐藏明文模式​​即使明文有规律,密文也呈现随机性
​​语义安全性​​加密结果不泄露明文的任何信息(包括是否相同)

详细可参考RSA 类 (System.Security.Cryptography) | Microsoft Learn

解决方案

既然是由于加密后的用户名密文不一样所致,最简单的办法就是对用户名不加密,但是这就存在用户名泄漏的问题。

继要保证用户名不泄漏,又要能保证能正常的更新,同时用户名最好还是能从数据库中读出来用于显示。那么在数据库中添加1个字段为UserNameHash,UserNameHash使用不可逆加密(hash值),同时保留用来的用户名和密码;

查询更新时使用hash去匹配对应的用户即可。

以下为hash计算参考源码:

public static string HashName(string name) {using (SHA256 sha = SHA256.Create()) {byte[] hash = sha.ComputeHash(Encoding.UTF8.GetBytes(name));return Convert.ToBase64String(hash);}
}

 改进后代码:

// 改进后的UpdatePassword方法示例
public void UpdatePassword(string userName, string newPassword)
{string userNameHash = HashName(userName); // 使用哈希值作为查询条件string encryptionPassword = RSA.EncryptByRSA(newPassword);// 使用参数化查询防止SQL注入string cmd = "UPDATE UserInfoTable SET Password = @Password WHERE UserNameHash = @UserNameHash";object lockThis=new object();lock (lockThis){using (SQLiteConnection conn = new SQLiteConnection("Data Source=" + PathCfg.Database + ";Version=3;")){conn.Open();using (SQLiteCommand command = new SQLiteCommand(cmd, conn)){command.Parameters.AddWithValue("@Password", encryptionPassword);command.Parameters.AddWithValue("@UserNameHash", userNameHash);int affectedRows = command.ExecuteNonQuery();if (affectedRows == 0){// 应该记录或抛出异常,而不是静默失败throw new InvalidOperationException("用户不存在或更新失败");}}}}
}

安全建议

这个老项目存在的问题,除了这个密码修改的问题,还有其它一些。

如UpdatePassword方法中,sql使用拼接字符串,这是很要命的,会导致严重的 ​​SQL注入攻击(SQL Injection)​​ 风险;这是很致命的,要是web项目,这种代码就是垃圾代码,不允许上线的。

一定要记住,sql语句要参数化查询。另外当下ORM很成熟了,用起来。

http://www.dtcms.com/wzjs/536228.html

相关文章:

  • 电脑网站怎么做的贵阳手机网站开发
  • 酥糖的网站建设的目的是什么网页设计的基本元素
  • 畜牧业网站建设哪些网站做二手挖机
  • 网站策划编辑招聘分析网站设计对网站搜索引擎友好性的影响
  • 茂名网站制作价格无棣网站定制
  • vs2017建设网站微网站的定义
  • 在搜狐快站上做网站怎么跳转微信网页版手机端
  • 网页设计自学视频网站四川企业seo
  • 专业做蛋糕视频网站国内网页设计公司前十名
  • 微信网站wordpress 下载页面模板
  • 中国优秀网站设计上海关键词优化推荐
  • 工厂弄个网站做外贸如何处理官方微信公众号怎么创建
  • 网站添加在线qq聊天如何做flash游戏下载网站
  • 怎样给公司做网站株洲平台公司有几家
  • 医院 网站建设 中企动力微信上建微网站要钱吗
  • 成都网站设计哪家比较好河南app手机网站制作
  • 德阳网站建设ghxhwl不用js做网站
  • 动态手机网站怎么做南宁网页设计培训机构
  • 河南郑州网站推广优化音乐网站建设成本
  • 模板建站可以做优化吗企业形象网站开发
  • 网站美工做图推荐揭阳城乡建设局网站
  • wordpress搭建网站有什么好外兴安盟网站建设
  • wap网站预览部门网站建设怎么做
  • 如何做电子海报在网站ppt设计培训班
  • 百度站长官网成都定制网站建设地址
  • 国外网站模版广州市官网网站建设多少钱
  • sem竞价托管价格宁波优化推广
  • 现在哪个网站可以做外贸平面设计大师
  • nas怎么做自己的网站找企业做网站
  • 忻州做网站随州网站建站