在Android中向USIM/SIM卡发送APDU命令

10

我已经使用过智能卡,熟悉在ISO/IEC 7816Global Platform规范中定义的APDU命令。

现在我想知道是否有办法向插入到我的手机中的USIM/SIM卡发送APDU命令?(我的手机是三星A3,安装了Android v4.4.4 kitkat系统。)

我已经在谷歌上搜索了一些相关主题和工具,例如SIM Toolkit ApplicationSeek for Android,但我不太理解这些是什么?这些是我必须在我的手机上安装的两个应用程序吗?还是这两个工具已经安装在USIM/SIM卡上,并从手机接收命令?

主动命令APDU命令AT命令之间有什么区别?

我是否需要学习Android开发SIM卡应用程序,还是只需了解Java Card规范和ETSI标准即可?

提前感谢。

2个回答

14

您的 SIM 卡上可能存在两种不同类型的小应用程序。

普通应用程序

普通应用程序以纯 JavaCard 编写。这是您从常见智能卡世界中所熟悉的应用程序类型。它有一个 process 方法,智能卡在通信中是被动主体:您的应用程序发送 APDU 命令,卡片响应。

您可以使用名为 SEEK for Android 的特殊 Android 库与这些应用程序通信。请参阅此教程,了解如何创建此类手机应用程序。

从 API 级别 21 开始,还可以通过电信管理器(Telephony Manager)与 SIM 卡通信。但是,有一个巨大的障碍:您的应用程序需要获得 MODIFY_PHONE_STATE 权限,该权限只能授予系统应用程序。普通的非系统应用程序不能使用它。

SIM 工具包应用程序

SIM 卡远不止是一张普通的智能卡,如果您想使用 SIM 卡提供的所有可能性编写 SIM 卡应用程序,这将比编写普通智能卡应用程序要复杂得多。我建议您阅读这篇论文 - 它是某人的毕业论文,但对于初学者来说是我在互联网上找到的最好的概述。我还建议观看DefConn 大会的这个视频

安装在 SIM 卡上的应用程序的作用是不同的:应用程序不再是被动实体。手机定期询问您的应用程序:“我可以为您做些什么吗?”您的应用程序可以回答:“是的,请发送此短信”或“请告诉我现在几点”等。此外,您的应用程序可以成为某些事件的侦听器:来电、收到的短信、经过的时间间隔等。是的,从技术角度来看,SIM 卡似乎是被动的,但它的角色实际上是积极的:它是向手机发送命令的 SIM 卡。

这些命令称为“主动命令”或 SIM 应用程序工具包命令。结构相同-CLA INS P1 P2 LC 数据 LE;意义不同。

您可以使用名为 sim.toolkit 的特殊 JavaCard 包中的类从您的应用程序发送它们。

(SIM 应用程序工具包是一种标准,它以与全球平台指定应用程序的生命周期相同的方式指定了主动命令。)

SIM 工具包应用程序示例:

import sim.toolkit.ToolkitInterface;
import sim.toolkit.ToolkitRegistry;
...
import javacard.framework.ISOException;

public class STKTest extends Applet implements ToolkitInterface {

public static void install(byte[] bArray, short bOffset, byte bLength) {
    // GP-compliant JavaCard applet registration
    new STKTest().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
}
//this method handles standard APDU commands
public void process(APDU apdu) {
    // Good practice: Return 9000 on SELECT
    if (selectingApplet()) {
        return;
    }

    apdu.setIncomingAndReceive();
    final byte[] buf = apdu.getBuffer();
    switch (buf[ISO7816.OFFSET_INS]) {
    case (byte) 0x00:
        //do something
        break;
    }
}
//this method handles the SIM Toolkit commands
public void processToolkit(byte event) throws ToolkitException {
    switch (event) {

    case ToolkitConstants.EVENT_TIMER_EXPIRATION:
        //do something
        break;
    }
}

}

是的,你应该学习Android - 这将帮助你使用SEEK库。你的问题非常广泛,如果需要任何详细信息,请随时向我提问。


感谢提供 SEEK 的链接。然而,根据我理解的文档,它需要运行一个修改过的 Android 构建,对吗?因此,我可以推断出原生 Android 缺乏这种低级 SIM 访问的机制(甚至可能主动阻止)吗? - user149408
@user149408 你好!不需要修改过的Android构建。你的应用程序需要使用特殊的SDK进行构建,并且供应商提供了一些特殊的库,仅此而已。例如,我成功地在标准的Sony Xperia L上使用了SEEK,没有进行任何额外的修改。 - vojta
@vojta 感谢你的澄清。与此同时,我发现Android的电话管理器现在也有发送命令到SIM卡的方法,但是它们需要API级别21(棒棒糖)或更高的版本。 - user149408
@user149408 哇,那很有趣!你能否请发一下你找到的链接吗?这样我就可以更新我的答案了。 - vojta
@vojta http://developer.android.com/reference/android/telephony/TelephonyManager.html#iccTransmitApduBasicChannel%28int,%20int,%20int,%20int,%20int,%20java.lang.String%29 - user149408
显示剩余8条评论

6
从API级别22(Android 5.1)开始,还有另一个选项称为“运营商特权”。它允许非系统应用程序使用Android TelephonyManager向SIM卡发送APDU。请参见: https://developer.android.com/reference/android/telephony/TelephonyManager.html#hasCarrierPrivileges() 例如,在Google Play上分发的移动网络运营商(MNO)应用程序可以使用此功能。但是,它并不对所有人开放。在这种情况下,您需要获得SIM卡的访问权限。SIM卡上的访问规则由发行它的MNO管理。请参见: http://source.android.com/devices/tech/config/uicc.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接