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