- PR -

Base64でエンコードしたパラメータの受け渡しについて

投稿者投稿内容
さき@神奈川
会議室デビュー日: 2004/03/31
投稿数: 9
投稿日時: 2004-03-31 09:51
Javaサーブレット+JSPでWebアプリケーションを構築しています。
WebサーバーはWeblogicのWebサーバーです。

1.JSPへ次画面へ引き継ぐ情報として、Base64形式でエンコードしたバイト文字列を書き出し、
2.サブミットした時にパラメータとしてRequestを送信しています。
3.サーブレット側で受け取った文字列をデコードする際に、
  余分な文字が混入しておりエラーとなっています。

画面に書き出す際に余分な文字が入ったのか、
送信時に余分な文字が入ったのか、
Webサーバーが原因なのかわからなく、手の打ちように困っています。

下の文字列サンプルで、"index"パラメータが、Base64エンコード文字列です。
サーブレットで受け取った際に、最後の・・・CxNwAuze8rKgAAAA=の後に
ランダムに3文字〜10文字くらいまでの余分な文字が付いており
デコード時にエラーになります。(???で化けているものもあります)

現在考えている原因はどれも根拠はないのですが・・・
・ユーザーの使用しているブラウザの仕様で、サブミット時に文字列が混入する
・Webサーバーの不具合
・JSP書き出し文字列の書き方(JSESSION等の使い方)

どなたかヒントとか、推測だけでもよいのでアイデアをお願いします。

【文字列のサンプル】
HREF=JavaScript:hoge_script("/hoge_servlet;jsessionid=AqL3RT903u6bXFtfOHurisb1101wzo1cvmTo2r54q6t2Bmr5TovB!-1503792740!-1407516405!8080!-1!680293395!-1407516404!8080!-1?index=H4sIAAAAAAAAAFvzloG1uIhBLzk/Vy8xOTk1r6S0KFUvqwAokJSYU6JXmqlXWpKZo-eZl5Ja4ZyfV5KYmZdapLHlxoGa3-c3MTEweTKwZeWXpqfmeTKwZicC6YoiBn2cpoGMckosTnUqLQaaU1zsn5SVmlxSlL6Q9eX3KSVMDIxRDFxJ-X6lOTluOYnpFQUMQCACxNwAuze8rKgAAAA=","hoge_mode")

【JavaScript】
function hoge_script(url, mode) {
if (flag) {
window.alert(message);
resetFlag();
return;
}
else {
document.form.action = url;
document.form.MODE.value = mode;
document.form.submit();
flag = true;
return;
}
}
ふーばー
大ベテラン
会議室デビュー日: 2003/06/05
投稿数: 163
投稿日時: 2004-03-31 11:34
引用:

下の文字列サンプルで、"index"パラメータが、Base64エンコード文字列です。
サーブレットで受け取った際に、最後の・・・CxNwAuze8rKgAAAA=の後に
ランダムに3文字〜10文字くらいまでの余分な文字が付いており
デコード時にエラーになります。(???で化けているものもあります)



具体的にどんな文字列がついているんですか?いくつか教えてください。

あと、普通、FORM で POST するんだったら、action の後ろに勝手にパラメータを
つけるんじゃなくて、hidden 項目の value にセットすると思うんですけど。
さき@神奈川
会議室デビュー日: 2004/03/31
投稿数: 9
投稿日時: 2004-03-31 14:35
>具体的にどんな文字列がついているんですか?いくつか教えてください。
 はい。以下のようなものになります。
 ???、YgW、></、iOQ、AME、t2?、Fla、rkI、=、!-1、H:?
 3文字が多いです。

あと、普通、FORM で POST するんだったら、action の後ろに勝手にパラメータを
つけるんじゃなくて、hidden 項目の value にセットすると思うんですけど。
 作り的におかしいかも知れませんが、FORMでもPOSTしつつ、
 書いているようにURLでもパラメータを渡しています。
 画面内に同じようなリンクを作成し、クリックされたリンクによって
 渡すパラメータを変えたいためです。

以上、よろしくお願いします。
さき@神奈川
会議室デビュー日: 2004/03/31
投稿数: 9
投稿日時: 2004-04-01 09:31
追記です。
 障害が発生している中にMAC使用のユーザーがいたという事がわかりました。
 全てのエラーがMACかどうかはわからないのですが、
 可能性としてMACだとこういう事が起こるとか、どなたか事例を知っている方いませんか?
 
 Help me〜
ふーばー
大ベテラン
会議室デビュー日: 2003/06/05
投稿数: 163
投稿日時: 2004-04-01 10:21
どの程度の障害解析、問題の切り分けをしているのかがさっぱり見えないんですが。
・再現性はあるか
・他にPOSTされるパラメータをすべてなくしてやってみたか
・問題のURLを直接入力してアクセスした場合の結果はどうなるか
などなど。こういう障害系の質問をする場合は、
・読み手に再現させる
・再現させなくてもわかるぐらいの詳細な情報を提示する
のどちらかをしないと。
びしばし
大ベテラン
会議室デビュー日: 2002/03/13
投稿数: 181
投稿日時: 2004-04-01 12:48
# 勘違いでしたらすみません。

