2016-04-25 5 views
0

私のJavaクラスでは、私のプロジェクトの一部は、ユーザーから暗号化キーの長さを取得し、それを1024の最も近い倍数に丸めます。長さはlongとして渡されます。私の方法では、私は長いと私は書き込みするファイルパスを取得します。例では、私はこの実装を見てきました:SecureRandom()でlongに基づいてファイルにバイトを書き込むにはどうすればいいですか?nextBytes?

try (FileOutputStream out = new FileOutputStream(file)) { 
    byte[] bytes = new byte[1024]; 
    new SecureRandom().nextBytes(bytes); 
    out.write(bytes); 
} 

しかし、どこで、どのように私は私の長い変数を実装していますか?長いバイトを入れることはできません。私は私の教授に従ってSecureRandom()。nextBytes()を使う必要があることを知っています。この部分が私を夢中にさせてくれたので、どんな助けも大歓迎です。あなただけの割り当て、ループする必要はありません。ここ

は、私がこれまで持っているものですが、私は助けるが、これは私の教授はそれが行わ望んでいる道はないと思うことができない...

public void oneKeyGenerator(String keyPath, long keyLength) { 
     final long CONST_MULTIPLE = 1024; 
     try { 
      FileOutputStream out = new FileOutputStream(keyPath); 
      byte[] bytes = new byte[1024]; 
      for(long x = 0; x < keyLength/CONST_MULTIPLE; x++) { 
       new SecureRandom().nextBytes(bytes); 
       out.write(bytes); 
      } 
     } catch(IOException e){ 
      gui.fileException(e.getMessage()); 
     } 
    } 
+0

「keyLength」はバイト数またはビット数を表しますか? – totoro

+0

キーの長さを示します。これはバイト単位で格納されているファイルの長さになります。 – JoshuaRG1993

答えて

0

必要なサイズのバイト配列:

long roundNext(long v, long multiple) { 
    return ((v + multiple - 1)/multiple) * multiple; 
} 

public void oneKeyGenerator(String keyPath, long keyLength) { 
    final long CONST_MULTIPLE = 1024; 
    try { 
     FileOutputStream out = new FileOutputStream(keyPath); 
     byte[] bytes = new byte[(int) roundNext(keyLength, CONST_MULTIPLE)]; 
     new SecureRandom().nextBytes(bytes); 
     out.write(bytes); 
    } catch(IOException e){ 
     gui.fileException(e.getMessage()); 
    } 
} 

希望します。

+0

行: バイト[]バイト=新しいバイト[roundNext(keyLength、CONST_MULTIPLE)]; はエラーを返します: 互換性のない型:longからintへの不可逆変換 – JoshuaRG1993

+0

'new byte [n]'は 'n'を' int'にしようとしますが、 'keyLength'は' long'です。 'long'は' int'より大きい可能性があります。警告です。あなたの場合、 'long'は常に' int'のために十分小さくなります。 – totoro

+0

@ JoshuaRG1993私は自分の答えを編集して、以前は見たことのないint(int)roundNext(keyLength、CONST_MULTIPLE)にキャストを追加しました。 – totoro

0

あなたが求めているのは奇妙なようです。ユーザーが入力したキーの長さを長い間保存する必要があるかどうかこれは、ユーザーが、intが保持できる最大値であるので、2,147,483,647を超える長さのキーを要求できることを意味します。それは非常に巨大で、ばかげて聞こえます。あなたはたぶんintを使用することができ、長いものではありません。 20億バイトは約2GBのデータになります。

暗号化キーは通常ビットで指定されますが、それでも260 + MBのデータです。

解決するには別の問題に分解し、別の方法を作成する必要があります。

  1. 別の方法で最も近い1024の倍数を取得します。
  2. 別の方法でSecureRandomを使用して「暗号化キー」を生成します。
  3. そのキーをファイルに書き込みます。

以下では、実際にあなたが超大型キーを書くことを可能にするソリューションを入れましたが、私はあなたが本当にそれを望んでいるとは思っていません。あなたはおそらくintにkeySizeをキャストし、トトロの答えのように使うべきです。この回答は一種の狂気ですが、それはあなたを導く助けとなり、多分あなたが何をやっているのか再考させるべきです。

static final long CONST_MULTIPLE = 1024; 

private long getNearest1024Multiple(long value) 
{ 
    double divisor = value/(double)CONST_MULTIPLE; 
    int multiple = (int)Math.round(divisor); 

    if (multiple == 0) 
    { 
     multiple = 1; 
    } 

    return multiple * CONST_MULTIPLE; 
} 

private ByteArrayOutputStream generateLongEncryptionKey(long keySize) throws IOException 
{ 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    SecureRandom secureRandom = new SecureRandom(); 

    while (keySize > 0) 
    { 
     if (keySize > Integer.MAX_VALUE) 
     { 
      // The keySize long actually has a super huge value in it, so grab a chunk at a time 
      byte[] randomBytes = new byte[Integer.MAX_VALUE]; 
      secureRandom.nextBytes(randomBytes); 

      baos.write(randomBytes); 
      keySize -= Integer.MAX_VALUE; 
     } 
     else 
     { 
      // We grabbed the last chunk 
      byte[] randomBytes = new byte[(int)keySize]; 
      secureRandom.nextBytes(randomBytes); 

      baos.write(randomBytes); 
      keySize -= keySize; 
     } 
    } 

    return baos; 
} 

private void generateAndSaveKey(String keyPath, long userInputKeyLength) throws IOException 
{ 
    long roundedKeyLength = getNearest1024Multiple(userInputKeyLength); 
    ByteArrayOutputStream baos = generateLongEncryptionKey(roundedKeyLength); 

    FileOutputStream fileOutputStream = new FileOutputStream(keyPath); 
    baos.writeTo(fileOutputStream); 
} 
関連する問題