token,加密,签名
一、token
在网站、app与服务器交互的过程中,很多时候为了:
1、避免用户多次输入密码
2、实现自动登陆
3、避免在终端直接存储用户的密码
4、标示客户端的请求是否合法
5、其他(暂时没想到)
我们需要引入token机制,基于Token的验证流程一般是这样的:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 Token,这个Token是与用户名一一对应的,token一般可以存储在缓存或数据库中,以方便后面查询出来进行验证。再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
Token存在过期时间,在Token生成的时候可以打上一个时间戳,验证token的时候同时验证是否过期,并告知终端。终端接收到token过期的返回后,则要求用户重新输入用户名跟密码,进行登录。
用户的一些操作需要从新请求服务端下发token,如退出、修改密码后重新登录。
二、加密解密
在客户端与服务器进行交互时,必然涉及到交互的报文(或者通俗的讲,请求数据与返回数据),如果不希望报文进行明文传输,则需要进行报文的加密与解密。
所以加密的主要作用就是避免明文传输,就算被截获报文,截获方也不知道报文的具体内容。
三、签名
为什么要签名?
1、在客户端与服务器进行交互时,报文虽然加密了,但我们并不能确认这个报文是谁发过来的。例如,与第三方服务器B进行交互时,我方收到了一个已加密的请求,但我方并不能确认是服务器B发送的这个报文,此时我们可以用数字签名的方式来进行验证。
作用:认证数据来源
2、如果我方收到一个B服务器签名的请求,那么B服务器也无法否认这个请求,因为带有它的签名,作用:抗否认性。
3、我方收到一个B服务器签名的请求,但我方并不能确认这个请求是否被篡改过(虽然报文加了密,也可能被篡改),此时即可用签名,验证签名中的报文与传过来的报文是否一致。作用:保证了数据的完整性
遵循规则:公钥加密,私钥解密
总结:在实际开发工作中应该 先通过web filter 解密,解密后进行验证签名(返回数据时,过程反过来,先签名再加密);然后再springmvc的Interceptor 中进行验证token
RSA概要介绍
1976年以前,所有的加密方法都是同一种模式:
- 甲方选择某一种加密规则,对信息进行加密;
- 乙方使用同一种规则,对信息进行解密
由于加密和解密使用同样的规则(简称“秘钥”),这种被称为“对称加密算法”。这种加密模式有个最大的弱点:甲方必须把加密规则告诉乙方,否则无法解密。保存和传递秘钥成了最头疼的问题。1976年,两位美国计算机科学家Whitfield Diffie和Martin Hellman,提出了一种崭新的构思,可以在不直接传递秘钥完成加密,这个被称为”Diffie-Hellman密钥交换算法”。这个算法启发了其他科学家。人们认识到,加密和解密可以使用不同的规则,这要这种规则直接存在某种对应的关系即可,这样就避免了直接传递秘钥。这种新的加密模式被称为“非对称加密算法”:
- 乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
- 甲方获取乙方的公钥,然后用它对信息加密。
- 乙方得到加密后的信息,用私钥解密。
如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。
1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的”非对称加密算法”。毫不夸张地说,只要有计算机网络的地方,就有RSA算法。这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。
RSA签名过程
(1)client提取消息m的消息摘要h(m),并使用自己的私钥对摘要h(m)进行加密,生成签名s。
(2)client将签名s和消息m一起,使用server发过来的公钥进行加密,获得密文c,发送给server。
RSA验签过程
(1)server接受到密文后,用自己的私钥对其解密,获得明文消息m和签名s。
(2)server使用client的公钥解密数字签名s,获得消息摘要h(m)。
(3)server使用相同的方法提取消息m的消息摘要h(m)与上一步解密得到的h(m)进行比较,如果相同则验签成功。
使用openssl生成秘钥
windows环境的操作方法:
1. 工具下载:openssl工具
2. 双击运行bin目录下的openssl.exe
3. 生成RSA私钥命令:genrsa -out rsa_private_key.pem 1024
4. 生成RSA公钥命令:rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
5. 将RSA私钥转换成PKCS8格式:pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -out rsa_private_key_pkcs.txt -nocrypt
注意上面提供的测试代码私钥是基于pkcs8格式的。
数据摘要
数据摘要就是对数据源进行一个算法之后得到的一个摘要,也叫数据指纹,不同的数据源,摘要结果不一样。
数据摘要算法是一种能产生特殊输出格式的算法,其原理是根据一定的运算规则对原始数据进行某种信息的提取,被提取的信息称为原始数据的信息摘要。
常用的摘要算法有RSA公司的MD5算法和SHA-1算法以及其大量的变体。
数据摘要的特点:
1. 无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。例如应用MD5算法摘要的消息有128个比特位,用SHA-1算法摘要的消息最终有160比特位的输出。
2. 一般来说(不考虑碰撞的情况下),只要输入的原始数据不同,对其进行摘要以后产生的消息摘要也必不相同,即使原始数据稍有改变,输出的消息摘要便完全不同。但是,相同的输入必会产生相同的输出。
3. 具有不可逆性,即只能进行正向的信息摘要,而无法从摘要中恢复出任何的原始消息。
数据签名
大家知道要保证信息的可靠通信,必须要解决两个问题:一,确定消息的来源就是其申明的那个人;二,要保证数据在传输的过程中不被第三方篡改,即使篡改了也能发觉出来。
所谓书数字签名就是为了解决上述两个问题二产生,对非对称加密技术和数据摘要技术的一个具体应用。对消息发送者来说,首先要生成一对公私钥,将公钥发给消息接收者。
使用方法:
1. 消息发送者要给消息接收者发送消息,出了发送原始数据外,还需要发送原始数据的数字签名
2. 对消息接受者来说,它将收到两个数据,原始数据和签名数据,它需要判断这两个数据的合法信来确保通信的可靠,那么如何操作呢:
(1):对原始数据提取数据摘要,注意这里使用的消息摘要算法和发送方的一致;
(2):对附加的那段数字签名使用预先得到的公钥解密;
(3):比较前两步所得到的两段消息是否一致。如果一致,则表明消息是可靠的,否则消息在传输过程中一定出现了问题,消息不可信。
在加解密的代码中已经提供了签名和验签的操作,就不在阐述。使用过支付宝的SDK的朋友都知道,向支付宝接口提交订单信息是就需要对订单信息进行签名,支付宝为了确保订单信息的可靠性就使用了签名机制。
总结:
- 使用加解密为了保证数据的安全性,公钥加密私钥解密;私钥加密公钥解密。
- 签名机制是为了保证数据通信的可靠性,私钥签名公钥验签。