Frage Java AES und benutze meinen eigenen Key


Ich möchte eine Zeichenfolge mit AES mit meinem eigenen Schlüssel verschlüsseln. Aber ich habe Probleme mit der Bitlänge des Schlüssels. Können Sie meinen Code überprüfen und sehen, was ich reparieren / ändern muss?

public static void main(String[] args) throws Exception {
    String username = "bob@google.org";
    String password = "Password1";
    String secretID = "BlahBlahBlah";
    String SALT2 = "deliciously salty";

    // Get the Key
    byte[] key = (SALT2 + username + password).getBytes();
    System.out.println((SALT2 + username + password).getBytes().length);

    // Need to pad key for AES
    // TODO: Best way?

    // Generate the secret key specs.
    SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

    // Instantiate the cipher
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

    byte[] encrypted = cipher.doFinal((secrectID).getBytes());
    System.out.println("encrypted string: " + asHex(encrypted));

    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
    byte[] original = cipher.doFinal(encrypted);
    String originalString = new String(original);
    System.out.println("Original string: " + originalString + "\nOriginal string (Hex): " + asHex(original));
}

Gerade jetzt bekomme ich eine Ausnahme "Ungültige AES-Schlüssellänge: 86 Byte". Muss ich meinen Schlüssel auffüllen? Wie soll ich das machen?

Muss ich auch etwas für EZB oder CBC setzen?

Vielen Dank


75
2017-08-10 17:24


Ursprung


Antworten:


Sie sollten SHA-1 verwenden, um einen Hash von Ihrem Schlüssel zu generieren und das Ergebnis auf 128 Bit (16 Byte) zu trimmen.

Außerdem generieren Sie keine Byte-Arrays von Strings bis getBytes () Es verwendet den Standard-Charset der Plattform. Das Passwort "blaöä" führt also zu unterschiedlichen Byte-Arrays auf verschiedenen Plattformen.

byte[] key = (SALT2 + username + password).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit

SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

Bearbeiten: Wenn Sie 256 Bit als Schlüsselgröße benötigen, müssen Sie die "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" herunterladen. Oracle Download-Link, verwende SHA-256 als Hash und entferne die Arrays.copyOf Linie. "ECB" ist der Standard-Cipher-Modus und "PKCS5Padding" das Standard-Padding. Sie könnten verschiedene Cipher Modes und Padding Modes durch die Cipher.getInstance string mit folgendem Format: "Cipher / Mode / Padding"

Für AES, die CTS und PKCS5Padding verwenden, lautet die Zeichenfolge: "AES / CTS / PKCS5Padding"


112
2017-08-10 19:21



Sie sollten einen KeyGenerator verwenden, um den Schlüssel zu generieren,

AES-Schlüssellängen sind 128, 192 und 256 Bit, abhängig von der Chiffre, die Sie verwenden möchten.

Sehen Sie sich das Tutorial an Hier 

