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 */
016package org.opengion.fukurou.security;
017
018import java.io.File;
019import java.io.FileInputStream;
020import java.io.InputStream;                                                                     // 5.10.9.0 (2019/03/01)
021import java.io.IOException;
022import java.nio.ByteBuffer;                                                                     // 5.5.2.6 (2012/05/25)
023import java.nio.channels.FileChannel;                                           // 5.7.2.1 (2014/01/17)
024import java.nio.charset.Charset;                                                        // 5.5.2.6 (2012/05/25)
025import org.opengion.fukurou.system.Closer;                                      // 5.5.2.6 (2012/05/25)
026import org.opengion.fukurou.system.OgRuntimeException ;         // 6.4.2.0 (2016/01/29)
027import org.opengion.fukurou.model.FileOperation;                        // 5.10.9.0 (2019/03/01)
028import static org.opengion.fukurou.system.HybsConst.CR;         // 8.1.2.0 (2022/03/10)
029
030import javax.crypto.spec.SecretKeySpec;
031import javax.crypto.Cipher;
032
033import java.security.MessageDigest;
034import java.security.NoSuchAlgorithmException;
035import java.security.GeneralSecurityException;                          // 5.7.2.1 (2014/01/17)
036import java.security.DigestInputStream;                                         // 5.10.9.0 (2019/03/01)
037
038/**
039 * HybsCryptography は、セキュリティ強化の為の Hybs独自の暗号化クラスです。
040 *
041 * このクラスは、暗号化キーを受け取り、それに基づいて暗号化/復号化を行います。
042 * ここでの暗号化は、秘密キー方式でバイト文字列に変換されたものを、16進アスキー文字に
043 * 直して、扱っています。よって、暗号化/復号化共に、文字列として扱うことが可能です。
044 *
045 * @og.rev 4.0.0.0 (2005/08/31) 新規追加
046 * @og.rev 5.9.10.0 (2019/03/01) クラウドストレージ対応を追加。(Fileクラスを拡張)
047 *
048 * @og.group ライセンス管理
049 *
050 * @version  4.0
051 * @author   Kazuhiko Hasegawa
052 * @since    JDK5.0,
053 */
054public final class HybsCryptography {
055        private final SecretKeySpec sksSpec ;
056        private static final String CIPHER_TYPE = "Blowfish" ;
057
058        /**
059         * 数字から16進文字に変換するテーブルです。
060         */
061        private static final char[] HEXA_DECIMAL =
062                { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
063                  'a', 'b', 'c', 'd', 'e', 'f' };
064
065        /**
066         * プラットフォーム依存のデフォルトの Charset です。
067         * プラットフォーム依存性を考慮する場合、エンコード指定で作成しておく事をお勧めします。
068         *
069         * @og.rev 5.5.2.6 (2012/05/25) findbugs対応
070         */
071        private static final Charset DEFAULT_CHARSET = Charset.defaultCharset() ;
072
073        // 注意:秘密キーは、8の倍数でないといけない。
074        private static final String HYBS_CRYPT_KEY = "2a5a88891d37ae59" ;
075
076        /**
077         * 内部設定の秘密鍵を使用して、暗号化を行うオブジェクトを構築します。
078         * ここでの暗号化は、Java標準のセキュリティパッケージを使用しています。
079         *
080         * @og.rev 6.2.5.0 (2015/06/05) 引数付コンストラクタを使用
081         */
082        public HybsCryptography() {
083                this( HYBS_CRYPT_KEY );
084        }
085
086        /**
087         * 秘密鍵の文字列を受け取って、暗号化を行うオブジェクトを構築します。
088         * ここでの暗号化は、Java標準のセキュリティパッケージを使用しています。
089         * 秘密鍵のサイズを、8 の倍数 (32 以上 448 以下) にする必要があります。
090         *
091         * @og.rev 5.8.8.0 (2015/06/05) null時の挙動はデフォルトキーを利用する
092         *
093         * @param       cryptKey        暗号化を行う秘密鍵
094         */
095        public HybsCryptography( final String cryptKey ) {
096                // 5.8.8.0 (2015/06/05) null時はデフォルトキーを利用
097                final String useKey;
098                if( cryptKey == null || cryptKey.length() == 0 ){
099                        useKey = HYBS_CRYPT_KEY;
100                }
101                else{
102                        useKey = cryptKey;
103                }
104                sksSpec = new SecretKeySpec( useKey.getBytes( DEFAULT_CHARSET ), CIPHER_TYPE );
105        }
106
107        /**
108         * セキュリティカラムのDBTyepに対してHybs独自の暗号化を行います。
109         * 暗号化されたデータは、通常 byte 文字ですが、16進数アスキー文字列に変換
110         * したものを返します。
111         * この暗号化では、引数が null の場合は、ゼロ文字列を返します。
112         *
113         * @og.rev 5.7.2.1 (2014/01/17) Exceptionをまとめます。
114         *
115         * @param       org     暗号化を行う元の文字列
116         *
117         * @return      暗号化された文字列(HEXADECIMAL化)
118         * @og.rtnNotNull
119         */
120        public String encrypt( final String org ) {
121                if( org == null || org.isEmpty() ) { return ""; }
122
123                try {
124                        final Cipher cipher = Cipher.getInstance( CIPHER_TYPE );
125                        cipher.init( Cipher.ENCRYPT_MODE, sksSpec );
126                        final byte[] encrypted = cipher.doFinal( org.getBytes( DEFAULT_CHARSET ) );             // 5.5.2.6 (2012/05/25) findbugs対応
127
128                        return byte2hexa( encrypted );
129                }
130                // 5.7.2.1 (2014/01/17) Exceptionをまとめます。
131                catch( final GeneralSecurityException   ex ) {
132                        final String errMsg = "暗号化処理に失敗しました。[" + org + "]"
133                                                        + ex.getMessage() ;
134                        throw new OgRuntimeException( errMsg,ex );
135                }
136        }
137
138        /**
139         * セキュリティカラムのDBTyepに対してHybs独自の復号化を行います。
140         * ここでの復号化は、encrypt で暗号化された文字を戻す場合に使用します。
141         * この復号化では、null は復号化できないため、ゼロ文字列を返します。
142         *
143         * @og.rev 5.7.2.1 (2014/01/17) Exceptionをまとめます。
144         *
145         * @param       hex     復号化を行う暗号化された16進数アスキー文字列
146         *
147         * @return      復号化された元の文字列
148         * @og.rtnNotNull
149         */
150        public String decrypt( final String hex ) {
151                if( hex == null || hex.isEmpty() ) { return ""; }
152
153                try {
154                        final Cipher cipher = Cipher.getInstance( CIPHER_TYPE );
155                        cipher.init( Cipher.DECRYPT_MODE, sksSpec );
156                        final byte[] encrypted = hexa2byte( hex );
157                        final byte[] decrypted = cipher.doFinal( encrypted );
158                        return new String( decrypted,DEFAULT_CHARSET );         // 5.5.2.6 (2012/05/25) findbugs対応
159                }
160                // 5.7.2.1 (2014/01/17) Exceptionをまとめます。
161                catch( final GeneralSecurityException   ex ) {
162                        final String errMsg = "復号化処理に失敗しました。[" + hex + "]"
163                                                        + ex.getMessage() ;
164                        throw new OgRuntimeException( errMsg,ex );
165                }
166        }
167
168        /**
169         * バイト配列を16進数アスキー文字列に変換します。
170         *
171         * バイト配列を、2文字の0~9,a~fのアスキーに変換されます。
172         * これにより、すべての文字を、アスキー化できます。
173         * アスキー化で、上位が0F以下の場合でも、0 を出すことで、固定長に変換します。
174         *
175         * よって、入力バイトの2倍のlength()を持ったStringを作成します。
176         *
177         * @param       input バイト配列
178         *
179         * @return      16進数アスキー文字列
180         */
181        public static String byte2hexa( final byte[] input ) {
182                String rtn = null;
183                if( input != null && input.length > 0 ) {
184                        final int len = input.length ;
185                        char[] ch = new char[len*2];
186                        for( int i=0; i<len; i++ ) {
187                                final int high = (input[i] & 0xf0) >> 4 ;
188                                final int low  = input[i] & 0x0f ;
189                                ch[i*2]   = HEXA_DECIMAL[high];
190                                ch[i*2+1] = HEXA_DECIMAL[low];
191                        }
192                        rtn =  new String(ch);
193                }
194                return rtn;
195        }
196
197        /**
198         * 16進数アスキー文字列をバイト配列に変換します。
199         *
200         * 2文字の0~9,a~fのアスキー文字列を、バイト配列に変換されます。
201         *
202         * よって、入力Stringの1/2倍のlengthを持ったバイト配列を作成します。
203         *
204         * @param       input 16進数アスキー文字列
205         *
206         * @return      バイト配列
207         */
208        public static byte[] hexa2byte( final String input ) {
209                byte[] rtn = null;
210                if( input != null ) {
211                        final int len = input.length() ;
212                        rtn = new byte[len/2];
213                        for( int i=0; i<len/2; i++ ) {
214                                char ch = input.charAt( i*2 );
215                                final int high = ch < 'a' ? ch-'0' : ch-'a'+10 ;
216                                ch = input.charAt( i*2+1 );
217                                final int low  = ch < 'a' ? ch-'0' : ch-'a'+10 ;
218                                rtn[i] = (byte)(high << 4 | low);
219                        }
220                }
221                return rtn;
222        }
223
224        /**
225         * MessageDigestにより、システム定数に定義されている ハッシュコード で
226         * ハッシュした文字に変換します。
227         *
228         * 連結後の文字列長は、ハッシュコードにより異なります。
229         *
230         * @og.rev 8.1.2.0 (2022/03/10) getMD5参照して新規作成
231         *
232         * @param       hashCode        ハッシュコード (MD5, SHA-1, SHA-256, SHA-512)
233         * @param       input           変換前の文字列
234         *
235         * @return      ハッシュコードでハッシュした文字列
236         */
237        public static String getHash( final String hashCode, final String input ) {
238                String rtn = null;
239                if( hashCode != null && input != null ) {
240                        try {
241                                final MessageDigest md = MessageDigest.getInstance( hashCode );
242                                md.update( input.getBytes( DEFAULT_CHARSET ) );                         // 5.5.2.6 (2012/05/25) findbugs対応
243                                final byte[] out = md.digest();
244                                rtn = byte2hexa( out );
245                        }
246                        catch( final NoSuchAlgorithmException ex ) {
247                                final String errMsg = "MessageDigestで失敗しました。" + CR
248                                                        + "ハッシュコード=[" + hashCode + "] , 変換前=[" + input + "]" + CR
249                                                        + ex.getMessage() ;
250                                throw new OgRuntimeException( errMsg,ex );
251                        }
252                }
253                return rtn;
254        }
255
256        /**
257         * MessageDigestにより、システム定数に定義されている ハッシュコード で
258         * ハッシュした文字に変換します。
259         *
260         * 連結後の文字列長は、ハッシュコードにより異なります。
261         *
262         * @og.rev 8.1.2.0 (2022/03/10) getMD5参照して新規作成
263         *
264         * @param       hashCode        ハッシュコード (MD5, SHA-1, SHA-256, SHA-512)
265         * @param       input           変換前のFileOperationオブジェクト
266         *
267         * @return      ハッシュコードでハッシュした文字列
268         */
269        public static String getHash( final String hashCode, final FileOperation input ) {
270                String rtn = null;
271                if( hashCode != null && input != null ) {
272                        InputStream is = null;
273                        DigestInputStream dis = null;
274                        try {
275                                final MessageDigest md = MessageDigest.getInstance( hashCode );
276                                is = input.read();
277                                dis = new DigestInputStream(is, md);
278
279                                final byte[] readBuf = new byte[1024];
280                                while(dis.read(readBuf) > 0) {
281                                        ;       // disを読み込んで、ダイジェスト情報を更新
282                                }
283
284                                // ダイジェスト情報を取得
285                                final byte[] out = md.digest();
286                                rtn = byte2hexa( out );
287                        }
288                        catch( NoSuchAlgorithmException ex ) {
289                                final String errMsg = "MessageDigestで失敗しました。" + CR
290                                                        + "ハッシュコード=[" + hashCode + "] , 変換前=[" + input + "]" + CR
291                                                        + ex.getMessage() ;
292                                throw new RuntimeException( errMsg,ex );
293                        }
294                        catch( IOException ex ) {
295                                final String errMsg = "ファイルの読み取りを失敗しました。[" + input + "]"
296                                                        + ex.getMessage() ;
297                                throw new RuntimeException( errMsg,ex );
298                        }
299                        finally {
300                                Closer.ioClose(dis);
301                                Closer.ioClose(is);
302                        }
303                }
304                return rtn;
305        }
306
307        /**
308         * MessageDigestにより、システム定数に定義されている ハッシュコード で
309         * ハッシュした文字に変換します。
310         *
311         * 連結後の文字列長は、ハッシュコードにより異なります。
312         *
313         * @og.rev 8.1.2.0 (2022/03/10) getMD5参照して新規作成
314         *
315         * @param       hashCode        ハッシュコード (MD5, SHA-1, SHA-256, SHA-512)
316         * @param       input           変換前のFile
317         *
318         * @return      ハッシュコードでハッシュした文字列
319         */
320        public static String getHash( final String hashCode, final File input ) {
321                // 2019/X FileOperationクラスの場合は、クラウドストレージ対応のメソッドを実行します。 oota tmp
322                if( input instanceof FileOperation ) {
323                        return getHash( hashCode, (FileOperation)input );
324                }
325
326                String rtn = null;
327                if( hashCode != null && input != null ) {
328                        FileInputStream fis     = null;
329                        FileChannel             fc      = null;
330                        try {
331                                final MessageDigest md = MessageDigest.getInstance( hashCode );
332                                fis = new FileInputStream( input );
333                                fc  =fis.getChannel();
334                                final ByteBuffer bb = fc.map( FileChannel.MapMode.READ_ONLY , 0L , fc.size() );
335                                md.update( bb );
336                                final byte[] out = md.digest();
337                                rtn = byte2hexa( out );
338                        }
339                        catch( final NoSuchAlgorithmException ex ) {
340                                final String errMsg = "MessageDigestで失敗しました。" + CR
341                                                        + "ハッシュコード=[" + hashCode + "] , 変換前=[" + input + "]" + CR
342                                                        + ex.getMessage() ;
343                                throw new OgRuntimeException( errMsg,ex );
344                        }
345                        catch( final IOException ex ) {
346                                final String errMsg = "ファイルの読み取りを失敗しました。[" + input + "]"
347                                                        + ex.getMessage() ;
348                                throw new OgRuntimeException( errMsg,ex );
349                        }
350                        finally {
351                                Closer.ioClose( fc );
352                                Closer.ioClose( fis );
353                        }
354                }
355                return rtn;
356        }
357
358        // 8.1.2.0 (2022/03/10) Delete
359//      /**
360//       * MessageDigestにより、MD5 でハッシュした文字に変換します。
361//       *
362//       * MD5で、16Byteのバイトに変換されますが、ここでは、16進数で文字列に変換しています。
363//       *
364//       * 変換方法は、各バイトの上位/下位を16進文字列に変換後、連結しています。
365//       * これは、Tomcat等の digest 認証(MD5使用時)と同じ変換方式です。
366//       * 連結後の文字列長は、32バイト(固定)になります。
367//       *
368//       * @og.rev 5.2.2.0 (2010/11/01) util.StringUtil から移動
369//       *
370//       * @param       input 変換前の文字列
371//       *
372//       * @return      MD5でハッシュした文字列。32バイト(固定)
373//       */
374//      public static String getMD5( final String input ) {
375//              String rtn = null;
376//              if( input != null ) {
377//                      try {
378//                              final MessageDigest md5 = MessageDigest.getInstance( "MD5" );
379//                              md5.update( input.getBytes( DEFAULT_CHARSET ) );        // 5.5.2.6 (2012/05/25) findbugs対応
380//                              final byte[] out = md5.digest();
381//                              rtn = byte2hexa( out );
382//                      }
383//                      catch( final NoSuchAlgorithmException ex ) {
384//                              final String errMsg = "MessageDigestで失敗しました。[" + input + "]"
385//                                                      + ex.getMessage() ;
386//                              throw new OgRuntimeException( errMsg,ex );
387//                      }
388//              }
389//              return rtn;
390//      }
391
392        // 8.1.2.0 (2022/03/10) Delete
393//      /**
394//       * MessageDigestにより、MD5 でハッシュした文字に変換します。
395//       *
396//       * MD5で、16Byteのバイトに変換されますが、ここでは、16進数で文字列に変換しています。
397//       *
398//       * 変換方法は、各バイトの上位/下位を16進文字列に変換後、連結しています。
399//       * これは、Tomcat等の digest 認証(MD5使用時)と同じ変換方式です。
400//       * 連結後の文字列長は、32バイト(固定)になります。
401//       * 下記サイトを参考に作成しています。
402//       * https://stackoverflow.com/questions/304268/getting-a-files-md5-checksum-in-java
403//       *
404//       * @og.rev 5.9.10.0 (2019/03/01) 新規追加。クラウドストレージ対応。
405//       *
406//       * @param       input 変換前のFileOperationオブジェクト
407//       *
408//       * @return      MD5でハッシュした文字列。32バイト(固定)
409//       */
410//      public static String getMD5( final FileOperation input ) {
411//              String rtn = null;
412//              if( input != null ) {
413//
414//                      InputStream is = null;
415//                      DigestInputStream dis = null;
416//                      try {
417//                              final MessageDigest md5 = MessageDigest.getInstance( "MD5" );
418//                              is = input.read();
419//                              dis = new DigestInputStream(is, md5);
420//
421//                              while(dis.read() > 0) {
422//                                      ;       // disを読み込んで、ダイジェスト情報を更新
423//                              }
424//
425//                              // ダイジェスト情報を取得
426//                              final byte[] out = md5.digest();
427//                              rtn = byte2hexa( out );
428//                      }
429//                      catch( NoSuchAlgorithmException ex ) {
430//                              final String errMsg = "MessageDigestで MD5 インスタンスの作成に失敗しました。[" + input + "]"
431//                                                      + ex.getMessage() ;
432//                              throw new RuntimeException( errMsg,ex );
433//                      }
434//                      catch( IOException ex ) {
435//                              final String errMsg = "ファイルの読み取りを失敗しました。[" + input + "]"
436//                                                      + ex.getMessage() ;
437//                              throw new RuntimeException( errMsg,ex );
438//                      }
439//                      finally {
440//                              Closer.ioClose(dis);
441//                              Closer.ioClose(is);
442//                      }
443//              }
444//              return rtn;
445//      }
446
447        // 8.1.2.0 (2022/03/10) Delete
448//      /**
449//       * MessageDigestにより、MD5 でハッシュした文字に変換します。
450//       *
451//       * MD5で、16Byteのバイトに変換されますが、ここでは、16進数で文字列に変換しています。
452//       *
453//       * 変換方法は、各バイトの上位/下位を16進文字列に変換後、連結しています。
454//       * これは、Tomcat等の digest 認証(MD5使用時)と同じ変換方式です。
455//       * 連結後の文字列長は、32バイト(固定)になります。
456//       *
457//       * @og.rev 5.7.2.1 (2014/01/17) Exceptionをまとめます。
458//       * @og.rev 5.9.10.0 (2019/03/01) クラウドストレージ対応を追加
459//       *
460//       * @param       input 変換前のFile
461//       *
462//       * @return      MD5でハッシュした文字列。32バイト(固定)
463//       */
464//      public static String getMD5( final File input ) {
465//              // 2019/X FileOperationクラスの場合は、クラウドストレージ対応のメソッドを実行します。 oota tmp
466//              if(input instanceof FileOperation) {
467//                      return getMD5((FileOperation)input);
468//              }
469//
470//              String rtn = null;
471//              if( input != null ) {
472//                      FileInputStream fis     = null;
473//                      FileChannel             fc      = null;
474//                      try {
475//                              final MessageDigest md5 = MessageDigest.getInstance( "MD5" );
476//                              fis = new FileInputStream( input );
477//                              fc  =fis.getChannel();
478//                              final ByteBuffer bb = fc.map( FileChannel.MapMode.READ_ONLY , 0L , fc.size() );
479//                              md5.update( bb );
480//                              final byte[] out = md5.digest();
481//                              rtn = byte2hexa( out );
482//                      }
483//                      catch( final NoSuchAlgorithmException ex ) {
484//                              final String errMsg = "MessageDigestで MD5 インスタンスの作成に失敗しました。[" + input + "]"
485//                                                      + ex.getMessage() ;
486//                              throw new OgRuntimeException( errMsg,ex );
487//                      }
488//                      catch( final IOException ex ) {
489//                              final String errMsg = "ファイルの読み取りを失敗しました。[" + input + "]"
490//                                                      + ex.getMessage() ;
491//                              throw new OgRuntimeException( errMsg,ex );
492//                      }
493//                      finally {
494//                              Closer.ioClose( fc );
495//                              Closer.ioClose( fis );
496//                      }
497//              }
498//              return rtn;
499//      }
500
501//      /**
502//       * MessageDigestにより、SHA1 でハッシュした文字に変換します。
503//       *
504//       * 16進数で文字列に変換しています。
505//       *
506//       * 変換方法は、各バイトの上位/下位を16進文字列に変換後、連結しています。
507//       * これは、Tomcat等の digest 認証と同じ変換方式です。
508//       *
509//       * @og.rev 5.9.27.1 (2010/12/08) 新規作成
510//       *
511//       * @param       input 変換前の文字列
512//       *
513//       * @return      SHA1でハッシュした文字列。32バイト(固定)
514//       */
515//      public static String getSHA1( final String input ) {
516//              String rtn = null;
517//              if( input != null ) {
518//                      try {
519//                              final MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
520//                              sha1.update( input.getBytes( DEFAULT_CHARSET ) );
521//                              final byte[] out = sha1.digest();
522//                              rtn = byte2hexa( out );
523//                      }
524//                      catch( final NoSuchAlgorithmException ex ) {
525//                              final String errMsg = "MessageDigestで失敗しました。[" + input + "]"
526//                                                                              + ex.getMessage() ;
527//                              throw new RuntimeException( errMsg,ex );
528//                      }
529//              }
530//              return rtn;
531//      }
532
533        // 8.1.2.0 (2022/03/10) Delete
534//      /**
535//       * MessageDigestにより、SHA-512 でハッシュした文字に変換します。
536//       *
537//       * 16進数で文字列に変換しています。
538//       *
539//       * 変換方法は、各バイトの上位/下位を16進文字列に変換後、連結しています。
540//       * これは、Tomcat等の digest 認証と同じ変換方式です。
541//       *
542//       * @og.rev 5.10.10.2 (2019/04/12) 新規作成
543//       *
544//       * @param       input 変換前の文字列
545//       *
546//       * @return      SHA-512でハッシュした文字列 128バイト
547//       */
548//      public static String getSHA512( final String input ) {
549//              String rtn = null;
550//              if( input != null ) {
551//                      try {
552//                              final MessageDigest sha1 = MessageDigest.getInstance("SHA-512");
553//                              sha1.update( input.getBytes( DEFAULT_CHARSET ) );
554//                              final byte[] out = sha1.digest();
555//                              rtn = byte2hexa( out );
556//                      }
557//                      catch( final NoSuchAlgorithmException ex ) {
558//                              final String errMsg = "MessageDigestで失敗しました。[" + input + "]"
559//                                                      + ex.getMessage() ;
560//                              throw new RuntimeException( errMsg,ex );
561//                      }
562//              }
563//              return rtn;
564//      }
565
566        /**
567         * 暗号化のテストを行う為のメインメソッド
568         *
569         * java HybsCryptography KEY TEXT で起動します。
570         *   KEY  : 秘密鍵(8 の倍数 (32 以上 448 以下)文字)
571         *   TEXT : 変換する文字列
572         *
573         * @og.rev 5.2.2.0 (2010/11/01) 循環参照の解消(LogWriter 削除)
574         *
575         * @param       args    引数配列
576         */
577        public static void main( final String[] args ) {
578                if( args.length != 2 ) {
579                        System.out.println( "java HybsCryptography KEY TEXT" );
580                        System.out.println( "  KEY  : 秘密鍵(8 の倍数 (32 以上 448 以下)文字)" );
581                        System.out.println( "  TEXT : 変換する文字列" );
582                        return;
583                }
584
585                final HybsCryptography cript = new HybsCryptography( args[0] );
586
587                System.out.println( "IN   TEXT : " + args[1] );
588
589                final String hexa = cript.encrypt( args[1] );
590                System.out.println( "HEXA TEXT : " + hexa );
591
592                final String data = cript.decrypt( hexa );
593                System.out.println( "OUT  DATA : " + data );
594        }
595}