保证接口安全一般分为两种,一个是防数据篡改,一个是防数据泄漏,防篡改使用摘要验证,防泄漏使用加密

token

token=5位随机数+时间戳

aesEnctrypt(token)

(1)验证时间和服务器时间不能超过3分。

(2)同一个时间戳,随机数只能使用一次。

对称加密

把参数对称加密 aes

签名验证

ras

调用方,要提供公钥,sign(通过双方定义好的算法把摘要和参数计算后的值)

我们把post过来的参数先解密,通过制定的算法算出sign

我们看我们算出sign与调用方传过来的sign是否一致,一致则可以进行业务处理,不一致返回签名失败。

sign算法

secretKey是双方定义的摘要

params是参数的hashmap集合

  1. byte[] data=Digest.getDigest(secretKey, params);
  2. public class Digest {
  3. public static byte[] getDigest(String secretKey, Map<String,String> params) throws Exception{
  4. Set<String> keySet = params.keySet();
  5. TreeSet<String> sortSet = new TreeSet<>();
  6. sortSet.addAll(keySet);
  7. String keyValueStr = "";
  8. Iterator<String> it = sortSet.iterator();
  9. while(it.hasNext()){
  10. String key = it.next();
  11. String value = params.get(key);
  12. keyValueStr += key + value;
  13. }
  14. keyValueStr = keyValueStr + secretKey;
  15. MessageDigest md = MessageDigest.getInstance("SHA-1");
  16. return md.digest(keyValueStr.getBytes("utf-8"));
  17. }
  18. }
  19. boolean b=RsaUtil.verify(data, sign, publicKeyString);

b=false 返回签名失败。

以下是rasutil

  1. /**
  2. *
  3. */
  4. package com.hlmedicals.app.util;
  5. import Java.io.UnsupportedEncodingException;
  6. import java.security.KeyFactory;
  7. import java.security.PrivateKey;
  8. import java.security.PublicKey;
  9. import java.security.spec.PKCS8EncodedKeySpec;
  10. import java.security.spec.X509EncodedKeySpec;
  11. import com.itextpdf.xmp.impl.Base64;
  12. /**
  13. * @author dell
  14. *
  15. */
  16. public class RsaUtil {
  17. public static void main (String [] args){
  18. try {
  19. byte[] privateKeyString= IConst.privateKeyString.getBytes("utf-8");
  20. byte[] publicKeyString= IConst.publicKeyString.getBytes("utf-8");
  21. String data1 = "testabc";
  22. //siyao签名
  23. byte[] data=data1.getBytes("utf-8");
  24. byte[] s = sign(data, privateKeyString);
  25. boolean b=verify(data,s,publicKeyString);
  26. System.out.println(b);
  27. } catch (Exception e) {
  28. // TODO Auto-generated catch block
  29. e.printStackTrace();
  30. }
  31. }
  32. /**
  33. * 使用私钥对数据进行加密签名
  34. * @param data 数据
  35. * @param privateKeyString 私钥
  36. * @return 加密后的签名
  37. */
  38. public static byte[] sign(byte[] data, byte[] privateKeyString) throws Exception {
  39. KeyFactory keyf = KeyFactory.getInstance("RSA");
  40. PrivateKey privateKey = keyf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(privateKeyString)));
  41. java.security.Signature signet = java.security.Signature.getInstance("SHA1withRSA");
  42. signet.initSign(privateKey);
  43. signet.update(data);
  44. byte[] signed = signet.sign();
  45. return Base64.encode(signed);
  46. }
  47. /**
  48. * 使用公钥判断签名是否与数据匹配
  49. * @param data 数据
  50. * @param sign 签名
  51. * @param publicKeyString 公钥
  52. * @return 是否篡改了数据
  53. */
  54. public static boolean verify(byte[] data, byte[] sign, byte[] publicKeyString) throws Exception {
  55. KeyFactory keyf = KeyFactory.getInstance("RSA");
  56. PublicKey publicKey = keyf.generatePublic(new X509EncodedKeySpec(Base64.decode(publicKeyString)));
  57. java.security.Signature signet = java.security.Signature.getInstance("SHA1withRSA");
  58. signet.initVerify(publicKey);
  59. signet.update(data);
  60. return signet.verify(Base64.decode(sign));
  61. }
  62. }

