001    /*
002     * Copyright (c) 2009 The openGion Project.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013     * either express or implied. See the License for the specific language
014     * governing permissions and limitations under the License.
015     */
016    package org.opengion.fukurou.security;
017    
018    
019    import java.util.Map;
020    import java.util.WeakHashMap;
021    import java.util.HashMap;
022    
023    /**
024     * URLHashMap は、セキュリãƒ?‚£強化ã?為の Hybs独自の暗号化クラスですã?
025     *
026     * こã?クラスは、暗号化キーを受け取りã?それに基づã�?�¦暗号åŒ?復号化を行いますã?
027     * ここでの暗号化ã?、秘å¯?‚­ー方式でバイト文字å?に変換されたものをã??‘6é?アスキーæ–?­—に
028     * 直して、扱ってã�?�¾すã?よって、暗号åŒ?復号化å?に、文字å?として扱ã�?�“とが可能ですã?
029     *
030     * @og.rev 5.2.2.0 (2010/11/01) 新規追åŠ?
031     * @og.group ライセンス管ç�?
032     *
033     * @version  5.2.2.0 (2010/11/01)
034     * @author   Kazuhiko Hasegawa
035     * @since    JDK1.6,
036     */
037    public final class URLHashMap {
038            private static final int SIZE = 6000;
039            private static final Map<String,String> urlMap1 = new HashMap<String,String>( SIZE*4/3 );           // 現役世代1
040            private static       Map<String,String> urlMap2 = new HashMap<String,String>( SIZE*4/3 );           // 現役世代2
041            private static final Map<String,String> urlMap3 = new WeakHashMap<String,String>( SIZE*4/3 );       // 旧世代
042            private static final Object lock = new Object();
043    
044            /**
045             * ãƒ?ƒ•ォルトコンストラクター
046             * これは、すべてstatic メソãƒ?ƒ‰で構æ?されてã�?‚‹クラスなので、直接インスタンスの生æ?を禁止しますã?
047             *
048             * @og.rev 5.3.0.0 (2010/12/01) 新規追åŠ?
049             */
050            private URLHashMap() {
051                    // 直接インスタンスの生æ?を禁止
052            }
053    
054            /**
055             * URL をハãƒ?‚·ュåŒ?暗号化して返しますã?
056             * 共通å?ç�?‚’簡易化するための、便利メソãƒ?ƒ‰ですã?
057             * ここでのハッシュåŒ?暗号化ã?、URLのパラメータ(?以降ã?部åˆ?のみ行いますã?
058             * またã?ここで渡す文字å?は、URLを含ã‚?–‡字å?なので、href のキーワードを
059             * 手がかりにã€? を探して、その部åˆ??み、変換しますã?
060             * href を含まなã�??合ã?、それè?体が URL と判断してã€? を探しますã?
061             * ? が存在しなã�?‚±ースは、url をそのまま返しますã?
062             *
063             * URLのアドレスがã?"/" から始まるå?合ã?、è?身のアドレスと判断しã?ハッシュ処ç�?‚’行いますã?
064             * そうでなã�??å�?http:// ã‚?../ の場å�?は、暗号化å?ç�?‚’行いますã?
065             * 第?’引数は、ハãƒ?‚·ュåŒ?暗号化されたパラメータを指定するキーになりますã?(標準ã?、h_r)
066             * 処ç�?‚’選択しますã?
067             * href を含まずã?'?' ã�?�‘を含ã‚??合ã?ã€??' 以降を暗号化しますã?
068             *
069             * ハッシュの場合ã?こã?キーをå?に、設定å?をå?部キャãƒ?‚·ュ(Map)に設定しますã?
070             * Map はã€?¼“世代持っており、å?部キャãƒ?‚·ュ(SIZE=6000)をè¶?�ˆるとã€?¼’世代目に移行しã€?
071             * さらに、è¶?�ˆるとã€?¼“世代目に移行しますã??“世代目は、WeakHashMap を利用してã�?‚‹
072             * ため、å?合によってはãƒ??タがなくなりã?アクセス不è?になってã�?‚‹可能性がありますã?
073             *
074             * @param       url     オリジナルのURL またã?、URL を含ã‚?–‡字å?
075             * @param       hkey    パラメータのキーとして使用するæ–?­?
076             * @param       extOnly 外部URLの場合ã?み処ç�?‚’実行するå?å�?true
077             *
078             * @return      変換されたURL を含ã‚?–‡字å?
079             */
080            public static String makeUrlChange( final String url , final String hkey , final boolean extOnly ) {
081                    if( url == null || hkey == null ) { return null; }
082                    // 外部のみ(extOnly=true)で、かつ、å?部URLの形式ã?場合ã?引数そã?ままを返しますã?
083                    if( extOnly && url.indexOf( "href=\"/" ) >= 0 ) { return url; }
084    
085                    String rtnUrl = url;
086    
087                    int idx1 = url.indexOf( "href=\"" );
088                    int idx2 = url.indexOf( '?', idx1 );            // href?¥?¥?¥ がなã�?™‚(idx1 == -1)でも正常に動作するã?
089                    if( idx2 >= 0 ) {
090                            String url1 = url.substring( 0,idx2+1 );                // æœ??から '?' まで(?を含ã‚?
091                            int idx3 = url.indexOf( "\"",idx2+1 );
092                            if( idx3 >= 0 ) {
093                                    String url2 = url.substring( idx2+1,idx3 );             // 純粋なパラメータ部åˆ?
094                                    String url3 = url.substring( idx3 );                    // ãƒ?ƒ–ルクオーãƒ?含ã‚?以é™?
095                                    // href="/ かどã�?�‹。文字å?の有効長があるかどã�?�‹をå?にチェãƒ?‚¯してã�?‚‹ã€?
096                                    if( idx1 >= 0 && url.length() > idx1+7 && url.charAt( idx1+7 ) == '/' ) {
097                                            url2 = makeHashKey( url2 );
098                                    }
099                                    else {
100                                            url2 = makeEncrypt( url2 );
101                                    }
102                                    rtnUrl = url1 + hkey + "=" + url2 + url3 ;
103                            }
104                            // '?' はあるがã?æœ?¾Œã?ãƒ?ƒ–ルクオートがなã�??合ã?ã€??' から後ろすべてを暗号化するã?
105                            else {
106                                    String url2 = url.substring( idx2+1 );          // ?以降ã?部åˆ?
107                                    rtnUrl = url1 + hkey + "=" + makeEncrypt( url2 ) ;
108                            }
109                    }
110    
111                    return rtnUrl;
112            }
113    
114            /**
115             * 引数の設定å?をハãƒ?‚·ュ化したときã?値(?�ハãƒ?‚·ュキー)を作æ?しますã?
116             * å†?ƒ¨çš?�«、このハッシュキーをå?に、設定å?をå?部キャãƒ?‚·ュ(Map)に設定しますã?
117             * こã?Mapは、WeakHashMap を利用してã�?‚‹ため、å?合によってはãƒ??タがなくなりã?
118             * アクセス不è?になってã�?‚‹可能性がありますã?
119             *
120             * @param       val     オリジナルの設定å?
121             *
122             * @return      ハッシュキー
123             */
124            public static String makeHashKey( final String val ) {
125                    if( val == null ) { return ""; }
126    
127                    // å¿?®ºæŠ?¼š最後に "X" を付けることで、ハãƒ?‚·ュ処ç�?�•れたことを示すã?
128                    String key = HybsCryptography.getMD5( val ) + "X";
129                    synchronized( lock ) {
130                            urlMap1.put( key,val );
131                    }
132                    return key;
133            }
134    
135            /**
136             * 引数の設定å?を暗号化したときã?値を作æ?しますã?
137             * 暗号化なので、ハãƒ?‚·ュ化ã?時ã?用に、å?部キャãƒ?‚·ュ(Map)に設定しませんã€?
138             * 処ç�?™‚間等をè€??すると、外部URLの暗号化やã€?•·期にわたるURL(ä¸?—¦、シスãƒ?ƒ の
139             * 外部にURLを渡す:例えば、メールでリンク先を送信するなど)の作æ?に使用しますã?
140             *
141             * @param       val     オリジナルの設定å?
142             *
143             * @return      暗号化キー
144             */
145            public static String makeEncrypt( final String val ) {
146                    if( val == null ) { return ""; }
147    
148                    // å¿?®ºæŠ?¼š最後に "Y" を付けることで、暗号化å?ç�?�•れたことを示すã?
149                    HybsCryptography crypt = new HybsCryptography();
150                    return crypt.encrypt( val ) + "Y";
151            }
152    
153            /**
154             * æŒ?®šã?キーに対応した設定å?を取りå?しますã?
155             * ここでは、ハãƒ?‚·ュåŒ?またã? 暗号化されてã�?‚‹キーに対してã€?
156             * ハッシュキーであればã€?–¢連付けられた設定å?を取りå?しã?暗号化キーで
157             * あれば、復号化å?ç�?‚’行いますã?
158             *
159             * @param       key     ハッシュåŒ?暗号化されたキー
160             *
161             * @return      オリジナルの設定å?
162             */
163            public static String getValue( final String key ) {
164                    if( key == null || key.isEmpty() ) { return null; }
165    
166                    String rtn = null;
167    
168                    char ch = key.charAt( key.length()-1 );
169                    if( ch == 'X' ) {
170                            synchronized( lock ) {
171                                    rtn = urlMap1.get( key );
172                                    if( rtn == null ) { rtn = urlMap2.get( key ); }
173                                    if( rtn == null ) { rtn = urlMap3.get( key ); }
174    
175                                    // ハッシュを作æ?するより取得する方がé?度が少なã�??
176                                    if( urlMap1.size() > SIZE ) {
177                                            urlMap3.putAll( urlMap2 );
178                                            urlMap2 = new HashMap<String,String>( urlMap1 );
179                                            urlMap1.clear();
180                                    }
181                            }
182                    }
183                    else if( ch == 'Y' ) {
184                            HybsCryptography crypt = new HybsCryptography();
185                            rtn = crypt.decrypt( key.substring( 0,key.length()-1 ) );
186                    }
187    
188                    return rtn ;
189            }
190    }