接口安全性知识面很广,我只是写下冰上一角,只是从java开发层面去写一点自己的理解
写这篇文档的缘由还要从我上家公司说起,离职后接到第一家公司的面试电话,简单的电话沟通后留下了面试的地点和时间,觉得这家公司还可以就去了,跑了很远的路程到了自己很想进的这家公司,面试的细节我记的不是很清楚了,已经大概有一年多了,现在能记得的就是跟标题有关系的这个面试问题.
我说我主要做的提供接口,面试官问我你们是怎么保证接口的安全性的,我说我们接口就是加上用户的id,通过用户id来判断用户的,其实我这样的回答,现在想想其实也没有回答啥,可能我当时用户id这个也没有说吧,记得不清楚了(后来就没有后来了),在上家公司主要做的是提供接口给Android端,接口字段传用户id,其他的也没有做安全性考虑,小公司做的是水利方便,对接口的安全性方面也没有太高的要求,目前自己做的主要是支付,所以对接口的安全性有一定的要求,所以现在记录下自己理解的几点分两种:
第一种:支付系统项目中在用的处理方式:
1:加密
1.1:项目中是独立的支付系统,对外我们提供的接口都是加密,所以请求和返回都需要对参数进行加密,对外系统我们提供公钥和私钥,公钥解密,私钥加密,对于不同的系统公私钥是不同的(公司目前的项目是对所有的参数都进行加密),
2:解密
2.1:验签的目的,我的理解是在网络传输的过程中会被截取和修改,接受到对方的结果后,进行验签目的调撤销(支付系统),不同的系统可能有不同处理方式,需要根据具体的业务来处理.
//支付中台
//公钥验签, 私钥解密 用公钥加密 私钥加签
//商户系统
//公钥加密 私钥加签 公钥验签 私钥解密
第二种:支付宝,中行 ,工行第三方的处理方式
3:加签
3.1:将请求的报本本地+部分字段加密 组装请求对象,对方拿到后以约定好的字段和加密方式进行加密,然后和传过去的加密字段相比较,是否相等,相等则验签成功,否则失败
4:验签
4.1:将响应的报文本地+部分字段加密 组装响应对象,接收到后以同样的方式进行验签
这个过程中我写的都是些流程,里面的一些细节处理没有写上去,有不理解的可以留言,有时间会给回复.希望给大家面试的时候问道的时候有的说,知道思路!
请求:公钥验签,私钥解密
返回:公钥加密 私钥加签
注:公钥加密 私钥解密,我之前一直不理解这两个,分不清! 公钥验签 私钥 加签 公钥大家随便拿,但是私钥不能随便透露。
生产公私钥 ,单向的 ,调用方 和被调用方用的是相同的公私钥
public String generateBizSecurityKeys(){
LOGGER.info("generateBizSecurityKeys");
Map keysMap = new HashMap<>();
try {
// 获取当前系统换行符
String lineSeparator = System.getProperty("line.separator");
// 生成RSA的公钥、私钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
String privateKey = new BASE64Encoder().encodeBuffer(keyPair.getPrivate().getEncoded());
String publicKey = new BASE64Encoder().encodeBuffer(keyPair.getPublic().getEncoded());
// 替换掉换行符
privateKey = StringUtils.replace(privateKey, lineSeparator, StringUtils.EMPTY);
publicKey = StringUtils.replace(publicKey, lineSeparator, StringUtils.EMPTY);
// 放入结果集合
keysMap.put("privateKey", privateKey);
keysMap.put("publicKey", publicKey);
keysMap.put("success", "true");
} catch (Exception e) {
LOGGER.logException(e);
LOGGER.warn("生成密钥异常:", e);
LOGGER.logException(e);
keysMap.put("success", "false");
}
// 转为Json以便返回前端
String resJson = JsonUtil.objectToJson(keysMap);
LOGGER.info(resJson);
return resJson;
}