分享
 
 
 

用Kerberos为J2ME应用程序上锁(1)

王朝java/jsp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

在本文中,我将开始实现生成并处理这些消息的 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

return null;

byte lengthBytes[];

if (length

{

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

j--;

lengthBytes[i] = (byte)(length (j*8) & 0xff);

}//for

}//else

return lengthBytes;

}//getLengthBytes

回想一下在本系列的 第一篇文章 中对表 2 的讨论,有两种表示字节长度的方法:单字节表示法和多字节表示法。单字节长度表示法用于表示小于或者等于 127 的长度值,而当长度值大于 127 时使用多字节长度表示法。

getLengthBytes() 方法首先检查长度值是否为负。如果为负,则只是返回 null,因为我不能处理负值。

然后这个方法检查长度值是否小于或者等于 127。如果是,就需要使用单字节长度表示法。

注意在 J2ME 中一个整数是 4 字节数据,而单字节长度表示法只需要 1 个字节。如果长度参数是 0 到 127 之间(包括这个两数)的一个值,那么其字节表达就在 0x00000000 与 0x0000007f 之间(意味着只有最低有效位字节包含有用的数据)。将这个整数造型为一个单字节时,只有最低有效位字节(0x00 到 0x7f)会作为十六进制值拷贝到单字节数组。因此,如果长度值在 0 到 127 之间,那么我可以只执行该长度与 0xff 之间的一个按位 AND 操作。这个操作会得到一个整数,它有效的最高 3 个字节都将填入零。因此,我可以将按位操作的结果造型为一个字节,将这个字节放入一个单字节数组,并将这个数组返回给调用应用程序。

如果长度值大于 127,那么我必须使用多字节长度表示法,它至少使用 2 字节数据。第一个字节表明长度字节的字节数,后面是实际的长度字节(有关这种格式的详细解释请参阅 第一篇文章)。

如果长度值小于 256,那么就需要总共 2 个长度字节 ―― 1 个字节表明还有一个长度字节,1 个字节包含实际的长度值。如果长度值至少为 256 并小于 65536(256 乘 256),那么就需要总共 3 个长度字节 ―― 1 个字节表明还有 2 个长度字节,两个字节包含实际的长度值。

因此,在多字节格式中所需要的字节数取决于长度值。这就是为什么在 getLengthBytes() 的 else 块的 do-while 循环中要计算长度字节所需要的字节数。

确定所需要字节数的方法很简单。我声明了一个名为 bytesRequired 的字节计数器,从 2 开始计数(所需要的最少字节数),将长度值除以 256,并检查商是否大于或者等于 1。如果是,那么就表明原始长度值大于 256,因而需要至少 3 个字节,所以我增加计数器(bytesRequired)。

我继续将长度值除以 256 并增加字节计数器,直到除得的值小于 1。这时,我就知道找到了在多字节整数格式中需要的字节数。

知道了所需要的字节数后,我就实例化一个具有适当大小的字节数组。自然,长度字节中的第一个字节将表明还有多少个长度字节。因此,我只是将所需要的字节数减 1(bytesRequired-1),并拷贝到一个名为 firstLengthByte 的字节中。

看一下清单 2 中 getLengthBytes() 方法中的 firstLengthByte |= 0x80 这一行代码。这一行代码对 firstLengthByte 和 0x80 (1000 0000)进行按拉 OR 操作,并将结果储存到 firstLengthByte 中。这种逻辑 OR 操作会将 firstLengthByte 的最左边(最高有效)位设置为 1。回想在本系列 第一篇文章 中的讨论,在希望使用多字节整数格式的时候,必须将第一个长度字节的最左边一位设置为 1。

下一行(lengthBytes[0]=firstLengthByte)只是拷贝在包含长度字节的数组的开始位置上的 firstLengthByte。然后,有一个 for 循环,它将长度字节从长度参数中拷贝到在 lengthBytes 数组中它们的正确位置上。当 for 循环退出时,就得到了符合 ASN.1 格式的这个 lengthBytes 数组。清单 2 中 getLengthBytes() 方法的最后一行返回这个数组。

getIntegerBytes()

这个方法取一个整数(value)作为参数并返回以 ASN.1 INTEGER表达的这个整数值。回想一下在本系列 第一篇文章 的表 1 中曾提到,在ASN.1 中 INTEGER 是一种通用数据类型。

清单 3 中显示了 getIntegerBytes() 方法的实现。

清单 3. getIntegerBytes() 方法

public byte[] getIntegerBytes (int integerContents)

{

//1. Declare a byte array named finalBytes, which will

//

hold all the bytes of the ASN.1 byte array representation.

byte finalBytes[];

//2. Calculate the number of bytes required to ho

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有