样本代码:一次性密码(OTP)演示

下载 PDF 文档

下载源代码

Peng Wang,软件应用工程师

应用来源:
英特尔软件和解决方案事业部 (SSG)

引言

双重身份验证通常采用一次性密码 (OTP),将用户了解的某些信息(用户名和密码)和用户拥有的某些设备(通常是能按需生成仅短期有效的六位数令牌或密钥卡)相结合。

如果您的企业已在使用双重身份验证,那么您对令牌可用性和逻辑的相关问题就不会感到陌生。 更换丢失或损坏的令牌和用户错误输入一次性密码是目前服务台和 IT 部门遇到的两大头疼问题。 采用 OTP 的英特尔® 身份保护技术(英特尔® IPT)是一种内置硬件令牌(您可以任意选择安全厂商),无需单独的物理令牌,从而简化了双重 VPN 登录流程,实现了几乎无延迟的无缝体验。

本文高度概括了一次性密码 (OTP) 功能并展示了如何在 Android* 中使用 OTP API。

代码及介绍

OTP 具有三大功能: OTP 配置、OTP 生成和 OTP 验证。  系统还配置了 API,用于查询 OTP 功能和 OTP 版本。

OTP 配置

InvokeIPTProv 扩展了 AsyncTask,从而在后台执行配置。 它首先构建了安全服务(配置服务),然后开始进行配置。

@Override
protected Void doInBackground(Void... params) {
	ChaabiProvision prov = new ChaabiProvision();
	try {
		prov.execute().get(PROV_MAX_TIMEOUT, TimeUnit.MILLISECONDS);
	} catch (InterruptedException e) {
		error = "Provisioning failed: " + e.getClass().getName() + ": "
				+ e.getLocalizedMessage();
		e.printStackTrace();
	} catch (ExecutionException e) {
		error = "Provisioning failed: " + e.getClass().getName() + ": "
				+ e.getLocalizedMessage();
		e.printStackTrace();
	} catch (TimeoutException e) {
		error = "Provisioning failed: " + e.getClass().getName() + ": "
				+ e.getLocalizedMessage();
		e.printStackTrace();
	}
	return null;
}

OTP 生成  

在开始生成 OTP 之前,我们需要检查设备是否已顺利完成配置流程。

// Read token if exists
if (!readData()) {
	tvOTPGenerate
			.setText("OTP generation failed: No token exists. Please do provisioning.");
	return;
}

然后,我们就可以调用异步调用生成 OTP。

boolean invokeResyncGenerateOTP(IPTWrapper obj) {
	try {
		// Send request to the server for resync message and process
		// the received resync message
		InvokeIPTResync ipt_obj = new InvokeIPTResync();
		boolean status = ipt_obj.execute().get();
		if (status) {

			// Processes the server resync message
			obj.ProcessResyncMessage(encrToken_b64, serverResyncMessage);

			// Invoke OTP generation again
			// Check if token is of type OCRA
			if (tokenInfo
					.equalsIgnoreCase(OTPDemoActivity.OCRA_TOKEN_INFO)) {
				invokeGenerateOTP(obj, true);
			} else {
				invokeGenerateOTP(obj, false);
			}
			displayOTP();
			progressDialog.dismiss();
		} else {
			String error = "Receive server resync message failed.";
			tvOTPGenerate.setText(error);
			progressDialog.dismiss();
			OTPDemoActivity.OTP = null;
			return false;
		}
	} catch (IhaException e) {
		String error = "OTP generation failed. Message: "
				+ e.getLocalizedMessage() + " Error code: " + e.GetError();
		tvOTPGenerate.setText(error);
		progressDialog.dismiss();
		OTPDemoActivity.OTP = null;
		return false;
	} catch (Exception e) {
		String error = "OTP generation failed: " + e.getClass().getName()
				+ ": " + e.getLocalizedMessage();
		tvOTPGenerate.setText(error);
		progressDialog.dismiss();
		OTPDemoActivity.OTP = null;
		return false;
	}
	return true;
}

OTP 验证

