【IT168 技术】随着互联网日益庞大,账号密码成为用户唯一的遮羞布,随着CSDN事件发生,这块遮羞布也变得透明,其实CSDN账号泄露仅仅是一个表现,账号安全早已经存在,黑客们手上多多少少都有一批账号,不论是攻击所获还是黑客之间分享。
再随着智能手机的发展,APP下载量的提高,互联网业务也在移动网络间壮大,但账号安全问题依然存在。
二次验证成为直接解决方案
一线安全的失守使互联网公司不得不建立第二道防线,这道防线拥有比密码更强、更安全的、更严谨的校验手段,如采用OTP、密保卡、密保问题、证书等等。于是各大互联网纷纷推出了二次验证服务,如腾讯、GOOGLE、淘宝等等,但这也同时带来了二个问题:
• 用户体验问题:凡是安全校验产品往往都存在用户体验问题,需要用户主动或被动的提供校验凭据才能信任用户。如果提供手段需要用户操作那无疑加大了用户操作负担,从而导致用户体验下降。
• 无线端支持问题:无线操作系统的不一致性对某些安全产品无法支持,或操作习惯不一致导致操作复杂(比如校验短信发送在手机,而自己需要登录手机应用,则必须先推出应用去看手机短信,再回过头来完成校验)
这些问题使二次验证在无线端无从下手。
隐形的校验
安全产品分为几个层次,即用户可知的、用户拥有的和用户自身的。用户可知的就是密码、密保问题等、用户拥有类似证书、OTP产品,而用户自身的便是生物特征等。安全级别也随层次增高而加强。
但实际上还存在一个可利用的环节,利用社会工程学可以明确,现在互联网用户存在习惯,而习惯带来的将会是行为规则。而这些规则完全可以利用起来,变成小伤用户体验的校验方式。
例如:用户时常登录互联网的IP,当发现用户登录IP时常为此IP,基本上可以认为没有异常,但突然某次IP不一致,视为威胁存在,然后再采用强校验或对用户身份进行识别来保证用户账号的安全性。
这样的校验方式的好处就是对于用户来说是透明的,而且有利于互联网公司对用户习惯行为进行一个预知,也有利于业务拓展。但这样的校验也存在缺陷,用户行为不可知(比如上例中IP作为校验凭据,但用户很有可能旅游,导致IP确实有变动)所以行为规则作为校验必须有补充,即二次验证还是需要存在,同时必须加强行为规则的校验凭据的强度和灵活度(不采用IP,采用MAC或键盘输入频率等等)
什么是XPS
xps是一种混合性定位服务,它拥有比GPS更精准的功能。其原理是及其能定位的条件与一身来做到精准判断手机位置,比如IP、WI-FI、基站信息等。这样的服务拥有多个组成成分,那么意味着是多样的校验凭据,从安全角度理解,多粒度的校验是较安全的,那么XPS就是满足者。
为什么要XPS,GPS或IP不能做到吗?其实问题很简单,如果了解过移动通信的童鞋就很明白,流量型网络出口IP可能是一个,Wi-FI用的是网关IP,在国内宽带IP没有规范型(运营商可能将宽带业务作为专线铺盖,而没有一个标准维护的IP地理位置库),而天然的手机终端设备信息正在被弱化(IOS5开始不提供唯一标示等)
不是新技术但是有条件:
XPS并不是什么新技术,而是集合了各种已有技术互补缺陷而维稳。简单的写些获取信息代码:
Android get Gps
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
代码段
private void getLocation()
{
// 获取位置管理服务
LocationManager locationManager;
String serviceName = Context.LOCATION_SERVICE;
locationManager = (LocationManager) this.getSystemService(serviceName);
// 查找到服务信息
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE); // 高精度
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW); // 低功耗
String provider = locationManager.getBestProvider(criteria, true); // 获取GPS信息
Location location = locationManager.getLastKnownLocation(provider); // 通过GPS获取位置
double latitude = location.getLatitude();
double longitude= location.getLongitude();
tv1.setText("维度:" + latitude+ "\n经度" + longitude);
// 设置监听器,自动更新的最小时间为间隔N秒(1秒为1*1000,这样写主要为了方便)或最小位移变化超过N米
locationManager.requestLocationUpdates(provider, 100 * 1000, 500,
locationListener);
}
Android get Cells
用的是Rexsee的基站定位(RexseeCellLocation对象)。示例代码如下,其中cid 和 lac 为经纬度。
import rexsee.core.browser.JavascriptInterface;
import rexsee.core.browser.RexseeBrowser;
import android.content.Context;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
public class RexseeCellLocation implements JavascriptInterface {
private static final String INTERFACE_NAME = "CellLocation";
@Override
public String getInterfaceName() {
return mBrowser.application.resources.prefix + INTERFACE_NAME;
}
@Override
public JavascriptInterface getInheritInterface(RexseeBrowser childBrowser) {
return this;
}
@Override
public JavascriptInterface getNewInterface(RexseeBrowser childBrowser) {
return new RexseeCellLocation(childBrowser);
}
public static final String EVENT_ONCELLLOCATIONCHANGED = "onCellLocationChanged";
public final Context mContext;
private final RexseeBrowser mBrowser;
private final int mPhoneType;
private PhoneStateListener mListener = null;
private CellLocation mLocation = null;
public RexseeCellLocation(RexseeBrowser browser) {
mContext = browser.getContext();
mBrowser = browser;
browser.eventList.add(EVENT_ONCELLLOCATIONCHANGED);
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
mPhoneType = tm.getPhoneType();
}
//JavaScript Interface
public boolean isEnabled() {
return mListener != null;
}
public boolean enable() {
try {
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
mListener = new PhoneStateListener() {
@Override
public void onCellLocationChanged(CellLocation location) {
mLocation = location;
mBrowser.eventList.run(EVENT_ONCELLLOCATIONCHANGED);
}
};
tm.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
return true;
} catch (Exception e) {
mBrowser.exception(getInterfaceName(), e);
return false;
}
}
public boolean disable() {
if (mListener == null) return true;
try {
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(mListener, PhoneStateListener.LISTEN_NONE);
mListener = null;
return true;
} catch (Exception e) {
mBrowser.exception(getInterfaceName(), e);
return false;
}
}
public String getLastKnownLocation() {
if (mLocation == null) return "{}";
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
String rtn = "";
rtn += "\"operator\":\"" + tm.getNetworkOperator() + "\"";
rtn += ",\"operatorName\":\"" + tm.getNetworkOperatorName() + "\"";
if (mPhoneType == TelephonyManager.PHONE_TYPE_GSM) {
GsmCellLocation gsm = (GsmCellLocation) mLocation;
rtn += ",\"type\":\"GSM\"";
rtn += ",\"cid\":" + gsm.getCid();
rtn += ",\"lac\":" + gsm.getLac();
} else if (mPhoneType == TelephonyManager.PHONE_TYPE_CDMA) {
CdmaCellLocation cdma = (CdmaCellLocation) mLocation;
rtn += ",\"type\":\"CDMA\"";
rtn += ",\"baseStationId\":" + cdma.getBaseStationId();
rtn += ",\"baseStationLatitude\":" + cdma.getBaseStationLatitude();
rtn += ",\"baseStationLongitude\":" + cdma.getBaseStationLongitude();
rtn += ",\"networkId\":" + cdma.getNetworkId();
rtn += ",\"systemId\":" + cdma.getSystemId();
}
return "{" + rtn + "}";
}
}
如何使用XPS
类似GPS基站信息,都需要我们去维护这个库,基站信息一把都把控在运营商手中作为盈利模式,所以维护基站信息是需要成本的,民间确实有些老库还能使用但不能所100%精准,但无妨因为XPS不仅仅依靠基站信息。而是结合了GPS+WPS+IP+基站等多个信息来判断用户手机位置,如果发现其中某些数据不对,可以降低其安全系数,如果安全系数非常低,就可以对这次校验请求进行进一步的确认,如弹出二次验证进行校验。