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 javax.crypto.spec.SecretKeySpec;
020 import javax.crypto.Cipher;
021
022 import java.security.MessageDigest;
023 import java.security.NoSuchAlgorithmException;
024 import java.nio.charset.Charset; // 5.5.2.6 (2012/05/25)
025
026 /**
027 * HybsCryptography は、セキュリãƒ?‚£強化ã?為の Hybs独自の暗号化クラスですã?
028 *
029 * こã?クラスは、暗号化キーを受け取りã?それに基づã�?�¦暗号åŒ?復号化を行いますã?
030 * ここでの暗号化ã?、秘å¯?‚ー方式でバイト文字å?に変換されたものをã??‘6é?アスキーæ–?—に
031 * 直して、扱ってã�?�¾すã?よって、暗号åŒ?復号化å?に、文字å?として扱ã�?�“とが可能ですã?
032 *
033 * @og.rev 4.0.0.0 (2005/08/31) 新規追åŠ?
034 * @og.group ライセンス管ç�?
035 *
036 * @version 4.0
037 * @author Kazuhiko Hasegawa
038 * @since JDK5.0,
039 */
040 public final class HybsCryptography {
041 private final SecretKeySpec sksSpec ;
042 private static final String CIPHER_TYPE = "Blowfish" ;
043
044 /**
045 * プラãƒ?ƒˆフォーãƒ?¾�存ã?ãƒ?ƒ•ォルトã? Charset ですã?
046 * プラãƒ?ƒˆフォーãƒ?¾�存æ?をè?慮する場合ã?エンコード指定で作æ?しておく事をお勧めしますã?
047 *
048 * @og.rev 5.5.2.6 (2012/05/25) findbugs対å¿?
049 */
050 private static final Charset DEFAULT_CHARSET = Charset.defaultCharset() ;
051
052 // 注意:秘å¯?‚ーはã€?¼˜ã?倍数でなã�?�¨ã�?�‘なã�??
053 private static final String HYBS_CRYPT_KEY = "2a5a88891d37ae59" ;
054
055 /**
056 * å†?ƒ¨設定ã?秘å¯?�µを使用して?Œ暗号化を行うオブジェクトを構築しますã?
057 * ここでの暗号化ã?、Java標準ã?セキュリãƒ?‚£パッケージを使用してã�?�¾すã?
058 */
059 public HybsCryptography() {
060 // sksSpec = new SecretKeySpec( HYBS_CRYPT_KEY.getBytes(), CIPHER_TYPE );
061 sksSpec = new SecretKeySpec( HYBS_CRYPT_KEY.getBytes( DEFAULT_CHARSET ), CIPHER_TYPE ); // 5.5.2.6 (2012/05/25) findbugs対å¿?
062 }
063
064 /**
065 * 秘å¯?�µのæ–?—å?を受け取って?Œ暗号化を行うオブジェクトを構築しますã?
066 * ここでの暗号化ã?、Java標準ã?セキュリãƒ?‚£パッケージを使用してã�?�¾すã?
067 * 秘å¯?�µのサイズをã?8 の倍数 (32 以ä¸?448 以ä¸? にするå¿?¦�がありますã?
068 *
069 * @param cryptKey 暗号化を行う秘å¯?�µ
070 */
071 public HybsCryptography( final String cryptKey ) {
072 // sksSpec = new SecretKeySpec( cryptKey.getBytes(), CIPHER_TYPE );
073 sksSpec = new SecretKeySpec( cryptKey.getBytes( DEFAULT_CHARSET ), CIPHER_TYPE ); // 5.5.2.6 (2012/05/25) findbugs対å¿?
074 }
075
076 /**
077 * セキュリãƒ?‚£カラãƒ??DBTyepに対してHybs独自の暗号化を行いますã?
078 * 暗号化されたãƒ??タはã€??常 byte æ–?—ですがã€?¼‘6é?数アスキーæ–?—å?に変換
079 * したもã?を返しますã?
080 * こã?暗号化では、引数ã�?null の場合ã?、ゼロæ–?—å?を返しますã?
081 *
082 * @param org 暗号化を行うå…??æ–?—å?
083 *
084 * @return 暗号化されたæ–?—å?(HEXADECIMALåŒ?
085 */
086 public String encrypt( final String org ) {
087 if( org == null || org.length() == 0 ) { return ""; }
088
089 try {
090 Cipher cipher = Cipher.getInstance( CIPHER_TYPE );
091 cipher.init( Cipher.ENCRYPT_MODE, sksSpec );
092 // byte[] encrypted = cipher.doFinal( org.getBytes() );
093 byte[] encrypted = cipher.doFinal( org.getBytes( DEFAULT_CHARSET ) ); // 5.5.2.6 (2012/05/25) findbugs対å¿?
094
095 return byte2hexa( encrypted );
096 }
097 catch( javax.crypto.IllegalBlockSizeException ex ) { throw new RuntimeException( ex ); }
098 catch( java.security.InvalidKeyException ex ) { throw new RuntimeException( ex ); }
099 catch( java.security.NoSuchAlgorithmException ex ) { throw new RuntimeException( ex ); }
100 catch( javax.crypto.BadPaddingException ex ) { throw new RuntimeException( ex ); }
101 catch( javax.crypto.NoSuchPaddingException ex ) { throw new RuntimeException( ex ); }
102 }
103
104 /**
105 * セキュリãƒ?‚£カラãƒ??DBTyepに対してHybs独自の復号化を行いますã?
106 * ここでの復号化ã?、encrypt で暗号化されたæ–?—を戻すå?合に使用しますã?
107 * こã?復号化では、null は復号化できなã�?�Ÿめã?ゼロæ–?—å?を返しますã?
108 *
109 * @param hex 復号化を行う暗号化された?‘6é?数アスキーæ–?—å?
110 *
111 * @return 復号化されたå…??æ–?—å?
112 */
113 public String decrypt( final String hex ) {
114 if( hex == null || hex.length() == 0 ) { return ""; }
115
116 try {
117 Cipher cipher = Cipher.getInstance( CIPHER_TYPE );
118 cipher.init( Cipher.DECRYPT_MODE, sksSpec );
119 byte[] encrypted = hexa2byte( hex );
120 byte[] decrypted = cipher.doFinal( encrypted );
121 // return new String( decrypted );
122 return new String( decrypted,DEFAULT_CHARSET ); // 5.5.2.6 (2012/05/25) findbugs対å¿?
123 }
124 catch( javax.crypto.IllegalBlockSizeException ex ) { throw new RuntimeException( ex ); }
125 catch( java.security.InvalidKeyException ex ) { throw new RuntimeException( ex ); }
126 catch( java.security.NoSuchAlgorithmException ex ) { throw new RuntimeException( ex ); }
127 catch( javax.crypto.BadPaddingException ex ) { throw new RuntimeException( ex ); }
128 catch( javax.crypto.NoSuchPaddingException ex ) { throw new RuntimeException( ex ); }
129 }
130 /**
131 * 数字から16é?æ–?—に変換するãƒ??ブルですã?
132 */
133 private static final char[] hexadecimal =
134 { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
135 'a', 'b', 'c', 'd', 'e', 'f' };
136
137 /**
138 * バイトé?列を?‘6é?数アスキーæ–?—å?に変換しますã?
139 *
140 * バイトé?列をã€?¼’文字ã?0??,a?žï½??アスキーに変換されますã?
141 * これにより、すべてのæ–?—を、アスキー化できますã?
142 * アスキー化で、上位が0F以下ã?場合でもã?0 をå?すことで、固定長に変換しますã?
143 *
144 * よって、å?力バイトã??’å?のlength()を持ったStringを作æ?しますã?
145 *
146 * @param input バイトé?åˆ?
147 *
148 * @return ?‘6é?数アスキーæ–?—å?
149 */
150 public static String byte2hexa( final byte[] input ) {
151 String rtn = null;
152 if( input != null ) {
153 int len = input.length ;
154 char[] ch = new char[len*2];
155 for( int i=0; i<len; i++ ) {
156 int high = ((input[i] & 0xf0) >> 4);
157 int low = (input[i] & 0x0f);
158 ch[i*2] = hexadecimal[high];
159 ch[i*2+1] = hexadecimal[low];
160 }
161 rtn = new String(ch);
162 }
163 return rtn;
164 }
165
166 /**
167 * ?‘6é?数アスキーæ–?—å?をバイトé?列に変換しますã?
168 *
169 * ?’文字ã?0??,a?žï½??アスキーæ–?—å?をã?バイトé?列に変換されますã?
170 *
171 * よって、å?力Stringの???’å?のlengthを持ったバイトé?列を作æ?しますã?
172 *
173 * @param input ?‘6é?数アスキーæ–?—å?
174 *
175 * @return バイトé?åˆ?
176 */
177 public static byte[] hexa2byte( final String input ) {
178 byte[] rtn = null;
179 if( input != null ) {
180 int len = input.length() ;
181 rtn = new byte[len/2];
182 for( int i=0; i<len/2; i++ ) {
183 char ch = input.charAt( i*2 );
184 int high = ( ch < 'a' ) ? ch-'0' : ch-'a'+10 ;
185 ch = input.charAt( i*2+1 );
186 int low = ( ch < 'a' ) ? ch-'0' : ch-'a'+10 ;
187 rtn[i] = (byte)(high << 4 | low);
188 }
189 }
190 return rtn;
191 }
192
193 /**
194 * MessageDigestにより、MD5 でハッシュしたæ–?—に変換しますã?
195 *
196 * MD5でã€?¼‘6Byteのバイトに変換されますが、ここではã€?del>マイナス時には,
197 * 符号を反転させてã€?/del>?‘6é?数でæ–?—å?に変換してã�?�¾すã?
198 * <del>よって、このメソãƒ?ƒ‰で変換したæ–?—でのみ突き合わせて正しいかどã�?�‹ã‚?
199 * 判断してくださいã€?/del>
200 *
201 * 変換方法ã?、各バイトã?上ä½?下位を?‘6é?æ–?—å?に変換後ã?連結してã�?�¾すã?
202 * これは、Tomcat等ã? digest 認証(MD5使用æ™?と同じ変換方式ですã?
203 * 連結後ã?æ–?—å?長はã€?¼“2バイãƒ?固å®?になりますã?
204 *
205 * @og.rev 5.2.2.0 (2010/11/01) util.StringUtil から移å‹?
206 *
207 * @param input 変換前ã?æ–?—å?
208 *
209 * @return MD5でハッシュしたæ–?—å?。32バイãƒ?固å®?
210 */
211 public static String getMD5( final String input ) {
212 String rtn = null;
213 if( input != null ) {
214 try {
215 MessageDigest md5 = MessageDigest.getInstance( "MD5" );
216 // md5.update( input.getBytes() );
217 md5.update( input.getBytes( DEFAULT_CHARSET ) ); // 5.5.2.6 (2012/05/25) findbugs対å¿?
218 byte[] out = md5.digest();
219 rtn = byte2hexa( out );
220 }
221 catch( NoSuchAlgorithmException ex ) {
222 String errMsg = "MessageDigestで失敗しましたã€?" + input + "]"
223 + ex.getMessage() ;
224 throw new RuntimeException( errMsg,ex );
225 }
226 }
227 return rtn;
228 }
229
230 /**
231 * 暗号化ã?ãƒ?‚¹トを行う為のメインメソãƒ?ƒ‰
232 *
233 * java HybsCryptography KEY TEXT で起動しますã?
234 * KEY : 秘å¯?�µ(8 の倍数 (32 以ä¸?448 以ä¸?æ–??
235 * TEXT : 変換するæ–?—å?
236 *
237 * @og.rev 5.2.2.0 (2010/11/01) 循環参ç?の解æ¶?LogWriter 削除)
238 *
239 * @param args 引数配å?
240 */
241 public static void main( final String[] args ) throws Exception {
242 if( args.length != 2 ) {
243 // LogWriter.log( "java HybsCryptography KEY TEXT" );
244 // LogWriter.log( " KEY : 秘å¯?�µ(8 の倍数 (32 以ä¸?448 以ä¸?æ–??" );
245 // LogWriter.log( " TEXT : 変換するæ–?—å?" );
246 System.out.println( "java HybsCryptography KEY TEXT" );
247 System.out.println( " KEY : 秘å¯?�µ(8 の倍数 (32 以ä¸?448 以ä¸?æ–??" );
248 System.out.println( " TEXT : 変換するæ–?—å?" );
249 return;
250 }
251
252 HybsCryptography cript = new HybsCryptography( args[0] );
253
254 System.out.println( "IN TEXT : " + args[1] );
255
256 String hexa = cript.encrypt( args[1] );
257 System.out.println( "HEXA TEXT : " + hexa );
258
259 String data = cript.decrypt( hexa );
260 System.out.println( "OUT DATA : " + data );
261 }
262 }