0

对于我的 java 类,我的项目的一部分涉及从用户获取加密密钥长度并将其四舍五入到最接近的 1024 倍数。长度作为 long 传递。在我的方法中,我得到了 long 并且得到了要写入的文件路径。在示例中,我看到了这种实现:

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

但是我在哪里以及如何实现我的长变量?我不能在 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 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 回答
0

你问的似乎有点奇怪。是否要求用户输入的密钥长度必须长存储?这意味着用户可以请求长度大于 2,147,483,647 的密钥,因为这是 int 可以容纳的最大值。那将是超级巨大的,听起来很荒谬。您可能只使用 int 而不是 long。20 亿字节大约是 2 GB 的数据。

加密密钥通常以位为单位指定,但仍然是 260+ MB 的数据。

您需要将其分解为单独的问题来解决,并创建单独的方法。

  1. 在单独的方法中获取最接近的 1024 倍数。
  2. 在单独的方法中使用 SecureRandom 生成您的“加密密钥”。
  3. 将该密钥写入文件。

下面我提出了一个解决方案,它实际上可以让你编写超级大密钥,但我认为你并不是真的想要那样,弄清楚它更有趣。您可能应该将 keySize 转换为 int,并像在 totoro 的答案中一样使用它。这个答案有点疯狂,但它应该有助于指导你,也许会让你重新思考你在做什么。

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 回答