理解 MIDP2.0 的安全架构

原文: http://developers.sun.com/techtopics/mobility/midp/articles/permissions/

??????

MIDP是移动设备的一个优秀平台, 原因之一就是它提供的安全性. 这部分是在Java编程模型中所固有的.MIDlet代码运行在虚拟机的边界内. 意思是说它对一些二进制代码可能造成的重大错误具有免疫力. 写得糟糕的或恶意的代码可使得设备无法操作. 在最坏的情况下, 糟糕的java代码将使java运行环境停止工作. 而设备的其它部分不会受到影响.???? MIDP2.0中设计的安全支持并不仅限于JVM, 这篇文章描述了其它MIDP2.0特性, 它们保护用户及它们的设备免受恶意软件的破坏. 你将使用J2ME Toolkit 2.0 (beta 2或以后版本)来学习怎样使用MIDP2.0安全架构.

?

哪些是敏感的操作?

?????? MIDP2.0的规范定义了一个开放的(open-ended)许可系统. 要进行任何类型的网络连接, 一个MIDlet必须要有一个适当的许可. 比如说, 一个用HTTP和服务器对话的MIDlet必须要有一个打开HTTP连接的许可.MIDP2.0中定义的许可与网络协议相关联, 但是安全架构允许可选API定义它们自己的许可.

?

每一个许可都有一个独一无二的名字, 以下是MIDP2.0中的许可:

  • javax.microedition.io.Connector.http
  • javax.microedition.io.Connector.socket
  • javax.microedition.io.Connector.https
  • javax.microedition.io.Connector.ssl
  • javax.microedition.io.Connector.datagram
  • javax.microedition.io.Connector.serversocket
  • javax.microedition.io.Connector.datagramreceiver
  • javax.microedition.io.Connector.comm
  • javax.microedition.io.PushRegistry

许可的名字和类的名字并不相同, 尽管它们看起来很相似. 比如说javax.microedition.io.Connector.https许可它支配MIDletjavax.microedition.io.Connector类进行https连接的能力.

?

MIDlet并不显式地从代码中获得许可, 而是通过一个称作保护域(protected domain)的东西. 在你被代码安全搞迷糊之前, 我给你展示一个可用的代码.

?

创建一个HTTP连接.

?

下面一个简单的MIDlet, 创建一个HTTP连接并取回一些服务器应答.

??????

import java.io.*;
?
     
     
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
?
     
     
public class HTTPMIDlet
??? extends MIDlet
??? implements CommandListener, Runnable {
? private Display mDisplay;
? private Form mMainScreen;
?
     
     
? public HTTPMIDlet() {
??? mMainScreen = new Form("HTTPMIDlet");
??? mMainScreen.append(
??????? "Press OK to create an HTTP connection.");
?
     
     
??? Command exitCommand =
??????? new Command("Exit", Command.EXIT, 0);
??? Command okCommand =
??????? new Command("OK", Command.OK, 0);
??? mMainScreen.addCommand(exitCommand);
??? mMainScreen.addCommand(okCommand);
??? mMainScreen.setCommandListener(this);
? }
? 
??public void startApp() {
??? if (mDisplay == null)
????? mDisplay = Display.getDisplay(this);
??? 
????mDisplay.setCurrent(mMainScreen);
? }
? 
??public void pauseApp() {
? }
? 
??public void destroyApp(boolean unconditional) {}
? 
??// CommandListener method
? 
??public void commandAction(Command c, Displayable s) {
??? if (c.getCommandType() == Command.EXIT)
????? notifyDestroyed();
??? else if (c.getCommandType() == Command.BACK)
????? mDisplay.setCurrent(mMainScreen);
??? else if (c.getCommandType() == Command.OK) {
????? // Put up a wait screen.
????? Form waitForm = new Form("Connecting...");
????? mDisplay.setCurrent(waitForm);
????? // Make the connection
????? Thread t = new Thread(this);
????? t.start();
??? }
? }
? 
??// Runnable method
? 
??public void run() {
??? String url = "http://wireless.java.sun.com/";
??? 
????Form resultsForm = new Form("Results");
??? Command backCommand =
??????? new Command("Back", Command.BACK, 0);
??? resultsForm.addCommand(backCommand);
??? resultsForm.setCommandListener(this);
??? 
????HttpConnection hc = null;
??? InputStream in = null;
?
     
     
??? try {
????? // Now make a connection to the server.
???? ?hc = (HttpConnection)Connector.open(url);
????? 
??????// Retrieve the response.
????? in = hc.openInputStream();
?
     
     
????? int length = 256;
????? byte[] raw = new byte[length];
????? int readLength = in.read(raw);
????? 
??????String message = new String(raw, 0, readLength);
????? resultsForm.append(message);
??? }
??? catch (Exception e) {
????? resultsForm.append(
????????? new StringItem("Exception: ", e.toString()));
??? }
??? finally {
????? if (in != null) {
??????? try { in.close(); }
??????? catch (IOException ioe) {}
????? }
????? if (hc != null) {
??????? try { hc.close(); }
??????? catch (IOException ioe) {}
????? }
??? }
??? mDisplay.setCurrent(resultsForm);
? }
}

