应该怎么做一个登录功能?
版权是我的,转载没有通过我的同意的爬虫都是傻逼.
假设有user表.里面有id,acount(账户,nvarchar(50)),pwd(密码,nvarchar(50)).
最简单的实现
渣渣说做个登录功能,那还不简单.
select * from user where acount=XX AND PWD =YY;
然而,某天,我们需要在登录的时候更新最后登录时间,也就是在user表里面加个lastLoginTime.
这时渣渣说
select id from user wher acount=XX AND PWD =YY;
update user set XXXX where id=@id;
然后就他就被打了.实际上,可以合为一句:
update user set XXXX where acount=XX AND PWD =YY;
受影响行数大于0表示登录成功.
密码的加密
某一天,渣渣看到某某数据库被下载了.想到自己的数据库如果泄露了怎么办,上面全是明文.
于是他就开始想加密这个事.
1MD5(同一个密码,MD5还是一样的,所以否决了)
2des(用于可逆密码加密解密,然而有些安全系数要求高的密码是不能被解密的,所以有适用范围)
3随机加盐HASH.
第三种方案,要加在原来的表加多一个salt列.
每一次的登录的话,
应该是select * from user wher acount=XX
然后把里面的盐加上输入的密码进行hash然后与数据库的加密后pwd进行比较.比如string.equal(MD(pwd+salt),pwd)
true当然就是说输入正确啦.
其实加密的方案我举的都只是最简单的例子.对于盐的把握,大家开脑洞自己想吧.
(比如可以对原密码进行md5,然后对于md5的每一个偶数位字符插入盐的一个字符,从而最后组成一个不明所以的字符串)
"无验证码登录"
我们为什么需要验证码呢?是为了防止被密码爆破.
那么是否可以无验证码登录呢?当然可以.
遍地开花的开放平台接口
比如支付宝,旺旺,qq,微博....
以qq为例.他的步骤无非就是,跳到一个指向自己应用的腾讯链接.用户在那上面授权给这个应用.授权后返回token和openid给网站.
做过微信第三方服务器的人就知道,这个token是用来以授权者的名义做各种操作的,实际上,对于登录,只要有这个openid,去数据库检索成功了,就应该视为登录有效.所以token其实没啥用.
可信状态下不需要验证码
固定的上网行为
我们应该怎么定义什么样的状态算作稳定?比如,我单个用户,连续10次的登录有9次都是在同一个ip上登录,那么这个ip的实际来源就应该视为可信的状态.
固定的上网行为其实还有很多种,比如登录的时间段众数,登录的频率,习惯使用的浏览器.只要你想的周全了,其实有很多用户细节可以捕捉.
不频繁的操作
我们相信这个世界的人大体都是美好的,所以你一看到我这个网站,要登录的时候我就需要你输入验证码,但如果你连续数次密码错误,那我就要怀疑你的人品,给你下套.具体的可以看新浪微博.
场景的变换
不明公共wifi
我们知道http 下,明文post上去的明文被截取了就能分分钟拿到信息.所以https就登场了.我post的密文就算给你看了,你也解密不了,耶~
然而这并没有卵用.https证书根据不同的级别收不同的钱.于是12306自己做了个证书,哈哈.如果你们有魄力教导用户安装自己做的证书,那就走这条路吧....
移动端(Android,iPhone)
这就是我最近遇到的一个比较蛋疼的问题.我们知道url有长度限制,并且参数还得(utf-8)编码.所以合适的做法应该是可解密的json密文作为http请求报文的body传上去.
然而.net环境的des默认工作模式是cbc,所以其他客户端也应该用cbc进行加密/解析.java的默认实现不是cbc,而且它的偏移向量每次都随机.所以加密的结果和c#不一样.
这里引用s站的说法,中文意思就是java的des是ecb而.NET的是cdc.工作模式不一样.并且,我发现一些java 的des实现是用随机向量的,所以变量不一致的话结果也会和.net的不一样.
SunJCE provider uses
ECB
as the default mode, andPKCS5Padding
as the default padding scheme for DES, DES-EDE and Blowfish ciphers. (JCA Doc)In
.Net
, The default operation mode for the symmetric algorithm isCipherMode.CBC
and default padding isPaddingMode.PKCS7
. (msdn..SymmetricAlgorithm)
/// <summary>/// DES加密字符串/// </summary>/// <param name="encryptString">待加密的字符串</param>/// <param name="key"></param>/// <returns>加密成功返回加密后的字符串,失败返回源串</returns>public static string DESEncrypt(this string encryptString, string key){try{if (key.Length < 8)throw new ArgumentException("密钥和向量必须为8位,否则加密解密都不成功", "key");byte[] rgbKey = Encoding.UTF8.GetBytes(key.Substring(0, 8));byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);using (var dCSP = new DESCryptoServiceProvider()){using (MemoryStream mStream = new MemoryStream()){using (var cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbKey), CryptoStreamMode.Write)){cStream.Write(inputByteArray, 0, inputByteArray.Length);cStream.FlushFinalBlock();cStream.Close();return Convert.ToBase64String(mStream.ToArray());}}}}catch{return encryptString;}}
这下面是哥用了2015年7月3日用了0.7个下午的时间研(抄)究(袭)出来的java加密代码
import java.util.HashMap; import java.util.Map;import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.SecretKeySpec;import java.security.InvalidAlgorithmParameterException; import java.security.Key; import java.security.Security;import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.IvParameterSpec;import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.KeySpec;import net.sf.json.JSONArray; import net.sf.json.JSONObject; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder;public static void main(String[] args) throws Exception {Map map = new HashMap(); map.put( "Msg", "哦" ); map.put( "Url", "oooo"); JSONObject jsonObject = JSONObject.fromObject( map ); String shit=jsonObject.toString();System.out.println(shit); System.out.println(encrypt(shit,"UTF8"));}public static String encrypt(String message,String encoding,String myKey) throws Exception { Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); DESKeySpec desKeySpec = new DESKeySpec(myKey.getBytes(encoding)); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); IvParameterSpec iv = new IvParameterSpec(myKey.getBytes(encoding)); cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); byte[] buf = cipher.doFinal(message.getBytes(encoding)); sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();String a = encoder.encode(buf);return a; }
这是哥移植到安卓的代码,只是最后的base64用了Android的类,其余无区别
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
public static String encrypt(String key, String message, String encoding) throws Exception {Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(encoding));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");SecretKey secretKey = keyFactory.generateSecret(desKeySpec);IvParameterSpec iv = new IvParameterSpec(key.getBytes(encoding));cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);byte[] buf = cipher.doFinal(message.getBytes(encoding));
return android.util.Base64.encodeToString(buf, android.util.Base64.DEFAULT);}
ios(object c)的我不知道,但是同事告诉我,转成的base64除了大小写有细微的差别外,没有其他问题(他们请求我的web api接口有正确的响应).
Android的,也许还能参考我的第一个参考链接.不过it does not work for me.
参考链接:
Android平台和java平台 DES加密解密互通程序及其不能互通的原因 .
C# and Java DES Encryption value are not identical
版权是我的,转载没有通过我的同意的爬虫都是傻逼.
转载于:https://www.cnblogs.com/zeusro/p/4619873.html
应该怎么做一个登录功能?相关推荐
- python做一个登录注册界面_python做一个登录注册界面的方法
python做一个登录注册界面的方法 发布时间:2020-08-21 10:37:05 来源:亿速云 阅读:111 作者:小新 这篇文章主要介绍python做一个登录注册界面的方法,文中介绍的非常详细 ...
- java多端登录_【Java】一个登录功能也能玩出这么多花样?sa-token带你轻松搞定多地登录、单地登录、同端互斥登录...
需求场景 说起登录,你可能会不屑一顾,还有比这更简单的功能吗? 获取一下用户提交参数 username + password 和数据库中一比对,有记录返回[登录成功],无记录返回[用户名或密码错误] ...
- python做一个登录注册界面_Python 实现简单的登录注册界面
Python 实现简单的登录注册界面 注意:编写代码之前需要导入很重要的包 import tkinter as tk import pickle from tkinter import message ...
- Python程序员找了个女朋友, 没有时间聊天? 做一个自动回复功能!还会怕没有女朋友吗?
本人已经从事了Python近9年,目前已经是一个全栈工程师,不怕本人出丑,程序员一般都是加班,特别是项目组,更是加班到四五更,但是有没有想过,在找了一个女朋友之后,不在女朋友身边,如何做到秒回女朋友的 ...
- vue中使用vuex结合sessionStorage做的登录功能
先说一波vuex的好处 vuex可以保存数组.对象.或者嵌套结构,不用toString 双向绑定,使用commit修改一处状态后,所有引用的地方自动更新,不需要重新取值 可以自定义数据过滤方法.取值方 ...
- python中字典的键是唯一的吗_Python怎么通过字典的键和值做一个登录程序?
杨魅力 LZ,登陆功能有两个子功能:注册与登陆,,初学版如下:dic = {}a = raw_input("Please input your name...")b = raw_i ...
- 使用reactjs做一个CRUD功能
第一步:引入reactjs所依赖的js文件,本案例使用的是bootstrap前端框架,所以引入了相应的js和css文件 第二步:body里面添加两个div 第三步:开始编写reactjs脚本 < ...
- 使用ionic2开发一个登录功能
2019独角兽企业重金招聘Python工程师标准>>> http://www.360doc.com/content/17/0223/13/16002580_631383544.sht ...
- QT使用SQLite数据库实现登录功能
QT实现用户登录功能(MySQL) https://blog.csdn.net/tianya_team/article/details/72566198 QT5中使用SQLite https://bl ...
最新文章
- 欧盟数据保护新规则 75%云应用没准备好
- NEFU 503 矩阵求解 (非01异或的高斯消元)
- golang 切片 接口_一日看尽golang高级语法之slice
- qt git linux 安装,git – 如何在Ubuntu上安装QtWebEngine
- mysql的快照速度_mysql 快照读 当前度
- 2019蓝桥杯省赛---java---C---2(矩阵切割)
- 又一起!北大副校长詹启敏院士被疑25篇论文造假
- Windows7无法访问(远程登录)Windows 2003共享问题解决
- Go36-3-代码包
- 华为或将推出“华为搜索”;​飞书回应微信指控;Fuchsia OS 进入开发者试用阶段 | 极客头条...
- SCCM报表点和SQL Server的报表服务集成, 随心所欲创建报表?
- Linux 下超级有趣的命令
- 使用Redis+AOP优化权限管理功能
- 整车CAN网络基本结构
- cad里面f命令用不了_cad命令_CAD命令中 F 命令是什么作用?
- mariadb mysql.sock_数据库缺少mysql.sock文件的解决办法
- 午间一乐:no zuo no die,唱起来
- Python对文件(外存)和内存的操作
- [iPhone]解决:手指按住不动时,屏幕也会上下抖动
- 一缕黑暗中的火光-----------部署图--------------优雅的建模语言
热门文章
- 《Linux内核设计与实现》读书笔记(六)- 内核数据结构
- CentOS 7升级gcc 8.3.1 7.x.x 4.9.4版本
- linux diff命令_Linux diff命令示例
- [BUUCTF-pwn]——ciscn_2019_n_3
- 如何编写配置文件 JAVA_SpringBoot 如何编写配置文件
- mysql bytessent_如何对DSQLSERVER、MySQL、Orache语句性能分析
- 在多个的共享ndk项目之间共享模块
- java 存储过程 数组参数_执行数组参数的存储过程
- 记录 spring 使用@Value获取properties文件中的属性值
- Vmware虚拟机中CentOS7与Docker安装图文教程