JavaScript基础教程之Web应用中保证密码传输安全
沉沙 2019-07-18 来源 : 阅读 791 评论 0

摘要:本篇文章探讨了JavaScript基础教程之Web应用中保证密码传输安全,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

本篇文章探讨了JavaScript基础教程之Web应用中保证密码传输安全,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

JavaScript基础教程之Web应用中保证密码传输安全

"

  去年写过一篇文章,使用HMAC的加密算法保证了在登录时的密码安全。虽然没看到有人质疑,但这里至少会引出一个问题:登录过程不需要将密码原文提交到服务器,但注册和修改密码这两个需要将密码原文提交到服务器的过程怎么办?

  解决这一问题最佳方案当然是使用非对称加密。简单的说,非对称加密算法需要两个密钥,分别称为公钥和私钥,其中公钥会被公布出来,而私钥由个了保管(就像保管自己的密码一样)。使用公钥加密的数据是不能用公钥解密的,只能由私钥来解密。如果将私钥保存在服务器,把公钥发送给浏览器对密码原文进行加密,那么加密后的数据在传输过程中是安全的,因为私钥始终不会出现在传输过程,这个加密数据就不能轻松的解开。关于非对称加密的知识,学霸们请去各种百科上搜索,这里就不多说了。

  目前最常用的非对称加密算法是RSA算法,在服务器端.NET、Java都支持,PHP也有组件支持。在浏览器端,也有JavaScript的RSA算法包——用Google搜索“javascript rsa”第一个结果就是“RSA In JavaScript - ohdave.com”,该网站提供了三个JS文件,BitInt.js、Barrett.js和RSA.js,这三个JS文件要在见面中按顺序引用。

  下面就以C#和JavaScript为例说明一下加密传输密码和后台解密的过程。

  当然第一步是要产生公钥和私钥,自己用C#写个小小的控制台程序或者Windows程序就能解决这个问题,顺便熟悉一下C#的RSA。顺便说一下,维基百科提到,要保证安全至少得使用1024位的Key,.NET的RSA支持384到2048位的Key,这里就以1024位为例吧,下面的程序会在执行目录输出一个key.xml文件,保存了产生的公钥和私钥

[STAThread]static void Main(string[] args){
    string keyFileName        = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,            ""key.xml"";    const int keySize = 1024;    // 这个类在System.Security.Cryptography命名空间中
    RSACryptoServiceProvider sp = new RSACryptoServiceProvider(keySize);    // 参数true表示XML中包含私钥。如果给false表示只生成公钥的XML
    string str = sp.ToXmlString(true);
    using (TextWriter writer = new StreamWriter(keyFileName)) {
        writer.Write(str);    }}

  打开生成的key.xml可以看到,这个Key值包含了如下几个部分:Modulus、Exponent、P、Q、DP、DQ、InverseQ、D。这几个部分的值都是以Base64编码保存的。其中,Modulus和Exponent就是组成公钥的部分,也就是需要传递给浏览器,简称M和E,用于加密的两个数值。

  生成key.xml之后,有两种方式使用,一种是在使用时从XML文件导入;另一种方式是把这几个值提取出来写在某个类中。导入XML需要先将XML文本读取到一个string中,再用RSACryptoServiceProvider的实例方法FromXmlString(string)导入。因为需要向浏览器提供M和E,所以还要把这两个值提取出来

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();rsa.FromXmlString(xmlString);RSAParameters rsap = rsa.ExportParameters(false);//下面就是需要的两个值//rsap.Exponent//rsap.Modulus

  如果嫌每次载入费事,可以这样(其中所有字符串常量都是从key.xml中拷贝过来的)

