在本文中,我将开始实现生成并处理这些消息的 J2ME 类。我将首先简单描述构成这个基于 J2ME 的 Kerveros 客户机的主要类的作用,然后我将解释并展示这些类如何生成在第一篇文章中讨论过的基本 ASN.1 数据类型。在第三节中,我将展示如何生成一个用于在 Kerveros 通信中进行加密和解密的密钥。最后一节将展示 J2ME 客户机如何生成对 Kerveros 票据的请求。 基于 J2ME 的 Kerveros 客户机中的类 在本文中,将要讨论三个 J2ME 类的操作: ASN1DataTypes KerberosClient KerberosKey ASN1DataTypes 类将包装所有一般性的 ASN.1 功能,如发布像 INTEGER 和 STRING 这样的通用数据类型。KerberosClient 类扩展 ASN1DataTypes 类,使用它的底层功能,并提供所有特定于 Kerveros 的功能。因此,可以说我将所需要的功能简单地分为两组:所有一般性的 ASN.1 功能都在 ASN1DataTypes 类中,而所有特定于 Kerveros 的功能都在 KerberosClient 类中。这提高了代码的重用性。如果您希望构建自己的、使用 ASN.1 功能的非 Kerveros 应用程序,那么您可以使用 ASN1DataTypes 类。 Kerberos 定义了一种利用用户的密码生成密钥的算法。KerberosKey 类实现了这种算法 。在 Kerveros 通信中您将需要这个密钥。 我将在本文分别展示这些类中的每个方法。我还在一个单独的 源代码下载 中加入了这些类。这个包将所有东西放到一组类中,可以将它们编译为一个 J2ME 项目。这个下载包含以下文件: ReadMe.txt,它包含描述如何根据本文的需要练习这些代码的指导。 ASN1DataTypes.java,它实现了ASN1DataTypes 类。 KerberosClient.java,它实现了 KerberosClient 类。 KerberosKey.java,它实现了 KerberosKey 类。 J2MEClientMIDlet.java,它提供了可以用来测试这些代码的一个非常简单的 MIDlet 包装器。 现在,我将进一步探讨这些类的细节。 生成基本 ASN.1 数据类型 清单 1 中显示的 ASN1DataTypes 类处理生成和处理 ASN.1 数据结构所需要的所有底层功能。这个类包含两种方法:生成(authoring) 方法负责生成 ASN.1 数据结构,而 处理(processing) 方法负责处理已生成的或者从远程应用程序收到的消息。我将在本文中解释并实现生成方法,在本系列的下一篇文章中讨论处理方法。 清单 1 只包含 ASN.1 类中不同方法的声明。我将在后面的几节中用单独的清单展示每一个方法的实现。 清单 1. ASN1DataTypes 类 public class ASN1DataTypes { public byte[] getLengthBytes(int length){} public byte[] getIntegerBytes (int integerContents){} public byte[] getGeneralStringBytes (String generalStringContent){} public byte[] getOctetStringBytes (byte[] octetStringContents){} public byte[] getBitStringBytes (byte[] content){} public byte[] getGeneralizedTimeBytes (byte[] generalizedTimeContent){} public byte[] concatenateBytes (byte[] array1, byte[] array2){} public byte[] getSequenceBytes (byte[] sequenceContents){} public byte[] getTagAndLengthBytes (int tagType, int tagNumber, byte[] tagContents){} }//ASN1DataTypes getLengthBytes() (在清单 2 中显示的)这个方法将一个整数值(length)作为参数。它生成一个该长度的 ASN.1 表示,并返回一个符合 ASN.1 长度格式的字节数组。 清单 2. getLengthBytes() 方法 public byte[] getLengthBytes(int length) { if (length < 0) return null; byte lengthBytes[]; if (length <= 127) { lengthBytes = new byte[1]; lengthBytes[0] = (byte)(length & 0xff); } else { int tempLength = length; int bytesRequired = 2; do { tempLength = tempLength / 256; if (tempLength > 0) bytesRequired ++; }while (tempLength > 0); lengthBytes = new byte[bytesRequired]; byte firstLengthByte = (byte) (bytesRequired -1); firstLengthByte |= 0x80; lengthBytes[0] = firstLengthByte; int j = bytesRequired - 1; for (int i=1; i < bytesRequired; i++) { j--; lengthBytes[i] = (byte)(length >>> (j*8) & 0xff); }//for }//else return lengthBytes; }//getLengthBytes 回想一下在本系列的 第一篇文章 中对表 2 的讨论,有两种表示字节长度的方法:单字节表示法和多字节表示法。单字节长度表示法用于表示小于或者等于 127 的长度值,而当长度值大于 127 时使用多字节长度表示法。 getLengthBytes() 方法首先检查长度值是否为负。如果为负,则只是返回 null,因为我不能处理负值。
[1] [2] 下一页
|
|