app接口设计之安全性

1. 什么是接口
接口简单来说就是服务器端用来返回给其他程序或者客户端数据的桥梁
2. 接口的作用
根据固定参数返回固定数据
3. API接口保障安全性原则
1.有调用者身份
2.请求的唯一性
3.请求的参数不能被篡改
4.请求的有效时间
4. 接口安全需求
1.最好必须启用HTTPS
2.signature签名
3.token登陆的唯一票据
4.验证时间戳
5.对要求安全性高的接口数据进行加密传输(aes+rsa)
5. signature签名

简而言之,签名设计的原则就是保证服务器所接收到的数据是自己的APP端传过来的,而不是其他人非法调用的,在APP端给签名加密时需要加上特有固定参数,服务器也是加上特有固定参数,从而来保证一对一的传输,每个接口都需要调用该签名验证方法

目的:

为了提高传参过程中,防止参数被恶意修改,在请求接口的时候加上sign可以有效防止参数被篡改

基本例子:
#接口
https://www.dong.com/api/product?&type=zl&p1=value1&p2=value2&p3=&sign=signValue

#第一步:
拼接参数字符串,除去sign参数本身和为空值的p3,
那么剩下的就是字符串type=zl&p1=value1&p2=value2,
然后按参数名字符升(降)序,
得到字符串p1=value1&p2=value2&type=zl

#第二步:
然后将参数名和值的字符串进行AES加密,
假设p1=value1&p2=value2&type=zl进行AES加密后的结果是abc123,
最终得到的字符串abc123就是参数sign的值signValue

#第三步:
在接口中我们会接收到参数名sign的参数值abc123,然后解密,
再与接口中参数拼接排序后进行比较,
如果不一样则说明参数的循序不一样,
参数的值就一定是被修改过了。
高级例子:
基本例子因为前端js暴露,
很容易被攻击人获取AES的加密方式,
因而有效防止参数被篡改就变得很弱。

所以,我们何不在AES的加密key进行RSA加密。
第一步:
我们先在客户端要产生一个random string(很重要,不能是单纯的string)
对其进行RSA加密,然后把加密后的内容发送给后端,
第二步:
我们把random string跟传递的参数+(时间戳13位数)进行AES加密,发送给后端
第三步:
后端进行解密,判断是否有改变传递的参数,
以及超过时间限制就不让访问,对sign进行cache缓存,
缓存中存在sign的就不让访问

RSA:非对称加密算法,内容越大,解密时间越长
AES:对称加密算法
代码例子:
/**
 * [AesSecurity aes加密,支持PHP7.1]
 */
class AesSecurity
{
    /**
     * [encrypt aes加密]
     * @param    [type]                   $input [要加密的数据]
     * @param    [type]                   $key   [加密key]
     * @return   [type]                          [加密后的数据]
     */
    public static function encrypt($input, $key)
    {
        $data = openssl_encrypt($input, 'AES-128-ECB', $key, OPENSSL_RAW_DATA);
        $data = base64_encode($data);
        return $data;
    }
    /**
     * [decrypt aes解密]
     * @param    [type]                   $sStr [要解密的数据]
     * @param    [type]                   $sKey [加密key]
     * @return   [type]                         [解密后的数据]
     */
    public static function decrypt($sStr, $sKey)
    {
        $decrypted = openssl_decrypt(base64_decode($sStr), 'AES-128-ECB', $sKey, OPENSSL_RAW_DATA);
        return $decrypted;
    }
}

用openssl生成rsa密钥对(私钥/公钥):

openssl genrsa -out rsa_private_key.pem 2048
openssl rsa -pubout -in rsa_private_key.pem -out rsa_public_key.pem

RSA:

header('Content-Type: text/plain;charset=utf-8');
$data = 'phpbest';
echo '原始内容: '.$data."\n";

openssl_public_encrypt($data, $encrypted, file_get_contents(dirname(__FILE__).'/rsa_public_key.pem'));
echo '公钥加密: '.base64_encode($encrypted)."\n";

$encrypted = base64_decode('nMD7Yrx37U5AZRpXukingESUNYiSUHWThekrmRA0oD0=');
openssl_private_decrypt($encrypted, $decrypted, file_get_contents(dirname(__FILE__).'/rsa_private_key.pem'));
echo '私钥解密: '.$decrypted."\n";
6. token登陆的唯一票据
和PC登陆的session一样,作为用户进入的唯一票据

因为APP端没有和PC端一样的session机制,所以无法判断用户是否登陆,以及无法保持用户状态,所以就需要一种机制来实现session,这就是token的作用,token是用户登陆的唯一票据,只要APP传来的token和服务器端一致,就能证明你已经登陆
2、token设计时的种类:
(1)第三方登陆型:这种token形如微信的access_token,设计原理是按照OAuth2.0来的,其特点是定时刷新(比如两小时刷新),目的是因为数据源将登陆权限赋予第三方服务器时必须要控制其有效期和权限,要不然第三方服务器可以不经过用户同意,无限期从数据源服务器获取用户任意数据

(2)APP自用登陆型:这种token就是一般的APP用的token,因为不经过第三方,而是用户直接取数据源服务器数据,所以设计比较随意,只需要保证其token的唯一性就行

3、APP自用登陆型token实现步骤:
(1)数据库用户表添加token字段和time_out这个token过期时间点(不是时间段,即某个时间点)
(2)用户登陆时(注册时自动登陆也需要)生成一个token和过期时间存入表中
(3)在其他接口调用前,判断token是否正确,正确则继续,错误则让用户重新登陆

//token验证方法,db::是数据库操作类,
这里设置是token如果七天没被调用则需要重新登陆
(也就是说用户7天没有操作APP则需要重新登陆),
如果某个接口被调用,则会重新刷新过期时间
    public static function checktokens($token, $table)
    {
        $res = db::getOneForFields($table, 'time_out', 'token1 = ?', array($token));
        if (!empty($res))
        {
            if (time() - $res['time_out'] > 0) 
            {
                return 90003;  //token长时间未使用而过期,需重新登陆
            }
            $new_time_out = time() + 604800;//604800是七天
            if (db::setWhere($table, array('time_out' => $new_time_out), 'token1 = ?', array($token)))
            {
                return 90001; 
               //token验证成功,time_out刷新成功,可以获取接口信息
            }
        }
        return 90002;  //token错误验证失败
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容