4.http 转成htts

5.后台登录要有验证码,没有验证码 ,系统会被爆破,验证码不能被多次使用。

我的项目登录成功后把验证码存在session里。要把session验证码设定为空就可以。

6.系统上传文件时候,应该上传白名单的文件类型,防止jsp、jspx在系统中执行导致系统崩掉。

在开发过程中,肯定会有和第三方或者app端的接口调用。在调用的时候,如何来保证非法链接或者恶意攻击呢?

签名

根据用户名或者用户id,结合用户的ip或者设备号,生成一个token。在请求后台,后台获取http的head中的token,校验是否合法(和数据库或者Redis中记录的是否一致,在登录或者初始化的时候,存入数据库/redis)

在使用Base64方式的编码后,Token字符串还是有20多位,有的时候还是嫌它长了。由于GUID本身就有128bit,在要求有良好的可读性的前提下,很难进一步改进了。那我们如何产生更短的字符串呢?还有一种方式就是较少Token的长度,不用GUID,而采用一定长度的随机数,例如64bit,再用Base64编码表示:

  1. var rnd = new Random();
  2. var tokenData = userIp+userId;
  3. rnd.NextBytes(tokenData);
  4. var token = Convert.ToBase64String(tokenData).TrimEnd('=');

由于这里只用了64bit,此时得到的字符串为Onh0h95n7nw的形式,长度要短一半。这样就方便携带多了。但是这种方式是没有唯一性保证的。不过用来作为身份认证的方式还是可以的(如网盘的提取码)。

加密

客户端和服务器都保存一个秘钥,每次传输都加密,服务端根据秘钥解密。

客户端:

​ 1、设置一个key(和服务器端相同)

​ 2、根据上述key对请求进行某种加密(加密必须是可逆的,以便服务器端解密)

​ 3、发送请求给服务器

服务器端:

​ 1、设置一个key

​ 2、根据上述的key对请求进行解密(校验成功就是「信任」的客户端发来的数据,否则拒绝响应)

​ 3、处理业务逻辑并产生结果

​ 4、将结果反馈给客户端

第三方支持

比如spring security-oauth

有兴趣的,可以参考这篇帖子

http://wwwcomy.iteye.com/blog/2230265

多数采用OAuth2,不过对于盗cookie没招,走HTTPS吧

api进行token校验或者签名,另外对于防刷,要进行限流

题主要看你如何定义接口安全了,我们可以看看新浪微博,每天无数的爬虫在爬,他的接口安全么?一般意义上安全指的是传输过程中不被盗取,走https基本可以做到,至于有人拿到api文档一类的东西(app被反向),那怎么样也防不了

所以如同楼上 1.对IP进行过滤,频繁访问的进行限制。 2.使用token令牌进行验证,通过后进行业务逻辑。 3.不对参数过渡暴露,传输的文本根据业务级别进行加密。

没有绝对的安全,题主可以看看微信开发者文档,看看他们的接口是怎么设计的

题主要看你如何定义接口安全了,我们可以看看新浪微博,每天无数的爬虫在爬,他的接口安全么?一般意义上安全指的是传输过程中不被盗取,走https基本可以做到,至于有人拿到api文档一类的东西(app被反向),那怎么样也防不了

所以如同楼上 1.对IP进行过滤,频繁访问的进行限制。 2.使用token令牌进行验证,通过后进行业务逻辑。 3.不对参数过渡暴露,传输的文本根据业务级别进行加密。

没有绝对的安全,题主可以看看微信开发者文档,看看他们的接口是怎么设计的