65.9K
CodeProject 正在变化。 阅读更多。
Home

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

2014年9月16日

CPOL

4分钟阅读

viewsIcon

22060

本文档旨在提供一次性密码 (OTP) 功能的概览,并展示如何在 Android* 中使用 OTP API。

引言

传统上,双因素身份验证使用一次性密码 (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;
}

然后我们可以调用 Async 调用来生成 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;
	}
}

结论

通过实施像本文档中描述的示例代码,您可以快速学习如何使用采用一次性密码 API 的英特尔® IPT,以在运行 Android 的基于英特尔®处理器的平台上使用基于硬件的 OTP。

作者简介

Peng Wang 是英特尔® 软件和解决方案集团 (SSG)、开发人员关系部门、英特尔® Atom™ 处理器 High Touch 软件支持团队的成员。在加入 SSG 之前,Peng 领导着 Ultra Mobile Group 的集成和验证团队。

注意事项

本文档中提供的有关英特尔产品的信息。 不通过本文档授予任何知识产权的明示或暗示许可,以禁止反言或其他方式授予。 除非在英特尔对此类产品的销售条款和条件中另有规定,否则英特尔不承担任何责任,并且英特尔不承担与销售和/或使用英特尔产品有关的任何明示或暗示的保证,包括与适用于特定用途、适销性或侵犯任何专利、版权或其他知识产权的责任或保证。

除非 Intel 书面同意,否则 Intel 产品不设计也不用于任何可能导致人员伤亡的应用程序。

英特尔可能会随时更改规范和产品描述,恕不另行通知。 设计人员不得依赖于任何标记为“保留”或“未定义”的特性或指令的缺失或特性。 英特尔保留这些用于未来定义,并且对因未来更改而引起的冲突或不兼容不承担任何责任。 此处的信息如有更改,恕不另行通知。 请勿使用此信息完成设计。

本文档中描述的产品可能包含已知为勘误的设计缺陷或错误,这可能导致产品偏离已发布的规范。当前的已表征勘误可应要求提供。

请联系您当地的英特尔销售办事处或您的经销商以获取最新的规范,并在下订单前进行咨询。

可以通过致电 1-800-548-4725 或访问以下网站获取具有订单编号并在本文档中引用或引用其他英特尔文献的文档副本:http://www.intel.com/design/literature.htm

性能测试中使用的软件和工作负载可能仅针对英特尔微处理器上的性能进行了优化。 性能测试(例如 SYSmark* 和 MobileMark*)是使用特定的计算机系统、组件、软件、操作和功能来测量的。 对这些因素的任何更改都可能导致结果有所不同。 您应该查阅其他信息和性能测试,以帮助您充分评估您计划购买的产品,包括该产品与其他产品组合时的性能。

本文档中重印的任何软件源代码均根据软件许可证提供,并且只能根据该许可证的条款使用或复制。

英特尔、英特尔徽标和 Atom 是英特尔公司在美国和/或其他国家/地区的商标。

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

*其他名称和品牌可能被声明为他人的财产。

© . All rights reserved.