java-使用Samsung Galaxy S3为Android设置SEEK
作者:互联网
这里是一些背景一:
我正在尝试做一个概念验证的Android应用程序,该应用程序将检查是否可以向SIM卡小程序发送一些APDU命令并处理响应.
我使用SEEK for Android作为Open Mobile API的参考实现.
如here所述,该应用程序应可在带有Open Mobile API的Samsung Galaxy S3智能手机上运行.
我不允许使用自定义ROM,也不能对Android源代码进行任何修改.
到目前为止,我所做的是:
>我已下载带有Open Mobile API和Open Mobile API软件包的Android API lvl 18.
>我创建了一个示例应用程序,应尝试访问SIM卡上的applet,如here所述.
>在按钮上单击,我收到SecurityException
06-23 12:57:15.620: I/HelloSmartcard(5386): creating SEService object
06-23 12:57:15.655: I/SEService(5386): Connected
06-23 12:57:22.525: I/HelloSmartcard(5386): Retrieve available readers...
06-23 12:57:22.530: I/HelloSmartcard(5386): Create Session from the UICC reader...
06-23 12:57:23.275: I/HelloSmartcard(5386): Create logical channel within the session...
06-23 12:57:23.285: E/HelloSmartcard(5386): Error occured:
06-23 12:57:23.285: E/HelloSmartcard(5386): java.lang.SecurityException: Access Control Enforcer: access denied: EF_DIR not found!!
06-23 12:57:23.285: E/HelloSmartcard(5386): at org.simalliance.openmobileapi.SEService.checkForException(SEService.java:234)
06-23 12:57:23.285: E/HelloSmartcard(5386): at org.simalliance.openmobileapi.Session.openLogicalChannel(Session.java:302)
06-23 12:57:23.285: E/HelloSmartcard(5386): at com.example.testsmartcardaccess2.MainActivity$1.onClick(MainActivity.java:81)
06-23 12:57:23.285: E/HelloSmartcard(5386): at android.view.View.performClick(View.java:4475)
06-23 12:57:23.285: E/HelloSmartcard(5386): at android.view.View$PerformClick.run(View.java:18786)
06-23 12:57:23.285: E/HelloSmartcard(5386): at android.os.Handler.handleCallback(Handler.java:730)
06-23 12:57:23.285: E/HelloSmartcard(5386): at android.os.Handler.dispatchMessage(Handler.java:92)
06-23 12:57:23.285: E/HelloSmartcard(5386): at android.os.Looper.loop(Looper.java:176)
06-23 12:57:23.285: E/HelloSmartcard(5386): at android.app.ActivityThread.main(ActivityThread.java:5419)
06-23 12:57:23.285: E/HelloSmartcard(5386): at java.lang.reflect.Method.invokeNative(Native Method)
06-23 12:57:23.285: E/HelloSmartcard(5386): at java.lang.reflect.Method.invoke(Method.java:525)
06-23 12:57:23.285: E/HelloSmartcard(5386): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
06-23 12:57:23.285: E/HelloSmartcard(5386): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
06-23 12:57:23.285: E/HelloSmartcard(5386): at dalvik.system.NativeStart.main(Native Method)
06-23 12:57:23.285: I/Choreographer(5386): Skipped 45 frames! The application may be doing too much work on its main thread.
>我有org.simalliance.openmobileapi.jar作为依赖项:
>我已获得许可:
<uses-permission android:name="org.simalliance.openmobileapi.SMARTCARD"/>
>我的SIM卡上有3个小程序,我正在尝试使用AID F9 F4 0F 65 18 C9 54 1E CD AD
这是我正在使用的粗略代码模板:
package com.example.testsmartcardaccess2;
import org.simalliance.openmobileapi.Channel;
import org.simalliance.openmobileapi.Reader;
import org.simalliance.openmobileapi.SEService;
import org.simalliance.openmobileapi.Session;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Toast;
public class MainActivity extends Activity implements SEService.CallBack {
private SEService seService;
private Reader uuicReader;
private boolean seServiceConnected;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
final String LOG_TAG = "HelloSmartcard";
try {
Log.i(LOG_TAG, "creating SEService object");
this.seServiceConnected = false;
seService = new SEService(MainActivity.this, MainActivity.this);
} catch (SecurityException e) {
Log.e(LOG_TAG,
"Binding not allowed, uses-permission org.simalliance.openmobileapi.SMARTCARD?");
} catch (Exception e) {
Log.e(LOG_TAG, "Exception: " + e.getMessage());
}
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
button = new Button(this);
button.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
button.setText("Click Me");
button.setEnabled(false);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
Log.i(LOG_TAG, "Retrieve available readers...");
Reader[] readers = seService.getReaders();
if (readers.length < 1)
return;
uuicReader = null;
for (Reader reader : readers) {
if (reader.getName().equalsIgnoreCase("SIM - UICC")) {
uuicReader = reader;
break;
}
}
Log.i(LOG_TAG, "Create Session from the UICC reader...");
Session session = uuicReader.openSession();
Log.i(LOG_TAG,
"Create logical channel within the session...");
Channel channel = session.openLogicalChannel(
new byte[] {
(byte) 0xF9,
(byte) 0xF4,
(byte) 0x0F,
(byte) 0x65,
(byte) 0x18,
(byte) 0xC9,
(byte) 0x54,
(byte) 0x1E,
(byte) 0xCD,
(byte) 0xAD
}
);
Log.d(LOG_TAG, "Send HelloWorld APDU command");
byte[] respApdu = channel.transmit(new byte[] {
(byte) 0x90, 0x10, 0x00, 0x00, 0x00 });
channel.close();
// Parse response APDU and show text but remove SW1 SW2
// first
byte[] helloStr = new byte[respApdu.length - 2];
System.arraycopy(respApdu, 0, helloStr, 0,
respApdu.length - 2);
Toast.makeText(MainActivity.this, new String(helloStr),
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Log.e(LOG_TAG, "Error occured:", e);
return;
}
}
});
layout.addView(button);
setContentView(layout);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void serviceConnected(SEService arg0) {
Log.i("SEService", "Connected");
this.seServiceConnected = this.seService.isConnected();
updateButtonStatus(button, this.seServiceConnected);
}
private void updateButtonStatus(Button button, boolean enabled) {
button.setEnabled(enabled);
}
@Override
protected void onDestroy() {
if (seService != null && seService.isConnected()) {
seService.shutdown();
this.seServiceConnected = false;
updateButtonStatus(button, this.seServiceConnected);
}
super.onDestroy();
}
}
我相信我的SIM卡上没有关于applet访问的设置,但是由于那部分不是我的网域,因此我不知道该如何解决.
我曾在Google网上论坛上进行过类似我的困境的讨论,但不确定如何解释它.
任何帮助表示赞赏!
解决方法:
错误
java.lang.SecurityException: Access Control Enforcer: access denied: EF_DIR not found!!
很清楚. S3的常规固件上的Open Mobiel API实现要求安全元素(UICC)上存在PKCS#15文件结构(访问控制文件系统,ARF). (而不是由GlobalPlatform安全元素访问控制规范引入的访问控制小程序(ARA).)
因此,您将需要一个看起来像这样的文件系统(请参阅此示例,并参阅GlobalPlatform安全元素访问控制规范以获取更多参考):
MF (3F00)
|- EF DIR (2F00) --> shall reference PKCS-15
|
|- DF PKCS-15
|
|- ODF --> shall reference DODF
|- DODF --> shall reference EF ACMain
|- EF ACMain --> shall reference EF ACRules
|- EF ACRules --> shall reference EF ACConditions files
|- EF ACConditions1
|- ...
标签:open-mobile-api,galaxy,java,android 来源: https://codeday.me/bug/20191121/2053051.html