?

HTTPMIDlet run() 方法连接到一个服务器, 获取一些数据, 并且在屏幕上显示出来. 你可以编译

并运行 HTTPMIDlet 而不需要考虑保护域. 当你选择OK命令来创建连接的时候, HTTPMIDlet 调用 Connector open() 方法. 如果你用的是 J2ME Wireless Toolkit, 仿真器会提示你选择许可.

?

The Emulator Asks for Permission

仿真器要求许可

?

你有机会来准予或拒绝这个连接的许可, 你也可以选择产生一个永久地准予或拒绝许可, 尽管这些选项仅在MIDlet套件的安装环境中才有意义, 我会在后面解释它.

?

如果你允许连接, 程序会正常地继续运行, MIDlet显示在HTTP连接中获取的数据.

?

Data from the Server

从服务器获取的数据

?

另一方面, 如果你的心情不好, 拒绝了这个连接, Connector.open() 抛出一个Security Exception异常. HTTPMIDlet 捕获了这个异常并显示了一个有关的消息. 所有的 MIDlets 都应该捕获网络连接抛出的 SecurityException, 并适当地处理它们.

?

?

Permission Denied

许可被拒绝

?

仿真器是如何知道它应该请求你的许可来创建HTTP连接的? 为什么许可不直接设成准予1”拒绝”? 答案就在于包含HTTPMIDlet的保护域.

?

理解保护域

?

一个保护包含两部分:

1.?????? 被允许的许可 (授予所包含的MIDlet套件), 和必须与用户商议的许可.

2.?????? 进入到保护域的条件 (Criteria)

?

当你在 J2ME Wireless Toolkit 中点击 Run 按钮时, 当前的MIDlet 套件运行在一个称为 UnTrusted 的保护域中, 在这个域中, 所有的许可都要和用户商议, 这就是为什么HTTPMIDlet试图创建HTTP连接的时候, 仿真器会提示你选择许可.

?

你可以改变MIDlet套件的运行时保护域, 选择 Edit->Preferences, 然后点击 Security 标签.

?

Selecting a Protection Domain

选择一个保护域

?

J2ME Wireless Toolkit 包含四个保护域. minimum 域中的MIDlets 所有许可被拒绝. UnTrusted 域中, 每个许可都提示用户选择. Trusted 域是MIDlet 的天堂, 所有的许可都被准予, 它和 Maximum 是等价的.

?

试着选择Minimum, 然后再运行HTTMIDlet, 这次, 当你选择OK来创建连接的时候, 许可马上被拒绝且HTTPMIDlet显示了一个 SecurityException.

?

J2ME Wireless Toolkit 仅演示了实现保护域的一种方法, 制造商, 运营商以及其它一些MIDP实现者可以自由地创建适合它们自己的域.

?

理解许可类型

?

一个保护域包含允许(allowed)许可和用户(user)许可, 用户许可就是要和用户商议的许可. 它又分三类, (在规范中称为交互模式), MIDlet 第一次需要许可的时候, 实现会询问用户许可应该被准予或拒绝, 这三类模式指出了实现在多长的时间内记住用户的决定

?

对于 oneshot 许可, 实现不保留任何用户的决定, 每一次都向用户请求许可. 对于 session 许可, 实现记住用户的决定直MIDlet 终止. 最后, blanket 许可, 用户的决定被保存, 直到MIDlet 套件被卸载.

?

一个保护域必须拒绝所有用户未显式允许的许可.

?

比如说, 一个叫做HTTPOnly的保护域仅仅包含一个许可:

?

allow: javax.microedition.io.Connector.http
     
     

?

这个域将拒绝其它所有的许可, 一个更宽容的域可能会在其它的许可上尊重用户的判断, 这样:

?

