`
wb284551926
  • 浏览: 538909 次
文章分类
社区版块
存档分类
最新评论

用RSA加密实现Web登录密码加密传输(转载)

    博客分类:
  • RSA
阅读更多

通常我们做一个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登录密码加密传输(网页口令传输加密)

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

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

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

    web传输js加密java解密.zip

    spring-boot写的demo,实现前端js rsa公钥加密,后端java rsa私钥解密,用于网络传输数据加密用

    同时兼容JS和C#的RSA加密解密算法详解(对web提交的数据加密传输)

    前言 我们在Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的...这个也给贯通前后台的RSA加密解密带来了难度。为了兼容OpenSSL生成的公钥/私钥文件格式,贯通jav

    加密在WEB程序设计的应用

    加密在WEB程序设计的各种应用场景说明.传输加密、存储加密、消息验证

    socket加密使用OpenSsl

    SSL是Secure Socket Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。Netscape公司在推出第一个Web浏览器的同时,提出了SSL协议标准,目前已有3.0版本。SSL采用公开密钥技术

    基于RSA加密解密算法的iOS OC语言实现,不依赖系统Keychain和Security.framework.zip

    网络与通信:数据传输、信号处理、网络协议、网络与通信硬件、网络安全网络与通信是一个非常广泛的领域,它涉及到计算机科学、电子工程、数学等多个学科的知识。 云计算与大数据:数据集、包括云计算平台、大数据...

    iOS 简单 RSA 加密方法,使用系统库. 包含如何创建钥匙对。.zip

    网络与通信:数据传输、信号处理、网络协议、网络与通信硬件、网络安全网络与通信是一个非常广泛的领域,它涉及到计算机科学、电子工程、数学等多个学科的知识。 云计算与大数据:数据集、包括云计算平台、大数据...

    Java加密与解密的艺术

    可以攻玉1094.1 加固你的系统1094.2 加密组件Bouncy Castle 1114.3 辅助工具Commons Codec 1204.4 小结121第二部分实践篇第5章电子邮件传输算法—Base64 1345.1 Base64算法的由来1345.2 Base64算法的定义1345.3 Base...

    Java加密与解密的艺术配书源代码

    第5章电子邮件传输算法—Base64 134 5.1 Base64算法的由来134 5.2 Base64算法的定义134 5.3 Base64算法与加密算法的关系135 5.4 实现原理136 5.5 模型分析137 5.6 Base64算法实现138 5.7 Url Base64算法实现147 5.8 ...

    基于RSA公钥算法的加密解密工具库iOS OC语言实现,依赖iOS系统的Security.framework。.zip

    网络与通信:数据传输、信号处理、网络协议、网络与通信硬件、网络安全网络与通信是一个非常广泛的领域,它涉及到计算机科学、电子工程、数学等多个学科的知识。 云计算与大数据:数据集、包括云计算平台、大数据...

    jsencrypt.min.js

    在web开发时,为了保障数据的传输安全,需要在前端加密数据,可以使用此JS,此JS为RSA加密,支持IE8,亲测有效;不支持分段加密。

    服务器安全技术详解.pptx

    信息泄露威胁消减措施(1/2):协议安全 基础安全强制规范 WEB安全开发规范 Apache加固规范 OS系统加固规范 安全加固规范 我们禁用 我们选择 Telnet(明文传输) SSH(加密传输) FTP(明文传输) SFTP(加密传输) ...

    openssl-1.0.0a

    数据的保密性 信息加密就是把明码的输入文件用加密算法转换成加密的文件以实现数据的保密。加密的过程需要用到密钥来加密数据然后再解密。没有了密钥,就无法解开加密的数据。数据加密之后,只有密钥要用一个安全的...

    物联网安全_实验9 信息保密性、完整性和不可抵赖性的综合应用.doc

    当PGP用RSA算法为用户生成一个新的公钥/私钥对时,PGP会要求用户提供一个口令短语,对该短语使用MD5/SHA-1消息摘要算法生成一个散列码后,销毁该短语,从而把用户输入的口令短语转化为IDEA/CAST-128密钥,再使用这个...

    详解使用JWT实现单点登录(完全跨域方案)

    JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。 虽然JWT可以加密以在各方之间提供保密,但只将专注于签名令牌。签名令牌可以验证其中包含的声明的完整性,而加密令牌则隐藏其他方的声明...

    java源码包---java 源码 大量 实例

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    java源码包2

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    Python中SOAP项目的介绍及其在web开发中的应用

    没有 Web 服务描述语言(Web Services Description Language,WSDL)或者任何其它附加的东西,只有用 Python 实现的 SOAP 客户机和服务器的透明支持。甚至这个包中的一个很好的功能也只是与基础架构相关:SOAP.py ...

Global site tag (gtag.js) - Google Analytics