OTP 生成后,我们就可以验证它是否有效。

	ChaabiOTPVerify otp_ver = new ChaabiOTPVerify();
	try {
		otp_ver.execute()
				.get(OTP_VERIFY_TIMEOUT, TimeUnit.MILLISECONDS);
	} catch (InterruptedException e) {
		error = "OTP verification failed: " + e.getClass().getName()
				+ ": " + e.getLocalizedMessage();
		e.printStackTrace();
	} catch (ExecutionException e) {
		error = "OTP verification failed: " + e.getClass().getName()
				+ ": " + e.getLocalizedMessage();
		e.printStackTrace();
	} catch (TimeoutException e) {
		error = "OTP verification failed: " + e.getClass().getName()
				+ ": " + e.getLocalizedMessage();
		e.printStackTrace();
	}
	return null;	} catch (JSONException e) {
		error = e.getClass().getName() + ": " + e.getLocalizedMessage();
		status = false;
		e.printStackTrace();
	} catch (UnsupportedEncodingException e) {
		error = e.getClass().getName() + ": " + e.getLocalizedMessage();
		status = false;
		e.printStackTrace();
	} catch (ClientProtocolException e) {
		error = e.getClass().getName() + ": " + e.getLocalizedMessage();
		status = false;
		e.printStackTrace();
	} catch (IOException e) {
		error = e.getClass().getName() + ": " + e.getLocalizedMessage();
		status = false;
		e.printStackTrace();
	}
	Log.v(LOG_TAG, "Return results: " + status);
	return status;
}

查询 OTP 功能

基于硬件的内置 OTP 并不适用于所有移动设备,所以首先查询系统是否支持 OTP 功能非常有帮助。

private boolean isOTPCapable(){
	try {
		IPTWrapper caps = new IPTWrapper();
		String cap = caps.GetCapabilities();
		displayMessage("Capabilities: " + cap);
		return true; 
	} catch (IhaException e) {
		String error = "GetCapabilities() failed. Message: "
				+ e.getLocalizedMessage() + " Error code: "
				+ e.GetError();
		notifyUser("Failed: " + error);
		return false;
	} catch (Exception e) {
		String error = "GetCapabilities() failed: "
				+ e.getClass().getName() + ": "
				+ e.getLocalizedMessage();
		notifyUser("Failed: " + error);
		return false;
	}
}

结论

您可以根据本文介绍的样本来执行代码,这样就能快速了解如何通过 Intel® IPT 和一次性密码 API,在运行 Android 的英特尔® 处理器平台上充分利用基于硬件的 OTP。

作者介绍

Peng Wang 是英特尔软件和解决方案事业部 (SSG)、开发人员关系部门、英特尔® 凌动™ 处理器高接触性软件支持团队的一员。 加盟 SSG 之前,Peng 负责领导超便携式产品事业部的集成和验证团队。 

 

声明

本文件中包含关于英特尔产品的信息。 本文件不构成对任何知识产权的授权,包括明示的、暗示的,也无论是基于禁止反言的原则或其他。 除英特尔产品销售的条款和条件规定的责任外,英特尔不承担任何其他责任。英特尔在此作出免责声明:本文件不构成英特尔关于其产品的使用和/或销售的任何明示或暗示的保证,包括不就其产品的(i)对某一特定用途的适用性、(ii)适销性以及(iii)对任何专利、版权或其他知识产权的侵害的承担任何责任或作出任何担保。

除非经过英特尔的书面同意认可,英特尔的产品无意被设计用于或被用于以下应用:即在这样的应用中可因英特尔产品的故障而导致人身伤亡。


英特尔有权随时更改产品的规格和描述而毋需发出通知。 设计者不应信赖任何英特产品所不具有的特性,设计者亦不应信赖任何标有“保留权利”或“未定义”说明或特性描述。 对此,英特尔保留将来对其进行定义的权利,同时,英特尔不应为因其日后更改该等说明或特性描述而产生的冲突和不相容承担任何责任。 此处提供的信息可随时改变而毋需通知。 请勿根据本文件提供的信息完成一项产品设计。

本文件所描述的产品可能包含使其与宣称的规格不符的设计缺陷或失误。 这些缺陷或失误已收录于勘误表中,可索取获得。

在发出订单之前,请联系当地的英特尔营业部或分销商以获取最新的产品规格。

索取本文件中或英特尔的其他材料中提的、包含订单号的文件的复印件,可拨打1-800-548-4725,或登录 http://www.intel.com/design/literature.htm

在性能检测过程中涉及的软件及其性能只有在英特尔微处理器的架构下方能得到优化。 诸如 SYSmark 和 MobileMark 等测试均系基于特定计算机系统、硬件、软件、操作系统及功能, 上述任何要素的变动都有可能导致测试结果的变化。 请参考其他信息及性能测试(包括结合其他产品使用时的运行性能)以对目标产品进行全面评估。

对本文件中包含的软件源代码的提供均依据相关软件许可而做出,任何对该等源代码的使用和复制均应按照相关软件许可的条款执行。

英特尔、Intel 标识、Atom 和凌动是英特尔在美国和/或其他国家的商标。

英特尔公司 © 2014 年版权所有。 所有权保留。

*其他的名称和品牌可能是其他所有者的资产。

有关编译器优化的更完整信息,请参阅优化通知