0

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

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

しかし、long 変数をどこにどのように実装すればよいのでしょうか。byte[long] に long を入れることができません。教授によると、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());
        }
    }
4

2 に答える 2

0

あなたが尋ねていることはちょっと奇妙に思えます。ユーザーが入力したキーの長さを long に格納する必要があるという要件はありますか? これは、int が保持できる最大値である 2,147,483,647 を超える長さのキーをユーザーが要求できることを意味します。それは非常に巨大で、ばかげているように聞こえます。おそらく、long ではなく int を使用できます。20 億バイトは、約 2 GB のデータになります。

暗号化キーは通常ビット単位で指定されますが、それでも 260 MB 以上のデータになります。

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

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

以下に、実際に超巨大なキーを書き込めるようにする解決策を示しましたが、あなたが本当にそれを望んでいるとは思いません。おそらくkeySizeをintにキャストし、トトロの答えのように使用する必要があります。この答えはちょっとクレイジーですが、あなたを導き、自分が何をしているのかを再考するのに役立つはずです.

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);
}
于 2016-04-25T19:47:39.860 に答える
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());
    }
}

それが役に立てば幸い。

于 2016-04-25T18:59:08.727 に答える