private static readonly RSAParameters rsap = new RSAParameters{
    Modulus = Convert.FromBase64String(@""uQlRZvfH6MMdhNRgiAlKMY88dqsU2suKNIWbHY/FiTsvDgH5DLmNmGMp85qtQwSPhBQ+/E7DQkvk1OxIN7EBL+21NRPJIaDKuJciWC940ZFVU0d5oUujKy5uCrF/rfZce8MXjoiErtc+QRjCKI8wfGdIKuclooEPiJwb1rydMuE=""),
    Exponent = Convert.FromBase64String(@""AQAB""),
    P = Convert.FromBase64String(@""wSwI9i+aM6h7hayvFD01iINAeZ9JK5qExBJAWDzjOQwWRE9x1dCX52jb+HrutwblfqQuOk6hazOmGTluxITXQw==""),
    Q = Convert.FromBase64String(@""9TfkbPTexGpQ9ZHNjYnmRJLcG8wG6yzzJ/RrWIjq1IKQYMhYDq08bNbUVuXlntKW9GgmEYnuhP8smrH5y+mRCw==""),
    DP = Convert.FromBase64String(@""s2Xx7LDIxLD0BnEZJ/KwhNdgSZNkoNof8vgASfJCE/jltQsS7T+L053OrDV+/PuqprJTPFNKFgUhfMuZ02iLgQ==""),
    DQ = Convert.FromBase64String(@""5IfLXXO0LI78lm/khlUPAbdwZIN3qzMABat3Y1Jur9BiZ6Au2LbASprH15h3r9WJE4wAdnX6kX4SfrUBHPW20w==""),
    InverseQ = Convert.FromBase64String(@""FhlNb2WkipUaXvuwDxEWPeE754+qM2F5otEUP9clG91yaerdsBpBmU0G6S2AqUNjr/qgfpQyl1EW2dl10rmTpw==""),
    D = Convert.FromBase64String(@""WjhPXv/Qks7T7UiqGppA+UIoToojPH1C0VIVrEfGHp/jVRakKs6sWhF7yoHwGf22xkUi4t26efBMTn84xSLCexjQwj5AQtYk+3Qr2QjRDdn2ooIV1gWKW/C0O0+80Y6PEeszItuBVfjKC6mNEcZ1g44/wOdvIG7Olsl0F7vmQrM="")};

  将E和M传递给浏览器的方式,最直接就是写在HTML里,我个人比较喜欢把一些小数据写在<HEAD>标签的属性中,就像这样:<HEAD M=""..."" E=""..."">。C#代码也很简单:

Header.Attributes[""M""] = rsap.Modulus.HexEncode();Header.Attributes[""E""] = rsap.Exponent.HexEncode();

  这里用到了一个byte[]的扩展方法HexEncode,即将byte[]转换为16进制字符串的方法,它最简单(但不一定是最快)的实现方法是

public static string HexEncode(this byte[] me){    return BitConverter.ToString(me).Replace(""-"", string.Empty);}

  现在是浏览器端的加密过程,引入需要的JS文件先:

<script type=""text/javascript"" src=""js/BigInt.js""></script><script type=""text/javascript"" src=""js/Barrett.js""></script><script type=""text/javascript"" src=""js/RSA.js""></script><script type=""text/javascript"" src=""js/jquery-2.1.0.js""></script>

  然后在加密密码之前当然要先得到RSAKeyPair对象,这个对象的构造函数定义在RSA.js中。不过在new RSAKeyPair之前,必须先调用setMaxDigits()函数,原因在BigInt.js中有说明,setMaxDigits()的参数值根据选用的RSA的Key大小不同,如果计算我不太清楚,不过按ohdave.com的示例(下载页面的源码就是示例),1024位的Key,应该设置setMaxDigits(130);如果是2048位的则应该设置为260。所以产生RSAKeyPair对象的代码应该是这样:

$(function() {    var key = (function() {        var m = $(""head"").attr(""M"");        var e = $(""head"").attr(""E"");        setMaxDigits(130);        // 第一个参数是加密因子,第二个参数是解密因子        // 因为浏览器端不需要解密,所以第二个参数传入空字符串        return new RSAKeyPair(e, """", m);    })();})

  在提交数据之前对密码进行加密

var encryptedPass = encryptedString(key, $(""#password"").val());

  提交到后台之后,C#解密的过程

string hex = Request[""encrypted_pass""]byte[] data = hex.HexDecode();RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();// 前面定义的private static readonly RSAParameter rsap = ...rsa.ImportParameters(rsap);byte[] source = rsa.Decrypt(data, false);string password = Encodnig.ASCII.GetString(source);

  密码原文得到,剩下的事情就好说了,当然是保存密码,记得先使用HMAC算法加密哦。后面有示例下载。

"      本文由职坐标整理发布,学习更多的相关知识,请关注职坐标IT知识库!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程