2016-04-25 1 views
0

Pour ma classe Java, une partie de mon projet consiste à obtenir une longueur de clé de chiffrement de l'utilisateur et à arrondir celle-ci au multiple de 1024 le plus proche. La longueur est passée comme longue. Dans ma méthode, je reçois le long et je reçois le chemin du fichier à écrire. Dans les exemples que j'ai vu cette implémentation:Comment écrire des octets dans un fichier basé sur un long avec SecureRandom(). NextBytes?

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

Mais où et comment puis-je implémenter ma variable longue? Je ne peux pas mettre un long octet [long]. Je sais que je dois utiliser le SecureRandom(). NextBytes() selon mon professeur. Toute aide serait grandement appréciée car cette partie m'a rendu fou.

Voici ce que j'ai jusqu'à présent, mais je ne peux pas empêcher de penser ce n'est pas la façon dont mon professeur veut faire ...

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

Est-ce que 'keyLength' indique le nombre d'octets ou de bits? – totoro

+0

Indique la longueur de la clé. Ce qui va être la longueur du fichier dans lequel il est stocké en octets. – JoshuaRG1993

Répondre

0

Vous n'avez pas à boucle, juste allouer un tableau d'octets de la taille dont vous avez besoin:

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.

+0

La ligne: octet [] octets = nouvel octet [roundNext (keyLength, CONST_MULTIPLE)]; donne l'erreur: types incompatibles: conversion avec pertes possibles de long à int – JoshuaRG1993

+0

'new byte [n]' veut 'n' être' int', mais votre 'keyLength' est' long'. 'long' peut être plus grand que' int', donc l'avertissement. Dans votre cas, votre 'long' sera toujours assez petit pour un' int'. – totoro

+0

@ JoshuaRG1993 J'ai modifié ma réponse et ajouté une distribution à int (int) roundNext (keyLength, CONST_MULTIPLE) 'que vous ne voyiez peut-être pas auparavant. – totoro

0

Ce que vous demandez semble un peu étrange. Est-ce que l'exigence que la longueur de clé entrée par l'utilisateur doit être stockée dans un long? Cela signifierait que l'utilisateur pourrait demander une clé d'une longueur supérieure à 2 147 483 647, car c'est la valeur maximale qu'un int peut contenir. Ce serait super énorme et semble ridicule. Vous pouvez probablement utiliser un int et pas longtemps. 2 milliards d'octets seraient d'environ 2 Go de données.

Les clés de cryptage sont généralement spécifiées en bits, mais tout de même, cela correspond à 260 Mo de données.

Vous devez décomposer ce problème en différents problèmes à résoudre et créer des méthodes séparées. Obtenez le multiple de 1024 le plus proche dans une méthode distincte.

  • Générez votre "clé de chiffrement" en utilisant SecureRandom dans une méthode séparée.
  • Ecrivez cette clé dans un fichier. Ci-dessous j'ai mis une solution qui vous permettrait en fait d'écrire la clé super énorme, mais je ne pense pas que vous le vouliez vraiment, c'était plus intéressant à comprendre. Vous devriez probablement lancer le keySize à un int, et l'utiliser comme dans la réponse de totoro. Cette réponse est un peu folle, mais elle devrait vous guider et peut-être vous faire réfléchir à ce que vous faites.

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