自从当初建议设立该板块起讨论的大多都是关于J2EE或是有着大量移动代码的安全问题而很少涉及J2ME,很久没来这里,近日发现J2ME的安全问题也很值得讨论,尤其是lhjiang兄又遇到类似问题,而我在所回的帖子中事后想想发觉有诸多不当,所以不敢怠慢,立刻上网查阅了类似资料兼之以往的些许经验似乎总结出来了一些关于J2ME中(这里只讨论MIDP1.0.3)安全问题的心得。不敢独享,拿出来分享一二,纯属愚见,请各位不吝指正。
方案一:使用第三方的高级加密API。
的确如lhjiang兄所述,目前基于MIDP的最有效的也是为数不多的第三方加密API是BouncyCastle,可到下列站点下载:www.bouncycastle.org 但问题也如lhjiang所言,并不是每个OEM都支持该API,在所回的上一篇帖子当中我提到一个办法,即如果你要使用一些第三方的API,唯一的解决办法就是把提供该API的jar文件和你的MIDP一并打包成一个MIDP Suite以使得该产品从而支持该API,这霎一看很有道理,但后来想想觉得不妥,因为API的使用与否还要看设备本身的支持程度,谁也不会认为随便一个Java手机只要下载了MMApi就可以支持MM了吧(据知情人士透漏,诺基亚的下一款新手机将会支持MMApi,大概要到明年才能面市)?当然不是!其实许多API本身并没有提供任何具体的实现,比如说GCF,在javax.microedition.io这个包中除了Connector这一个类之外其余全是接口,这些只是为了标准化的要求,至于具体的实现还要看OEM的支持程度。所以不能对第三方的API抱有过高的期望。
解决办法:确定你所开发机型的OEM支持该API,否则请看方案二。
方案二:根据要开发机型的支持程度自己实现具体的安全措施,这里主要是加密。但这种方法几乎是行不通的,原因有三:
(1)支持CLDC1.0规范的设备本身的处理和计算能力不足以胜任如此繁重的计算工作。
(2)CLDC1.0规范目前不支持浮点数,如此复杂的加密算法没浮点数支持就干脆别想了;
(3)MIDP1.0规范所支持的J2SE的子集中Math类只有三个方法:abs(),max(),min()还想什么呢?
解决办法:等待MIDP规范2.0的推出
方案三:使用HTTPS.
方案三的提出我是要感谢一位作者(是外国人,名字又忘了,唉!)我是参考了他的文档才知道MIDP1.0.3的参考实现(Reference Implementation)竟然支持了HTTPS,我很惊奇(说实话,文档本身并不令我惊奇,因为MIDP的安全模型和J2EE中的经典安全模型完全一致,比起诸如Jini,RMI等大量移动代码的安全性而言要简单得多,1.0.3支持HTTPS才是最令我吃惊的),后来仔细又看了看MIDP1.0.3参考实现的文档,果然支持,嗯!当初看文档太粗心了。那这就比睡大觉还简单了,因为其中的安全模型和以往的经典模型完全一致,比如在Applet中的数字签名(关于Applet的数字签名的文章我以前曾写过一篇,可以参考一下,贻笑大方了)或关于在移动代码中的代码签名等(关于这方面的东西,我曾发过一篇帖子专门论及RMI和Jini的移动代码签名问题,可供参阅)所以如果你对这些内容非常熟悉的话,相信MIDP的HTTPS协议的实现方法就会很快掌握了。在API方面没有作任何的更动,只需在Connector的open(String url)方法的url中指定https协议即可。最重要的是必须得到要认证的服务器端所配置的证书并将其导入到J2MEWTK所维护的密钥库中即可。而所有的命令都是由J2MEWTK的bin目录下的MEKeytool命令所完成的,是不是很眼熟,若你用过J2SE的keytool命令的话很快就可以搞定的。当然为练习起见你可以使用keytool先生成一些自签署的证书用以测试之用。