allow: javax.microedition.io.Connector.http
     
     
blanket: javax.microedition.io.Connector.https
     
     
blanket: javax.microedition.io.Connector.socket
?
     
     

在这种情况下, 用户将会被要求选择允许或拒绝 https socket 连接.

?

记住, 保护域的定义和配置完全是实现者的责任 (province), 这是你作为一个应用开发者的工作来有效地利用MIDP2.0规范中定义的安全架构.

?

MIDlet 套件请求许可

?

JAD中的特殊属性标明(signal)了一个MIDlet 套件所信赖的特定许可. 你可以使用这些特性来来表达如这个MIDlet需要创建一个HTTP连接而且可能也需要创建一个socket连接”. 在这种情况下, 描述文件中的属性看起来就象这样:

?

MIDlet-Permissions: javax.microedition.io.Connector.http
     
     
MIDlet-Permissions-opt: javax.microedition.io.Connector.socket
     
     

?

幸运的是, 你不用手动添加这些属性. J2ME Wireless Toolkit 可以很容易地添加它们, 点击 Settings, 选择 Permission标签, 根据需要添加必要和可选的许可, 工具箱会自动地将它们写到MIDlet套件的JAD.

?

将必要和可选的许可加到JAD中有什么好处呢? 这是一个很方便的方法可以在安装的时候通知目标设备你的MIDlet试图进行一些特别的操作. 如果设备将把MIDlet安装到一个保护域中, 而这个域不允许该MIDlet套件所要求的某些许可. 安装过程可以显示失败, 如果没有这个机制, 用户会安装一个MIDlet套件, 随后却发现它不能工作.

?

代码签名

?

我们刚刚学到了一个保护域包含允许的(allowed)和用户(user)许可. 保护域的另一部分是一套描述MIDlet套件如何进入域的规则.

????????????????

下载的代码可能会非常危险, 尤其是当你不知道是谁写的代码或它从哪里来的时候. 尽管在虚拟机上运行的MIDlet本质上比二进制代码安全一些, 但仍然有风险. 下载的MIDlet可以创建未授权的网络连接, 连接会花费用户的钱. 恶意的MIDlet可收集你的信息并发送到服务器进行未授权的使用. MIDP设备给了用户很大的灵活性来选择游戏和应用程序, 但是这些灵活性带来了运行来源和动机不明的代码的风险.

?

代码域可以配置使用户更安全地运行下载的MIDlet, MIDP规范故意地模糊了关于保护域怎样定义的内容, 它留下了很多内容让实现者自行决定: 要表现的保护域的数量及它们如何定义. 但是规范推荐了一个基于密码签名和证书的保护域. 想法是让一个运营商或软件开发者创建一个签名密鈅对并从一个经过验证的CA得到一个证书. 运营商或开发者计算出一个MIDlet套件JAR包的签名, 然后将该签名和相应的证书放在应用的描述文件中.

?

一个签名的MIDlet套件向用户保证MIDlet套件的内容没有被篡改的而且MIDlet套件来自于一个可确认(从而有法律责任的)的来源. 设备上的MIDP实现可通过开发者的签名来核实开发者, 它可以自行用开发者的公鈅来验证MIDlet套件的完整性.????

?

J2ME Wireless Toolkit 2.0版本包括了易于使用的管理签名MIDlet套件和密鈅的工具, 设想, 比如, 在你用Project->Package->Create Package来打包了这个MIDlet套件后, 你想要签名这个HTTPMIDlet项目, 选择Project->sing 来开始签名过程.

?

?Signing a MIDlet Suite

签名一个MIDlet套件

?

这个窗口显示了所有toolkit知道的所有签名密鈅对的列表. 如果你在java的密鈅存储中有一个密鈅对, 且你想用它来签名你的MIDlet套件, 你可以用 Import->Key Pair 来导入到 J2ME Wireless Toolkit.

?

如果你想创建一个新的密鈅对来签名, 点击 New Key Pair ,填入适当的 密鈅别名, 域名, 公司名.

?

Creating a Key Pair

创建一个密鈅对

?

toolkit创建新的密鈅对并加到可用签名密鈅对的列表中. 在这时, toolkit 问你哪 个保护域应该和这个新的密鈅对相关联. 仿真器将安装用新密鈅对签名的MIDlet套件你选择的保护域中, 在这个例子中, 选择 Trusted.

?

Choosing a Protection Domain

选择一个保护域

?

