`

用RSA加密实现Web登录密码加密传输【转】

 
阅读更多

转自:http://www.cnblogs.com/guogangj/archive/2012/03/05/2381117.html 

 

通常我们做一个Web应用程序的时候都需要登录,登录就要输入用户名和登录密码,并且,用户名和登录密码都是明文传输的,这样就有可能在中途被别人拦截,尤其是在网吧等场合。

这里顺带一个小插曲,我以前有家公司,办公室装修时候安排的网口相对较少,不太够用,于是我和另外一个同事使用了一个hub来共享一个网口,这就导致了很有趣的现象:任何他的网络包我都能抓得到,当然了,我的他也能抓得到。这是不是有很大的安全隐患了?我有可能在不经意间会泄漏自己的密码。

所以,很多安全要求较高的网站都不会明文传输密码,它们会使用https来确保传输过程的安全,https是用证书来实现的,证书来自于证书颁发机构,当然了,你也可以自己造一张证书,但这样别人访问你的网站的时候还是会遇到麻烦,因为你自己造的证书不在用户浏览器的信任范围之内,你还得在用户浏览器上安装你的证书,来让用户浏览器相信你的网站,很多用户并不知道如何操作,就算会操作,也能也不乐意干;另一种选择是你向权威证书颁发机构申请一张证书,但这样有一定的门槛,还需要付费,也不是我们乐意干的事。

所以,我打算自己实现一个密码加密传输方法。

这里使用了RSA非对称加密算法,对称加密也许大家都已经很熟悉,也就是加密和解密用的都是同样的密钥,没有密钥,就无法解密,这是对称加密。而非对称加密算法中,加密所用的密钥和解密所用的密钥是不相同的:你使用我的公钥加密,我使用我的私钥来解密;如果你不使用我的公钥加密,那我无法解密;如果我没有私钥,我也没法解密。

我设计的这个登录密码加密传输方法的原理图如下:

 

首先,先演练一下非对称加密:

复制代码
static void Main(string[] args)
{
//用于字符串和byte[]之间的互转
UTF8Encoding utf8encoder = new UTF8Encoding();

//产生一对公钥私钥
RSACryptoServiceProvider rsaKeyGenerator = new RSACryptoServiceProvider(1024);
string publickey = rsaKeyGenerator.ToXmlString(false);
string privatekey = rsaKeyGenerator.ToXmlString(true);

//使用公钥加密密码
RSACryptoServiceProvider rsaToEncrypt = new RSACryptoServiceProvider();
rsaToEncrypt.FromXmlString(publickey);
string strPassword = "@123#abc$";
Console.WriteLine("The original password is: {0}", strPassword);
byte[] byEncrypted = rsaToEncrypt.Encrypt(utf8encoder.GetBytes(strPassword), false);
Console.Write("Encoded bytes: ");
foreach (Byte b in byEncrypted)
{
Console.Write("{0}", b.ToString("X"));
}
Console.Write("\n");
Console.WriteLine("The encrypted code length is: {0}", byEncrypted.Length);

//解密
RSACryptoServiceProvider rsaToDecrypt = new RSACryptoServiceProvider();
rsaToDecrypt.FromXmlString(privatekey);
byte[] byDecrypted = rsaToDecrypt.Decrypt(byEncrypted, false);
string strDecryptedPwd = utf8encoder.GetString(byDecrypted);
Console.WriteLine("Decrypted Password is: {0}", strDecryptedPwd);
}
复制代码

大家可以清楚看到,密码被加密成128字节长度的密文,为什么是固定128字节呢?这是因为我们的RSACryptoServiceProvider默认生成的key的长度是1024,即1024位的加密,所以不管你要加密的密码有多长,它生成的密文的长度肯定是128字节,也因为这样,密码的长度是有限制的,1024位的RSA算法,只能加密大约100个字节长度的明文,要提高可加密的明文的长度限制,就得增加key的长度,比如把key改到2048位,这样能加密的明文的长度限制也就变为大概200出头这样……还是太少啊!而且这样会带来加密速度的显著下降,RSA本来就很慢……是的,比同没有长度限制的对称加密,这种非对称加密的限制可真多,即便是200个字符,又能传输什么东西呢?——密码!这个就够了,传输完密码之后,我们就使用对称加密,所以,RSA往往是用来“协商”一个对称加密的key的。

接下去,真正的难点在于用javascript实现一个和.net的RSA兼容的算法。密码学,对我来说真像天书一般,每次我一看就头大,这个工作是没办法自己做的了,只能到网上找,那是相当的费力啊,找到许多js的RSA实现,但都和.net的这套东西不兼容,最后还是功夫不负有心人,终于找到了一套。不多说,上代码:

复制代码
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>RSA Login Test</title>
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<script src="Scripts/jQuery.md5.js" type="text/javascript" ></script>
<script src="Scripts/BigInt.js" type="text/javascript"></script>
<script src="Scripts/RSA.js" type="text/javascript"></script>
<script src="Scripts/Barrett.js" type="text/javascript"></script>
<script type="text/javascript">
function cmdEncrypt() {
setMaxDigits(
129);
var key = new RSAKeyPair("<%=strPublicKeyExponent%>", "", "<%=strPublicKeyModulus%>");
var pwdMD5Twice = $.md5($.md5($("#txtPassword").attr("value")));
var pwdRtn = encryptedString(key, pwdMD5Twice);
$(
"#encrypted_pwd").attr("value", pwdRtn);
$(
"#formLogin").submit();
return;
}
</script>

</head>
<body>
<form action="Default.aspx" id="formLogin" method="post">
<div>
<div>
User Name:
</div>
<div>
<input id="txtUserName" name="txtUserName" value="<%=postbackUserName%>" type="text" maxlength="16" />
</div>
<div>
Password:
</div>
<div>
<input id="txtPassword" type="password" maxlength="16" />
</div>
<div>
<input id="btnLogin" type="button" value="Login" onclick="return cmdEncrypt()" />
</div>
</div>
<div>
<input type="hidden" name="encrypted_pwd" id="encrypted_pwd" />
</div>
</form>
<div>
<%=LoginResult%>
</div>
</body>
</html>
复制代码

这是客户端代码,大家可以看到,基本没有什么服务器端代码,<%=postbackUserName%>用于回显输入的用户名,<%=LoginResult%>用于显示登录结果,<%=strPublicKeyExponent%>和<%=strPublicKeyModulus%>则用来告诉客户端RSA公钥。需要的javascript文件说明:

  • jQuery.md5.js -  用于对密码进行两次md5加密;(我通常在数据库中保存的用户密码是两次MD5后的结果)
  • BigInt.js - 用于生成一个大整型;(这是RSA算法的需要)
  • RSA.js - RSA的主要算法;
  • Barrett.js - RSA算法所需要用到的一个支持文件;

对于密码学,我几乎一无所知,所以没办法跟大家解释清楚RSA算法的原理,抱歉,我只知道怎么用。关于javascript中这行代码:“setMaxDigits(129);”具体表示什么我也不清楚,我只知道,把参数改为小于129的数之后会导致客户端的javascript执行进入死循环。服务器端代码也很简单:

复制代码
protected void Page_Load(object sender, EventArgs e)
{
LoginResult = "";
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
if (string.Compare(Request.RequestType, "get", true)==0)
{
//将私钥存Session中
Session["private_key"] = rsa.ToXmlString(true);
}
else
{
bool bLoginSucceed = false;
try
{
string strUserName = Request.Form["txtUserName"];
postbackUserName = strUserName;
string strPwdToDecrypt = Request.Form["encrypted_pwd"];
rsa.FromXmlString((string)Session["private_key"]);
byte[] result = rsa.Decrypt(HexStringToBytes(strPwdToDecrypt), false);
System.Text.ASCIIEncoding enc = new ASCIIEncoding();
string strPwdMD5 = enc.GetString(result);
if (string.Compare(strUserName, "user1", true)==0 && string.Compare(strPwdMD5, "14e1b600b1fd579f47433b88e8d85291", true)==0)
bLoginSucceed = true;
}
catch (Exception)
{

}
if (bLoginSucceed)
LoginResult = "登录成功";
else
LoginResult = "登录失败";
}

//把公钥适当转换,准备发往客户端
RSAParameters parameter = rsa.ExportParameters(true);
strPublicKeyExponent = BytesToHexString(parameter.Exponent);
strPublicKeyModulus = BytesToHexString(parameter.Modulus);
}
复制代码

用户名“user1”
密码“123456”

登录成功!

抓取http报文看看POST的“密码”:

这样的“密码”的破解就成为了理论上的可行了。:)

下面提供完整代码下载(使用VS2010开发环境):

http://files.cnblogs.com/guogangj/RSALoginTest.zip

分享到:
评论

相关推荐

    C# 用RSA加密实现Web登录密码加密传输(网页口令传输加密)

    八成网站登录口令“裸身待缚” 电商类全军覆没,在用户口令传输过程中,仍然存在很多隐患。一般而言,用户在登录网站...而《报告》中显示,大部分样本网站在传输口令时,没有做加密处理,直接将明文密码向服务端传输。

    Java RSA加密前后端实现

    在这个项目"Java RSA加密前后端实现"中,前端部分可能使用JavaScript实现了RSA加密。JavaScript作为客户端语言,可以方便地在用户浏览器中运行,对用户的密码或其他敏感信息进行加密,然后将加密后的数据发送到...

    rsa加密前后端交互.前端加密后端解密

    通常,前端可以通过JavaScript库如CryptoJS或者Web Cryptography API来实现RSA加密。后端则可能使用Java的Java Cryptography Extension (JCE)、Python的pycryptodome库或者其他语言的相应库来处理RSA加密解密。 在...

    RSA非对称 C#解密、js加密实现登陆密文传输

    在C#中,可以使用`System.Security.Cryptography.RSACryptoServiceProvider`类来实现RSA加密和解密。首先,你需要生成一对RSA密钥,然后将公钥暴露给客户端(这里指的是JavaScript),私钥保留在服务器端。C#代码...

    前端 RSA分段加密算法

    这个库很可能提供了对RSA加密的基本操作,如生成公钥/私钥对,使用公钥加密数据,以及使用私钥解密数据。开发者可以利用这个库将大文件或长字符串通过分段加密的方式进行安全传输。 在实际应用中,前端开发者首先...

    java版web登录用RSA加密

    在本文中,我们将深入探讨如何使用Java实现基于RSA加密的Web登录系统。RSA是一种非对称加密算法,常用于安全通信,确保数据在传输过程中的安全性。在这个小例子中,我们将会关注以下几点: 1. **RSA算法简介**:RSA...

    易语言调用JSEncrypt实现RSA加密解密

    在易语言中调用JSEncrypt库来实现RSA加密解密,可以为易语言的应用增加一层安全防护。 JSEncrypt是一个JavaScript库,由Benjamin van Ryseghem开发,主要用于RSA加密操作,特别适用于前端与后端之间的安全通信。它...

    nacos2.0.4版本使用RSA算法加密之后的源码,可以直接使用。

    下载nacos源码之后进行代码编写,修改了前端用户名和密码加密传输,后端使用RSA算法将收到的信息进行解码判断。内容包含源代码、打包之后的zip文件以及tar.gz文件,可以直接使用。 适用人群:项目使用nacos作为注册...

    js版本实现rsa加密

    另外,为了增强安全性,通常会结合对称加密算法(如AES)一起使用,即使用RSA加密对称密钥,然后用对称密钥加密大量数据。 7. **解密过程**:在服务器端,接收到加密数据后,使用私钥进行解密,恢复原始数据。这个...

    C#百度最新登录源码2015-07-04 添加Rsa加密

    本资源“C#百度最新登录源码2015-07-04 添加Rsa加密”是一个特定时期的C#代码示例,旨在帮助开发者实现对百度账号的模拟登录,并且包含了Rsa加密技术的集成,这样就无需依赖JavaScript文件进行加密操作。 首先,让...

    python Django RSA 前台加密 后端解密。

    在Python中,我们可以使用`PyCryptodome`库来实现RSA加密和解密。这个库提供了完整的密码学服务,包括RSA算法。`Cryptodome_demo`可能是一个包含示例代码的文件,我们可以通过它了解如何在Django中使用RSA。 下面是...

    RSA加密文件.rar

    对于这种情况,通常会使用对称加密算法(如AES)对大量数据进行快速加密,然后用RSA加密对称密钥,实现“密钥交换”,兼顾效率和安全性。 总的来说,RSA加密在前端和后端间的应用是现代Web服务中保障信息安全的重要...

    RSA加密与解密毕业论文

    RSA加密算法是公钥密码学领域的一个里程碑,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,因此得名RSA。这种算法基于数论中的大整数因子分解问题,使得加密过程和解密过程在数学上是可逆的,但在实际...

    RSA加密所需要的js

    RSA加密是一种非对称加密算法,它在网络安全和数据保护领域广泛应用。该算法基于大整数因子分解...总的来说,这些JavaScript库为开发者提供了在Web环境中实现RSA加密解密的工具,对于网络数据的安全传输具有重要意义。

    jsp网页中用户登陆密码的MD5加密

    在jsp网页中,可以使用MD5类来实现用户登录密码的加密。例如,可以在登录页面的jsp代码中使用MD5类来加密用户输入的密码,然后将加密后的密码存储在数据库中。在登录验证时,可以再次使用MD5类来加密用户输入的密码...

    在ASP.Net中实现RSA加密

    在ASP.Net中实现RSA加密是一项重要的安全性技术,用于保护数据的隐私和完整性...总之,RSA加密是ASP.Net中实现数据安全的重要工具,通过熟练掌握RSACryptoServiceProvider类的使用,可以有效地保护应用程序的数据安全。

    rsa加密,js前端加密,java后端加密

    在你的项目中,前端(JavaScript)和后端(Java)都实现了RSA加密,使得数据在传输过程中更加安全。 在JavaScript中,你可以使用`crypto-js`库来实现RSA加密。这个库提供了各种加密算法,包括RSA。首先,你需要生成...

    RSA加密.zip

    在JavaScript中,可以使用开源库如CryptoJS或者Web Cryptography API来进行RSA加密。CryptoJS虽然不直接支持RSA,但可以通过导入如Forge等第三方库来实现。前端加密的基本流程是:生成一个密钥对(公钥和私钥),将...

    用HTML和JavaScript写的RSA加密小工具

    标题中的“用HTML和JavaScript写的RSA加密小工具”是指利用这两种前端技术开发的一款加密应用程序,主要功能是实现RSA加密算法。RSA是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,...

    集成jsencrypt实现密码加密传输方式.zip

    "集成jsencrypt实现密码加密传输方式.zip"这个压缩包文件显然包含了关于如何在若依(RuoYi)单体项目中集成jsencrypt库,以实现密码加密传输的详细步骤和示例。下面将详细介绍jsencrypt库以及如何在实际项目中应用它...

Global site tag (gtag.js) - Google Analytics