昔、似たようなことをやったときは、Base64 の文字セット(後ろのほう)を変更した記憶があります。
「Base64 の文字セット」は「HTTP でエスケープなしで送信可能な文字セット」に完全に含まれているか確認してみてください。
さき@神奈川
会議室デビュー日: 2004/03/31
投稿数: 9
投稿日時: 2004-04-01 17:39
ふーばーさん、びじばしさん、回答ありがとうございます。

不足している情報を書き足します。

>・再現性はあるか
特定のユーザーで再現しているようですが、(ユーザーID等を取っている事から判る)
開発環境での再現はしていません。
開発環境でテストしているノード環境はWindows2000+IE6.0、IE5.5、NN4.7
システム全体の作りとして、パラメータをBase64でやり取りしており
他の画面でも同様にBase64を使用していたりするのですが、
FormのパラメータからPOSTしている部分では発生しておらず、
Base64を前掲のようにURLに埋め込んで送っている箇所でのみ発生しています。

>・他にPOSTされるパラメータをすべてなくしてやってみたか
手元の環境で再現していないので、試しておりません。

>・問題のURLを直接入力してアクセスした場合の結果はどうなるか
直接入力すると、Base64に到達するまえにリファラーチェックしてはじいてしまいますので
それ用のエラー画面に遷移させています。

>「Base64 の文字セット」は「HTTP でエスケープなしで送信可能な文字セット」に完全に含まれているか確認してみてください。

早速チェックしてみました。↓Base64文字列を書きます。
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/=
しかし私には問題なさそうに見えます・・・

URLエンコードする際に、送信バイトデータとの文字コードの不一致により
デコードする際にちゃんとデコードできない事とかってはずれてますでしょうか?

以下、Base64のエンコード、デコードのソースを書いておきます。
public class Base64 {

/** BASE64文字(0から63)のコードキャラクタ(padding文字も含む)を順に代入した文字配列 **/
private static final char[] alphabet ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/=".toCharArray();

/** 0から63までの数字に変換されたBase64方式の文字を代入するための配列 **/
private static byte[] codes = new byte[256];

static {
for (int i = 0 ; i < 256; i++) {
codes[i] = -1;
}
for (int i = 'A'; i <= 'Z'; i++) {
codes[i] = (byte)(i - 'A');
}
for (int i = 'a'; i <= 'z'; i++) {
codes[i] = (byte)(26 + i - 'a');
}
for (int i = '0'; i <= '9'; i++) {
codes[i] = (byte)(52 + i - '0');
}
codes['-'] = 62;
codes['/'] = 63;
}

public static char[] encodeFromByteToChar (byte[] data) {

String METHOD = "encodeFromByteToChar(byte[])";

char[] out = new char[((data.length + 2) / 3) * 4];

for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
boolean quad = false;
boolean trip = false;

int val = (0xFF & (int) data[i]);
val <<= 8;

if ((i+1) < data.length) {
val |= (0xFF & (int) data[i+1]);
trip = true;
}

val <<= 8;
if ((i+2) < data.length) {
val |= (0xFF & (int) data[i+2]);
quad = true;
}

out[index+3] = alphabet[(quad? (val & 0x3F): 64)];
val >>= 6;
out[index+2] = alphabet[(trip? (val & 0x3F): 64)];
val >>= 6;
out[index+1] = alphabet[val & 0x3F];
val >>= 6;
out[index+0] = alphabet[val & 0x3F];

} // end of for statement

return out;

}// end of encodeFromByteToChar

public static byte[] decodeFromCharToByte (char[] data) {

String METHOD = "decodeFromCharToByte(byte[])";


int len = ((data.length + 3) / 4) * 3;

if (data.length > 0 && data[data.length-1] == '=') {
--len;
}
if (data.length > 1 && data[data.length-2] == '=') {
--len;
}

byte[] out = new byte[len];

int shift = 0; // accumに格納されている余分なビット
int accum = 0; // 余分なビット
int index = 0;

for (int ix = 0; ix < data.length; ix++){
int value = codes[ data[ix] & 0xFF ];
if ( value >= 0 ) {
accum <<= 6;
shift += 6;
accum |= value;
if ( shift >= 8 ) {
shift -= 8;
out[index++] = (byte) ((accum >> shift) & 0xff);
}
}
}

if (index != out.length) {
// ここでExceptionをThrowしてます。
}

return out;

}

}
yuzy
大ベテラン
会議室デビュー日: 2002/02/14
投稿数: 117
投稿日時: 2004-04-01 17:46
>>「Base64 の文字セット」は「HTTP でエスケープなしで送信可能な文字セット」>に完全に含まれているか確認してみてください。

>早速チェックしてみました。↓Base64文字列を書きます。
>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/=
>しかし私には問題なさそうに見えます・・・

問題あるのでは?
/ とか = が含まれていたらまずいです。(RFC番号忘れましたが、使用できる文字には
制限があります。調べてみてください。)
影響がない他の文字(って何???)に変えるべきではないでしょうか。

スキルアップ/キャリアアップ(JOB@IT)