一旦你创建了密鈅对并选择了一个保护域, 签名一个MIDlet套件非常简单, 选择你想要使用的密鈅对的别名并点击 Sign MIDlet Suite.如果你已通过 File->Utilities 到达 Sign MIDlet Suite 窗口, toolkit 将要求你定位你想要签名的MIDlet套件的描述文件. 选择这个项目的描述文件, 如果你在作用 HTTPMIDlet项目, 描述文件就是 apps/HTTPMIDlet/bin/HTTPMIDlet.jad, 它在J2ME Wireless Toolkit的安装目录下. 此外, 如果你从 Ktoolbar的菜单中选择 Project->:Sign, 它会选择当前活动项目的描述文件.

?

Toolkit会在完成对MIDlet套伯签名后通知你, 如果你不相邻已经完成了, 可以在文件编辑器中打开描述文件, 你将看至两个新的属性, MIDlet-Certificate-1-1 MIDlet-Jar-RSA-SHA1, 两个属性都是以Base64编码形式呈现, 这是一个将二进制数据编码成文本的方法.

?

安装一个签名的MIDlet套析

?

现在你已经有了一个签名的MIDlet套件, 你将怎样处理它呢? J2ME Wireless Toolkit,, 你可以在仿真器中安装这个MIDlet 来看它是否在结束后被放在正确的保护域中. 任何一个MIDP实现(包括 toolkit 仿真器) 有管理MIDlet MIDlet 套件功能的软件, 称为AMS(application management software).. AMS管理MIDlet套件的安装并且负责启动和清理MIDlets. (你是不是好奇是什么调用了你MIDlet中的startApp()方法? 就是AMS)..

?

toolkit仿真器包括了一个AMS, 它可以处理 OTA (Over the Air)供给. 你要做的一切就是让仿真器的AMS指向一个包含MIDlet套件描述文件链接的网页, AMS可以使用MIDP规范中描述的OTA协议来下载和安装这个MIDlet套件.

?

幸运地是, 你不必找寻自己的服务器秋使用这个特性, J2ME Wireless Toolkit 2.0 (beta2及以后版本)包含了一个小的仿真OTA服务器可以很容易地测试一个签名的MIDlet套伯的OTA安装.

?

假设你已经打包并签名了一个MIDlet套件, Ktoolbar菜单中选择 Project->Run via OTA, 仿真器显示一个AMS启动画面:

?

?? AMS Splash Screen ?

AMS 启动画面

?

选择Apps 显示已安装的MIDlet套件列表

?

AMS Application List

AMS 应用程序列表

?

要安装你刚刚签名的MIDlet套件, 选择 Install Applicztion 点击 select 按钮. AMS 提示要求一个URL, 但是

它已经填好了 toolkit 的本地OTA服务器的地址.

?

Entering a URL

输入一个URL

?

你要做的仅是选择 Go 命令. AMS连接到toolkits OTA服务器并提示你选择要安装的MIDlet套件. 应该只有一个.

?

Choosing a MIDlet Suite

选择一个MIDlet套件

?

选择 Install 秋开始安装, AMS提供了一些关于MIDlet套件的基本信息并询问你是否要继续:

?

Confirming Installation

确认安装

?

再选择 Install, AMS安装这个MIDlet套件并且把它加在你可以运行的MIDlet套件列表当中. 当你运行HTTPMIDlet示例的时候, 你可以建立HTTP连接, 而仿真器不会要求你选择许可. 为什么? 当你创建这个密鈅对的时候, 你关联Trusted 保护域. 当你通过 Run via OTA 安装, 仿真器就将它安装到了 Trusted . 最后, HTTPMIDlet尝试HTTP连接时, 它可以从包含它的保护域 Trusted 中得到许可,

?

总结

?

这篇文章是一个MIDP2.0安全架构的概览, 你学习了关于在MIDP设备的安全架构的动机, 以及在MIDP2.0中受保护的网络操作, J2ME WTK使得我们很容易指定MIDlet套件需要的许可, MIDlets基于它们的凭证被分类进称为保护域的存储段, 一个保护域是一个许可的集合以及一套进入保护域的条件(criteria). MIDP2.0规范包含用密码对MIDlet套件进行签名建议, 这个在J2ME WTK中实现的方案包括简单的创建密鈅对和签名一个MIDlet套件的工具. 最后, toolkitsRun via OTA特性使得很容易测试签名的MIDlet套件的安装.

?

MIDP2.0的安全架构灵活而且健壮, J2ME WTK使得用新的安全架构来开发用户可以安全运行的软件变得非常容易.

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值