Ankündigung

Einklappen
Keine Ankündigung bisher.

RSA-AES-Crypter in Konsole

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • RSA-AES-Crypter in Konsole

    Hallo GAGA,

    ich interessiere mich sehr für den von dir Vorgestellten quelltext zum AES/RAS Hybridverfahren. AES und RSA in Java

    Habe leider ein paar Probleme damit und bin mir nicht sicher wie diese zu lösen sind.

    Da ich nicht an der GUI interessiert bin habe ich mich erstmal nur an der file crypt.java bedient und habe die Datei noch um eine main methode erweitert.

    Code:
    public static void main(String[] args) {
    String privateKeyFileName =".\\privateKey";
    String publicKeyFileName =".\\publicKey";
    String kennziffer =".\\kennziffer";
    String crypt_kennziffer =".\\crypt_kennziffer";
    String decrypt_kennziffer =".\\decrypt_kennziffer";
    
    generateKey(privateKeyFileName,publicKeyFileName);
    encrypt(publicKeyFileName, kennziffer,crypt_kennziffer);
    decrypt(privateKeyFileName, crypt_kennziffer,decrypt_kennziffer);
    }
    Was ich hier testen wollte war nun:
    => private/public key erzeugen
    => ein Wort dass ich in die Datei "kennziffer" geschrieben habe verschlüsseln und das verschlüsselte Wort in "crypt_kennziffer" speichern.
    => das ganze wieder entziffern.
    => eigentlich sollte das Wort das in "kennziffer" war nun auch in "decrypt_kennziffer" stehen. Oder nicht?

    Ich poste hier nochmal den kompletten Quelltext der Datei inklusive hinzugefügter main methode:
    Code:
    /*
    * This file is part of the AES and RSA in Java demo. It demonstrates
    * the combination of a symmetric and asymmetric encryption algorithm.
    * Copyright (C) 2005 - 2011 CodePlanet. All rights reserved.
    * For more informations, visit CodePlanet: The planet of living code!.
    *
    * This program is free software: you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation, either version 3 of the License, or
    * (at your option) any later version.
    *
    * This program is distributed in the hope that it will be useful,
    * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    * GNU General Public License for more details.
    *
    * You should have received a copy of the GNU General Public License
    * along with this program. If not, see <http://www.gnu.org/licenses/>.
    */
    
    import java.io.*;
    import java.security.*;
    import java.util.logging.Logger;
    import javax.crypto.*;
    
    /**
    * A basic class for encryption and decription using symmetric and asymmetric
    * algorithms.
    *
    * @author CodePlanet
    * @version 1.0.1, 12/06/2010
    * @see <a href="http://www.codeplanet.eu/">http://www.codeplanet.eu/</a>
    */
    public class AESTest {
    /**
    * Private Constructor, all methods are static.
    */
    private AESTest() {
    }
    
    /**
    * Generate a RSA pair key (public.key, private.key) and stores it in files.
    *
    * @param privateKeyFileName
    * name of the private key
    * @param publicKeyFileName
    * name of the public key
    */
    public static void generateKey(String privateKeyFileName,
    String publicKeyFileName) {
    try {
    KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA");
    SecureRandom random = new SecureRandom();
    pairgen.initialize(KEYSIZE, random);
    KeyPair keyPair = pairgen.generateKeyPair();
    ObjectOutputStream out = new ObjectOutputStream(
    new FileOutputStream(publicKeyFileName));
    out.writeObject(keyPair.getPublic());
    out.close();
    out = new ObjectOutputStream(new FileOutputStream(
    privateKeyFileName));
    out.writeObject(keyPair.getPrivate());
    out.close();
    } catch (IOException e) {
    } catch (GeneralSecurityException e) {
    }
    }
    
    /**
    * Encrypt a file with AES using the public RSA key.
    *
    * @param publicKeyFile
    * name of the public key
    * @param inputFile
    * name of the input file
    * @param outputFile
    * name of the output file
    */
    public static void encrypt(String publicKeyFile, String inputFile,
    String outputFile) {
    try {
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    SecureRandom random = new SecureRandom();
    keygen.init(random);
    SecretKey key = keygen.generateKey();
    
    // Wrap with public key
    ObjectInputStream keyIn = new ObjectInputStream(
    new FileInputStream(publicKeyFile));
    Key publicKey = (Key) keyIn.readObject();
    keyIn.close();
    
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.WRAP_MODE, publicKey);
    byte[] wrappedKey = cipher.wrap(key);
    DataOutputStream out = new DataOutputStream(new FileOutputStream(
    outputFile));
    out.writeInt(wrappedKey.length);
    out.write(wrappedKey);
    
    InputStream in = new FileInputStream(inputFile);
    cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    crypt(in, out, cipher);
    in.close();
    out.close();
    } catch (IOException e) {
    } catch (GeneralSecurityException e) {
    } catch (ClassNotFoundException e) {
    }
    }
    
    /**
    * Decrypt a file with the private key.
    *
    * @param privateKeyFile
    * @param inputFile
    * @param outputFile
    */
    public static void decrypt(String privateKeyFile, String inputFile,
    String outputFile) {
    try {
    DataInputStream in = new DataInputStream(new FileInputStream(
    inputFile));
    int length = in.readInt();
    byte[] wrappedKey = new byte[length];
    in.read(wrappedKey, 0, length);
    
    // Open with private key
    ObjectInputStream keyIn = new ObjectInputStream(
    new FileInputStream(privateKeyFile));
    Key privateKey = (Key) keyIn.readObject();
    keyIn.close();
    
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.UNWRAP_MODE, privateKey);
    Key key = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);
    
    OutputStream out = new FileOutputStream(outputFile);
    cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, key);
    crypt(in, out, cipher);
    in.close();
    out.close();
    } catch (IOException e) {
    } catch (GeneralSecurityException e) {
    } catch (ClassNotFoundException e) {
    }
    }
    
    /**
    * Encrypt a byte array with AES using the public RSA key.
    *
    * @param publicKeyFile
    * name of the public key
    * @param plainText
    * name of the input file
    * @param outputFile
    * name of the output file
    */
    public static byte[] encrypt(byte[] plainText, PublicKey publicKey) {
    byte[] data = null;
    
    try {
    // Create cipher object
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    SecureRandom random = new SecureRandom();
    keygen.init(random); // Initialize with random data
    SecretKey key = keygen.generateKey();
    
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.WRAP_MODE, publicKey);
    byte[] wrappedKey = cipher.wrap(key);
    out.write(wrappedKey.length);
    out.write(wrappedKey);
    
    InputStream in = new ByteArrayInputStream(plainText);
    cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, key);
    crypt(in, out, cipher);
    data = out.toByteArray();
    in.close();
    out.close();
    } catch (IOException e) {
    _logger.warning(e.getMessage());
    } catch (GeneralSecurityException e) {
    _logger.warning(e.getMessage());
    }
    
    return data;
    }
    
    /**
    * Decrypt a byte array with the private key.
    *
    * @param privatecKeyFile
    * @param cipherText
    * @param outputFile
    */
    public static byte[] decrypt(byte[] cipherText, PrivateKey privateKey) {
    byte[] data = null;
    
    try {
    ByteArrayInputStream in = new ByteArrayInputStream(cipherText);
    int length = in.read();
    byte[] wrappedKey = new byte[length];
    in.read(wrappedKey, 0, length);
    
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.UNWRAP_MODE, privateKey);
    Key key = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);
    
    cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, key);
    
    crypt(in, out, cipher);
    data = out.toByteArray();
    in.close();
    out.close();
    } catch (IOException e) {
    _logger.warning(e.getMessage());
    } catch (GeneralSecurityException e) {
    _logger.warning(e.getMessage());
    }
    
    return data;
    }
    
    /**
    * Transforms all bytes from the input stream with a crypt alorithm and
    * sends the transformed bytes to the output stream.
    *
    * @param in
    * input stream
    * @param out
    * output stream
    * @param cipher
    * crypt alorithm used
    */
    public static void crypt(InputStream in, OutputStream out, Cipher cipher)
    throws IOException, GeneralSecurityException {
    int blockSize = cipher.getBlockSize();
    int outputSize = cipher.getOutputSize(blockSize);
    byte[] input = new byte[blockSize];
    byte[] output = new byte[outputSize];
    int inLength = 0;
    boolean finished = false;
    
    while (!finished) {
    inLength = in.read(input);
    
    if (inLength == blockSize) {
    int outLength = cipher.update(input, 0, blockSize, output);
    out.write(output, 0, outLength);
    } else {
    finished = true;
    }
    }
    
    if (inLength > 0)
    output = cipher.doFinal(input, 0, inLength);
    else
    output = cipher.doFinal();
    
    out.write(output);
    }
    
    /** The key size. */
    private static final int KEYSIZE = 2048;
    
    /** A logger. */
    private static final Logger _logger = Logger.getLogger(AESTest.class
    .getName());
    //
    public static void main(String[] args) {
    String privateKeyFileName =".\\privateKey";
    String publicKeyFileName =".\\publicKey";
    String kennziffer =".\\kennziffer";
    String crypt_kennziffer =".\\crypt_kennziffer";
    String decrypt_kennziffer =".\\decrypt_kennziffer";
    
    generateKey(privateKeyFileName,publicKeyFileName);
    encrypt(publicKeyFileName, kennziffer,crypt_kennziffer);
    decrypt(privateKeyFileName, crypt_kennziffer,decrypt_kennziffer);
    }
    }
    Es werden keys erzeugt, allerdings bin ich mir nicht sicher ob der Inhalt dieser keys richtige keys sind. (komische symbole und die Dateien sind auch nicht 2048 bytes groß sondern der private key ca. 1500 bytes und der public key ca. 500 bytes). Kopierbar sind die Inhalte der Dateien leider nicht.
    In die Datei crypt_kennziffer wurde wirklich etwas geschrieben(wieder zufällige Zeichen) aber die Datei decrypt_kennziffer lässt sich leider nicht öffnen. (Could not open the editor: Editor could not be initialized.)
    Mich interessiert nun vorallem ob die Keys korrekt erstellt werden und weshalb decrypt nicht zu einem ordentlichem Ergebnis führt. Würde mich sehr über Hilfe freuen.

  • #2
    Hallo!

    Zunächst einmal ist es normal das die Keys sich nicht mit einem normalen Texteditor vernünftig öffnen und bearbeiten lassen. Die Daten liegen in Bytes vor und können nur mit einem Hex-Editor korrekt geöffnet werden. Ein gewöhnlicher Text-Editor kann die Zeichen nicht darstellen und zerstört die Datei.

    Bitte erzeuge die Schlüssel neu und führe die Ver- und Entschlüsselung erneut durch. Danach öffne die Datei "decrypt_kennziffer" und überprüfe, ob sie mit den Daten von "kennziffer" übereinstimmt.

    Gruß,
    GAGA
    Zuletzt geändert von GAGA; 20.02.2012, 10:55.

    Kommentar


    • #3
      Hallo GAGA,
      decrypt funktioniert nun wunderbar - vielen Dank schonmal! Wie man wohl merkt kenne ich mich im Bereich der cryptographie noch nicht so wirklich aus und ich denke ich habe in meiner Unwissenheit die Schlüssel zerstört in dem ich sie, wie du sagtest, in einem Texteditor angeschaut hatte.
      Ich habe nun nurnoch eine kurze generelle Frage zum Schlüsselpaar. Ich habe mir nun einen Hexeditor installiert und mir die Größe der Schlüssel ausgeben lassen.
      Der private key ist nun 1478 bytes groß und der public key 551 bytes. Sind das normale zu erwartende Werte? Ich hätte erwartet, dass beide Schlüssel eine Größe von 2048 bytes besitzen müssen?

      Ich hätte zudem noch eine weitere Frage - hierzu zitiere ich ein Stück des Textes aus deinem Tutorial:
      Die Blockgröße des AES beträgt 128 Bit und ist im Gegensatz zum normalen Rijndael fest implementiert, kann also nicht verändert werden.
      An sich dachte ich der AES wäre der Rjindael Algorithmus? Wäre es auch möglich anstelle des AES den Rjindael zu verwenden und diesen auch ein wenig sicherer zu machen, also z.B. 256 Bit?

      Kommentar


      • #4
        Zitat von Don83 Beitrag anzeigen
        Ich habe nun nurnoch eine kurze generelle Frage zum Schlüsselpaar. Ich habe mir nun einen Hexeditor installiert und mir die Größe der Schlüssel ausgeben lassen.
        Der private key ist nun 1478 bytes groß und der public key 551 bytes. Sind das normale zu erwartende Werte? Ich hätte erwartet, dass beide Schlüssel eine Größe von 2048 bytes besitzen müssen?
        Ja, das sind normale Werte. Du verwechselst hier Bytes mit Bits. Der RSA hat typischerweise zwischen 1.024 to 4.096 Bit. Ein Byte besteht aus 8-Bit.

        In den Schlüsseldateien landen noch ein paar andere Daten von Java, weshalb sie dann auch etwas größer ausfallen kann.

        Zitat von Don83 Beitrag anzeigen
        Ich hätte zudem noch eine weitere Frage - hierzu zitiere ich ein Stück des Textes aus deinem Tutorial:

        An sich dachte ich der AES wäre der Rjindael Algorithmus? Wäre es auch möglich anstelle des AES den Rjindael zu verwenden und diesen auch ein wenig sicherer zu machen, also z.B. 256 Bit?
        Der AES ist eine standardisierte Variante des Rjindael-Algorithmus. Der AES wurde weltweit offiziell standardisiert und die Blockgröße wurde auf 128 Bit festgesetzt. Man kann den Rjindael auch selbst implementieren, mit mehr Möglichkeiten. Wir haben dazu auch in der C/C++ Region ein Tutorial.

        Allerdings solltest du dir darum keine Gedanken machen. Der AES ist absolut sicher, auch mit "nur" 128 Bit. Du musst dir vorstellen das mit 128 Bit insgesamt 2^128 Passwörter existieren. Das ist eine unvorstellbar hohe Zahl!
        Zuletzt geändert von GAGA; 20.02.2012, 11:35.

        Kommentar


        • #5
          Vielen Dank GAGA für die ausführlichen Erklärungen.

          Kommentar


          • #6
            Hallo nocheinmal,

            eigentlich hat sich programmiertechnisch fast alles geklärt und das System läuft grundsätzlich einwandfrei. Ich habe nun nur festgestellt, dass das Programm doch schon relativ hohe Laufzeiten hat. Also bei einer Datei mit 10MB dauert das ganze ca. 10 Minuten. Ich wundere mich ein wenig, da ich das ganze mal mit PGP ausprobiert habe und hier dauert alles nur ca. 10 Sekunden. Gibt es dafür eine Begründung? Eve. liegt es ja an den Keygrößen für den RSA habe ich eine Größe von 2048bit beim AES bin ich mir nicht sicher ob ich als festen Wert 128 bit verwenden sollte oder folgendes Konstrukt:
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            SecureRandom random = new SecureRandom();
            keygen.init(random);
            SecretKey key = keygen.generateKey();
            Naja eventuell liegt es ja auch an etwas ganz anderem oder PGP verwendet ein anderes System. Soweit ich aber informiert bin benutzt auch PGP das hybride Verschlüsselungsverfahren. Also wie gesagt ich sehe nicht ganz woher der große Unterschied in der Laufzeit kommt.

            Wenn gewünscht kann ich auch nochmal meinen kompletten Quellcode schicken.
            Zuletzt geändert von Don83; 21.05.2012, 15:22.

            Kommentar


            • #7
              OpenPGP ist in C/C++ geschrieben und natürlich auf Laufzeit optimiert. Deshalb ist es auch deutlich schneller als einfacher Java-Code.

              Unser in C geschriebenes Programm im AES-Artikel verschlüsselt 10 MB große Dateien sogar in weniger als zwei Sekunden!

              Gruß,
              GAGA

              Kommentar

              Lädt...
              X