Hier ist der Code für die passwortbasierte Verschlüsselung. Hier wird das Passwort über System.in eingegeben. Sie können dies ändern, um ein gespeichertes Passwort zu verwenden, wenn Sie möchten.

        PBEKeySpec pbeKeySpec;
        PBEParameterSpec pbeParamSpec;
        SecretKeyFactory keyFac;

        // Salt
        byte[] salt = {
            (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
            (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
        };

        // Iteration count
        int count = 20;

        // Create PBE parameter set
        pbeParamSpec = new PBEParameterSpec(salt, count);

        // Prompt user for encryption password.
        // Collect user password as char array (using the
        // "readPassword" method from above), and convert
        // it into a SecretKey object, using a PBE key
        // factory.
        System.out.print("Enter encryption password:  ");
        System.out.flush();
        pbeKeySpec = new PBEKeySpec(readPassword(System.in));
        keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

        // Create PBE Cipher
        Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");

        // Initialize PBE Cipher with key and parameters
        pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

        // Our cleartext
        byte[] cleartext = "This is another example".getBytes();

        // Encrypt the cleartext
        byte[] ciphertext = pbeCipher.doFinal(cleartext);

13
2017-08-10 17:43



import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.*;
import java.io.BufferedReader;
import java.io.FileReader;

public class AESFile 
{
private static String algorithm = "AES";
private static byte[] keyValue=new byte[] {'0','2','3','4','5','6','7','8','9','1','2','3','4','5','6','7'};// your key

    // Performs Encryption
    public static String encrypt(String plainText) throws Exception 
    {
            Key key = generateKey();
            Cipher chiper = Cipher.getInstance(algorithm);
            chiper.init(Cipher.ENCRYPT_MODE, key);
            byte[] encVal = chiper.doFinal(plainText.getBytes());
            String encryptedValue = new BASE64Encoder().encode(encVal);
            return encryptedValue;
    }

    // Performs decryption
    public static String decrypt(String encryptedText) throws Exception 
    {
            // generate key 
            Key key = generateKey();
            Cipher chiper = Cipher.getInstance(algorithm);
            chiper.init(Cipher.DECRYPT_MODE, key);
            byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedText);
            byte[] decValue = chiper.doFinal(decordedValue);
            String decryptedValue = new String(decValue);
            return decryptedValue;
    }

//generateKey() is used to generate a secret key for AES algorithm
    private static Key generateKey() throws Exception 
    {
            Key key = new SecretKeySpec(keyValue, algorithm);
            return key;
    }

    // performs encryption & decryption 
    public static void main(String[] args) throws Exception 
    {
        FileReader file = new FileReader("C://myprograms//plaintext.txt");
        BufferedReader reader = new BufferedReader(file);
        String text = "";
        String line = reader.readLine();
    while(line!= null)
        {
            text += line;
    line = reader.readLine();
        }
        reader.close();
    System.out.println(text);

            String plainText = text;
            String encryptedText = AESFile.encrypt(plainText);
            String decryptedText = AESFile.decrypt(encryptedText);

            System.out.println("Plain Text : " + plainText);
            System.out.println("Encrypted Text : " + encryptedText);
            System.out.println("Decrypted Text : " + decryptedText);
    }
}

5
2017-12-24 10:41



Das wird funktionieren.

public class CryptoUtils {

    private  final String TRANSFORMATION = "AES";
    private  final String encodekey = "1234543444555666";
    public  String encrypt(String inputFile)
            throws CryptoException {
        return doEncrypt(encodekey, inputFile);
    }


    public  String decrypt(String input)
            throws CryptoException {
    // return  doCrypto(Cipher.DECRYPT_MODE, key, inputFile);
    return doDecrypt(encodekey,input);
    }

    private  String doEncrypt(String encodekey, String inputStr)   throws CryptoException {
        try {

            Cipher cipher = Cipher.getInstance(TRANSFORMATION);

            byte[] key = encodekey.getBytes("UTF-8");
            MessageDigest sha = MessageDigest.getInstance("SHA-1");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16); // use only first 128 bit

            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

            byte[] inputBytes = inputStr.getBytes();     
            byte[] outputBytes = cipher.doFinal(inputBytes);

            return Base64Utils.encodeToString(outputBytes);

        } catch (NoSuchPaddingException | NoSuchAlgorithmException
                | InvalidKeyException | BadPaddingException
                | IllegalBlockSizeException | IOException ex) {
            throw new CryptoException("Error encrypting/decrypting file", ex);
       }
     }


    public  String doDecrypt(String encodekey,String encrptedStr) { 
          try {     

              Cipher dcipher = Cipher.getInstance(TRANSFORMATION);
              dcipher = Cipher.getInstance("AES");
              byte[] key = encodekey.getBytes("UTF-8");
              MessageDigest sha = MessageDigest.getInstance("SHA-1");
              key = sha.digest(key);
              key = Arrays.copyOf(key, 16); // use only first 128 bit

              SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

              dcipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            // decode with base64 to get bytes

              byte[] dec = Base64Utils.decode(encrptedStr.getBytes());  
              byte[] utf8 = dcipher.doFinal(dec);

              // create new string based on the specified charset
              return new String(utf8, "UTF8");

          } catch (Exception e) {

            e.printStackTrace();

          }
      return null;
      }
 }

2
2018-04-06 20:45



    byte[] seed = (SALT2 + username + password).getBytes();
    SecureRandom random = new SecureRandom(seed);
    KeyGenerator generator;
    generator = KeyGenerator.getInstance("AES");
    generator.init(random);
    generator.init(256);
    Key keyObj = generator.generateKey();

0
2018-05-31 23:38