简体   繁体   English

如何使用SecureRandom()。nextBytes将字节写到文件中?

[英]How do I write bytes to a file based on a long with SecureRandom().nextBytes?

For my java class, part of my project involves getting a encryption key length from the user and rounding that up to the nearest multiple of 1024. The length is passed as a long. 对于我的java类,我项目的一部分涉及从用户那里获取加密密钥长度,并将其舍入到最接近的1024的倍数。该长度以长整数形式传递。 In my method I get the long and I get the file path to write to. 在我的方法中,我得到的很长,并且我得到了要写入的文件路径。 In examples I've seen this implementation: 在示例中,我看到了此实现:

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

But where and how do I implement my long variable? 但是,在哪里以及如何实现我的long变量? I can't put a long in byte[long]. 我不能在字节[long]中加长。 I know I need to used the SecureRandom().nextBytes() according to my professor. 我知道我需要根据教授使用SecureRandom()。nextBytes()。 Any help would be greatly appreciated because this part has been driving me crazy. 任何帮助将不胜感激,因为这部分一直让我发疯。

Here is what I have so far but I can't help but think this isn't the way my professor wants it done... 这是我到目前为止所拥有的,但是我忍不住认为这不是我的教授想要完成的方式...

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());
        }
    }

You don't have to loop, just allocate a byte array of the size you need: 您不必循环,只需分配所需大小的字节数组即可:

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());
    }
}

Hope it helps. 希望能帮助到你。

What you are asking seems kind of odd. 您的要求似乎有些奇怪。 Is the requirement that the user's inputted key length must be stored in a long? 是否要求用户输入的密钥长度必须存储很长? This would mean that the user could request a key that is a length greater than 2,147,483,647 since that is the max value an int can hold. 这将意味着用户可以请求一个长度大于2,147,483,647的密钥,因为这是int可以容纳的最大值。 That would be super huge and sounds ridiculous. 那将是巨大的,听起来很荒谬。 You can probably just use an int and not a long. 您可能只能使用int而不是long。 2 Billion Bytes would be around 2 GB of data. 20亿字节大约需要2 GB的数据。

Encryption keys are usually specified in bits, but still, that would be 260+ MB of data. 加密密钥通常以位指定,但是仍然是260+ MB的数据。

You need to break this down into separate problems to solve, and create separate methods. 您需要将其分解为单独的问题来解决,并创建单独的方法。

  1. Get the nearest 1024 multiple in a separate method. 用单独的方法获取最接近的1024倍数。
  2. Generate your "encryption key" using SecureRandom in a separate method. 使用SecureRandom在另一种方法中生成“加密密钥”。
  3. Write that key to a file. 将该密钥写入文件。

Below I have put a solution that would actually allow you to write the super huge key, but I don't think you really want that, it was more interesting to figure out. 下面,我提出了一个解决方案,该解决方案实际上可以让您编写超级大密钥,但是我认为您并不是真的想要这样做,弄清楚它会更有趣。 You should probably just cast the keySize to an int, and use it like in totoro's answer. 您可能应该将keySize强制转换为int,然后像在totoro的答案中一样使用它。 This answer is kind of crazy, but it should help guide you and maybe make you re-think what you are doing. 这个答案有点疯狂,但是它应该可以帮助您,甚至可以让您重新思考自己在做什么。

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM