2

HTTP が独自のセキュリティ モデルを備えた Java ベースのレポート システムにクライアントをリダイレクトする、アクセス制御された PHP システムを使用しています (これはひどいものです)。レポート セキュリティ モデルを回避するために、Tomcat フィルターを使用して、レポート システムに到達する前にすべての要求を検証しています。PHP から Java に渡された暗号化されたトークンを使用しています。これにより、レポート システムにクライアントが誰であるかが通知されます。フィルターは、要求されたレポート名を制限リストと照合してチェックし、クライアントの役割が不十分な場合は 403 を返します。

暗号化されたトークンには、タイムスタンプとユーザーの役割が格納されます。

1365549482|SysAdmin

暗号化するとこんな感じ

vSEFgBYd30Ik5p4PZlG968cvdg==

PHP システムは、すべてのレポート リクエストのプロキシとして機能します。ユーザーがレポートを要求すると、その要求は PHP に送られ、暗号化されたトークンが生成され、URL がエンコードされてレポート URL に追加され、レポート システムに対して GET 要求が行われます。私の Java フィルターはトークンを復号化し、それを引き離し、何をすべきかを判断します。

10 回中 9 回は問題ありませんが、トークンを適切に復号化できない場合があります。上記の(暗号化されていない)例は、次のように変換されます

1365549482q??YZ7

そして、すべてがうまくいかない。

私は暗号化、復号化、および文字エンコーディングの詳細について少し詳しくありませんが、残念ながら、これに取り組むことができる開発者は私だけです。ここで何がうまくいかないのかについての考えは、非常に高く評価されます。ほとんどの場合は機能するため、大きなコードの変更はないと思いますが、時間に敏感なコンポーネントが混在していることは明らかです。以下のコード スニペット

編集

私はこれをデバッグするのにしばらく費やしましたが、それは奇妙になりました。HTTP GET 経由で PHP からトークンを要求する小さな Java プログラムを作成しました。PHP スクリプトは、通常のワークフローで URL パラメーターを介して Java に渡される値と同じ (URL エンコードされた) 値を返します。Java プログラムは、以下のコード スニペットと同じ方法でこれをデコードおよび復号化し、結果を確認します。数千回以上の反復 (これまでのところ、数え切れないほど) が期待どおりに機能しています。ただし、このテストの進行中に、フィルターのログ ファイルで同じエラーが発生していることがわかります。

この断続的な問題の原因は、Tomcat フィルターである Java クラスまたは Tomcat を介して URL で渡されるデータに関連しているようです。これは、ここで何が起こっているのかについてのヒントを誰かに与えますか? 私は今とても混乱しています。

PHP

$presentAsSeconds = time();

$message = strval($presentAsSeconds + Configure::read('Reporting.Authentication.ExpireInSeconds')) . '|' . $userDetails['role'];

return base64_encode(
    mcrypt_encrypt(
        MCRYPT_RIJNDAEL_128,
        md5(Configure::read('Reporting.Authentication.Key')),   // matches "the key" in Java function
        $message,
        MCRYPT_MODE_CFB,
        Configure::read('Reporting.Authentication.IVector')     // matches "the vector" in Java function
    )
);

ジャワ

private String decrypt(String initial) throws Exception {

    SecretKeySpec skeySpec = new SecretKeySpec(md5("the key").getBytes("UTF-8"), "AES");
    IvParameterSpec initialVector = new IvParameterSpec("the vector".getBytes("UTF-8"));
    Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, initialVector);
    byte[] encryptedByteArray = (new org.apache.commons.codec.binary.Base64()).decode(initial.getBytes("UTF-8"));
    byte[] decryptedByteArray = cipher.doFinal(encryptedByteArray);

    return (new String(decryptedByteArray, "UTF8"));
}

private String md5(String input) throws NoSuchAlgorithmException {

    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] messageDigest = md.digest(input.getBytes("UTF-8"));
    BigInteger number = new BigInteger(1, messageDigest);

    return number.toString(16);
}
4

2 に答える 2

0

問題は getBytes() メソッドにある可能性があります。これらはデフォルトのシステム文字エンコーディングを使用しますが、これはすべての JVM で同じではありません。代わりに getBytes("UTF-8") を使用してください。

于 2013-04-10T00:09:41.707 に答える
0

問題は、PHP で mcrypt ライブラリを使用した方法にあると思いますが、暗号化されたデータを base64 でエンコードしていますか? 同様のことを行うと、間違いなくいくつかの問題が発生し、base64 エンコードが削除され、その後は機能しました。

URL の代わりに別の方法でトークンを渡すことはできますか? クッキーや認証ヘッダーなど?

あなたのmcryptが正しくないと思うので、PHPでの暗号化/復号化のスニペットです(私はJavaが得意ではありません)。

エンコーディング:

    $userObjectJson = json_encode($this);

    //encrypt the user session object
    $mcrypt = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CFB, '');
    $_SESSION['iv'] = mcrypt_create_iv(mcrypt_enc_get_iv_size($mcrypt), MCRYPT_RAND);
    $keySize = mcrypt_enc_get_key_size($mcrypt);
    $key = substr(MYAWESOME_KEY, 0, $keySize);

    mcrypt_generic_init($mcrypt, $key, $_SESSION['iv']);
    $_SESSION['user'] = mcrypt_generic($mcrypt, $userObjectJson);
    mcrypt_generic_deinit($mcrypt);
    mcrypt_module_close($mcrypt);

デコード:

    //decrypt the user session object
    $mcrypt = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CFB, '');
    $keySize = mcrypt_enc_get_key_size($mcrypt);
    $key = substr(MYAWESOME_KEY, 0, $keySize);
    mcrypt_generic_init($mcrypt, $key, $_SESSION['iv']);
    $userObjectJson = mdecrypt_generic($mcrypt, $_SESSION['user']);
    mcrypt_generic_deinit($mcrypt);
    mcrypt_module_close($mcrypt);
于 2013-04-10T00:53:43.553 に答える