2016-05-15 7 views
1

SecureRandomを使用して秘密鍵を生成する方法。 getInstanceStrong()SecureRandom.getInstanceStrong()を使って秘密鍵を生成するには?

このコードでは、ランダムな値を持つバイト配列を受け取ることができます。 (ビット)、タイプ(int、文字列)、フォーマット(hex、bin、dec)のキーを生成する簡単な方法はありますか?

package com.company; 

import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 

public class KeyGen { 

    public void generate() throws NoSuchAlgorithmException { 

     SecureRandom random = SecureRandom.getInstanceStrong(); 
     byte[] values = new byte[32]; // 256 bit 
     random.nextBytes(values); 

     StringBuilder sb = new StringBuilder(); 
     for (byte b : values) { 
      sb.append(String.format("%02x", b)); 
     } 
     System.out.print("Key: "); 
     System.out.println(sb.toString()); 
    } 
} 

出力:

Key: 8fcea84897f48f575c22441ece4e7ddb43ac08cd2c1a83fca46c080768468059

+0

実際にあなたのパッケージ名は 'com.pany'です。 –

+0

@MaartenBodewes IntelliJ IDEAのデフォルトテンプレートです。 –

+0

ああ、OK、デフォルトではEclipseを使っていましたが、それは分かりませんでした。あなた自身の暗号では、あなたの現在のコードでは間違っているようには見えません。あなたは鍵管理について考えるかもしれません。ランダムキーを何らかのコンテナに置くことは、良いアイデアか、教師の公開PGPキーで暗号化することができます(Bouncy Castle機能など)。 –

答えて

0

キーは、例えば、特定のタイプのものであるべきですAES。それらは好ましくはSecretKeyインスタンスまたは同様のKey派生クラスの内部に保持される必要があります。

最新の対称暗号の鍵はビットで構成されています。通常は、それらの人間/文字列表現は必要ありません(そして、これは実際にセキュリティに害を与える可能性があります)。 KeyStoreに保存するか、代わりにパスワードから派生させてください。エンコードする場合、変換中にデータを失わない限り、表現形式は重要ではありません。

これはおそらく、強力なAESキーを生成するための最良の方法である:

public class GenerateStrongAESKey { 

    public static SecretKey generateStrongAESKey(final int keysize) { 
     final KeyGenerator kgen; 
     try { 
      kgen = KeyGenerator.getInstance("AES"); 
     } catch (final NoSuchAlgorithmException e) { 
      throw new RuntimeException("AES key generator should always be available in a Java runtime", e); 
     } 
     final SecureRandom rng; 
     try { 
      rng = SecureRandom.getInstanceStrong(); 
     } catch (final NoSuchAlgorithmException e) { 
      throw new RuntimeException("No strong secure random available to generate strong AES key", e); 
     } 
     // already throws IllegalParameterException for wrong key sizes 
     kgen.init(keysize, rng); 

     return kgen.generateKey(); 
    } 

    public static void main(String[] args) { 
     SecretKey strongAESKey = generateStrongAESKey(256); 
     // well, if you must have a human readable string, here it is 
     // but you've been warned 
     System.out.println(toHex(strongAESKey.getEncoded())); 
    } 

    private static String toHex(final byte[] data) { 
     final StringBuilder sb = new StringBuilder(data.length * 2); 
     for (byte b : data) { 
      sb.append(String.format("%02X", b)); 
     } 
     return sb.toString(); 
    } 
} 

注:これは、キー> 128ビットのOracleランタイム環境のための無制限強度管轄ファイルを必要とします。

+0

私はGOST/Magmaブロック暗号の実現に '人間が読める文字列 'が必要です。私の場合は、教師に暗号鍵を提示する必要があります。または何とか彼を救うために。 –

+0

しかし、同じ(?)結果が得られれば、あなたのコードと私の基本的な違いは何かを完全に理解できません。 –

+0

違いは、あなたのコードは単純にバイト配列を使用していますが、私の場合はJCEが使用されています。出力値は同じ(または少なくとも同じ種類のランダム)でもかまいませんが、上記のコードではキーが保護されている場合や、利用可能な場合にはハードウェアデバイスを使用する場合があります。もちろん、自作の暗号の鍵を生成したい場合はあまり役に立ちません。その場合、コードに間違いはほとんどありません。前述の通り、Javaは幸いにも16進数や人間が読める他の文字列を(安全でない)デフォルトとして出力しません。 –

関連する問題