Šifrování v Javě pomocí algoritmu AES 256

Java Pro pokročilé Šifrování v Javě pomocí algoritmu AES 256

V tomhle článku si ukážeme jak si napsat vlastní třídu na šifrování a dešifrování AES256.

Ze všeho nejdřív je potřeba si stáhnou upravenou verzi JCE (Java Cryptography Extension), která řeší problém s chybou vadného klíče. Stáhnou můžete zde: http://www.oracle.com/…-432124.html

Přepíšete jen stávající soubory ve složce jdk\jre\lib\s­ecurity

Jako další krok si vytvoříme třídu AESEncrypter a hned si definujeme pár základních proměnných.

private static final byte[] SALT;
private static final int ITERATION_COUNT;
private static final int KEY_LENGTH;

static{
    SecureRandom secureRandom = new SecureRandom();
    SALT = secureRandom.generateSeed(8);
    ITERATION_COUNT = 65536;
    KEY_LENGTH = 256;
}

private Cipher ecipher; //šifrování
private Cipher dcipher; //dešifrování
  • SALT - pole s náhodnými bity, které slouží jako doplňující vstup. Je to z toho důvodu, aby výstup měl více možných variant (SALT je vhodné někam ukládat, protože když budete něco chtít dešifrovat, tak se vám vygeneruje jiný SALT, než když jste to šifrovali, nebo taky používat stále ten jeden stejný, ale to není nějak moc bezpečné)
  • ITERATION_COUNT - počet kolikrát se nám klíč mění v metodě
  • KEY_LENGHT - jak dlouhý je klíč, v našem případě se jedná o AES256, takže 256 bitů

Dále bude následovat konstruktor, do kterého budeme volat námi zadaný klíč a inicializujeme zbytek proměnných.

public AESEncrypter(String passPhrase) throws Exception {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), SALT, ITERATION_COUNT, KEY_LENGTH);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

        ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        ecipher.init(Cipher.ENCRYPT_MODE, secret);

        dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        byte[] iv = ecipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
        dcipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
    }
  • SecretKeyFactory - bude sloužit jako továrna na vytvoření klíče. Parametrem je název algoritmu kterým se to bude šifrovat. Více typů najdete zde http://docs.oracle.com/…rdNames.html#…
  • KeySpec - vytvoří nám jakýsi předpis pro náš klíč, specifikaci, kde zkombinujeme námi zadaný klíč, salt, počet proměn a finální délku
  • SecretKey tmp - pomocí továrny a specifikace klíče se nám vytvoří klíč pomocí defaultních algoritmů
  • SecretKey secret - vezme se defaultní zakódování a vytvoří se klíč pro AES

Dále se získává instance Ciphrů pomocí zadané transformace ve tvaru jméno algoritmu/režim algoritmu/postup algoritmu. Všechny druhy můžete najít opět zde http://docs.oracle.com/…rdNames.html#…

U dešifrátoru se navíc inicializuje iv což je Initialization vector jehož popis najdete např. zde http://en.wikipedia.org/…ation_vector

Metody na dešifraci a šifraci jsou naprosto jednoduché, volají jen metodu Cipheru doFinal() kde parametrem je pole bytů. Při převodu String na pole bytů je vhodné používat třídu BASE64Decoder a BASE64Encoder.

public String encrypt(String encrypt) throws Exception {
       byte[] bytes = encrypt.getBytes("UTF8");
       byte[] encrypted = encrypt(bytes);
       return new BASE64Encoder().encode(encrypted);
   }

   public byte[] encrypt(byte[] plain) throws Exception {
       return ecipher.doFinal(plain);
   }

   public String decrypt(String encrypt) throws Exception {
       byte[] bytes = new BASE64Decoder().decodeBuffer(encrypt);
       byte[] decrypted = decrypt(bytes);
       return new String(decrypted, "UTF8");
   }

   public byte[] decrypt(byte[] encrypt) throws Exception {
       return dcipher.doFinal(encrypt);
   }

Celou třídu i s ukázkou najdete v archivu pod článkem. Můžeme ji otestovat následujícím způsobem:

try {
     AESEncrypter e = new AESEncrypter("e8ffc7e56311679f12b6fc91aa77a5eb");
     byte[]test = e.encrypt(new byte[]{'a','h','o','j'});
     System.out.println(Arrays.toString(test));
     System.out.println(Arrays.toString(e.decrypt(test)));
     //vypisuje hodnoty pismen v ASCII
 } catch (Exception e1) {
     e1.printStackTrace();
 }

 

Stáhnout

Staženo 366x (1.18 kB)
Aplikace je včetně zdrojových kódů v jazyce java

 

  Aktivity (1)

Článek pro vás napsal Fugiczek
Avatar

Jak se ti líbí článek?
Celkem (2 hlasů) :
55555


 


Miniatura
Předchozí článek
Obfuskace Java kódu
Miniatura
Všechny články v sekci
Java - Pro pokročilé
Miniatura
Následující článek
Regulární výrazy v Javě

 

 

Komentáře
Zobrazit starší komentáře (2)

Avatar
karels
Člen
Avatar
karels:

Já jsem se také pokoušel šifrovat ale pomocí MD5 ... bohužel jsem narazil na to samé ... také jsem nevěděl jak to že když při vytvoření usera heslo zašifruji a pak když v průběhu relace přihlašování převedu zadané heslo na hash tak jsou tyto hashe rozdílné ... Ale já jsem využíval jiného nástroje ... myslím že je to tím že se musí nastavit shodně to šifrování ale nevím jak

Používal jsem toto, a pokuď jsem správně pochopil by měl zváldat i AES nebo SSH :

final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(string.getBytes(Charset.forName("UTF8")));
final byte[] resultByte = messageDigest.digest();
final String result = new String(Hex.encodeHex(resultByte));

Ale určitě mě zkritizujete že jsem to nepochopil ... ale doufám že mi někdo dá nějaký dobrý směr :)

Odpovědět 25.1.2013 18:24
Nejvíc času promarníme tím, že usilujeme získat čas. - John Steinbeck
Avatar
Hartrik
Redaktor
Avatar
Hartrik:

Dobře zkusim to s tim IV snad už to půjde

 
Odpovědět 25.1.2013 18:49
Avatar
Fugiczek
Redaktor
Avatar
Odpovídá na Hartrik
Fugiczek:

Tak jsem si s tím chvíli hrál a prostě když se vytvoří nová instance té třídy tak to nefunguje to dešifrování. Nevím proč, na to jsem moc krátkej. Jinak AES je asymetrický takže výsledek bude pokaždé jiný a to IV je blbost ukládat :-) Teoreticky by stačilo na dešifrování znát jen klíč, jenže ono to všechno funguje v jedné instanci, jakmile je další tak je to problém, třeba s tím poradí někdo jiný :-)

 
Odpovědět 25.1.2013 19:32
Avatar
karels
Člen
Avatar
Odpovídá na Fugiczek
karels:

No a proč řešíte dešifrování, tedy pokuď se nemejlím, není snažší to zašifrovat a zašifrované data porovnávat ? Pokuď se nemýlím takhle se běžně provádí autentizace na webovkách? na serveru je v DB heslo zahešované a PHP jen porovnává dva heše ne ? ale je potřeba aby ty dva heše byli stejné, což by měli, ale problém je asi právě v tom šifrovacím klíči ... bohužel toho se mi nepodařilo docílit i když nevím proč ...

Odpovědět 25.1.2013 19:49
Nejvíc času promarníme tím, že usilujeme získat čas. - John Steinbeck
Avatar
Fugiczek
Redaktor
Avatar
Odpovídá na karels
Fugiczek:

Jenže u tady tohoto je výsledek šifrování pokaždé jiný, protože šifra je asymetrická, porovnávání zde nepomůže :-)

 
Odpovědět 25.1.2013 19:51
Avatar
karels
Člen
Avatar
Odpovídá na Fugiczek
karels:

Advanced Encryption Standard (AES) je symetrická bloková šifra ...
By wiki, a to samé englisch wiki ... pokuď vím, tak jestli je symetrická nebo nesymetrická se rozhoduje podle toho jak se šifruje a dešifruje u symetrické je to stejný klíč pro šifrování i dešifrování ne ... u asymetrické je to jeden klíč pro zašifrování a druhý pro rozšifrování a opačně použít nejdou ...

pokuď snad ale šifruju stejným klíčem tak by měl být výsledek stejný ne u symetrické šifry ?
Jelikož pokuď oba zašifruju jiným klíčem ... tak na straně serveru budu mít problém s dešifrací ... budu si muset poslat klíč a to je po síti trošku nebezpečné ne ? jako nejsem žádný odborník, jen uvažuji ... a vztahuju to ke svému problému ... kdy jsem chtěl posílat přes síť zašifrované heslo na na straně TCP serveru jen porovnat s hešem z databáze ...

a ještě jedna věc MD5 je tedy taky asymetric ?

Odpovědět 25.1.2013 20:30
Nejvíc času promarníme tím, že usilujeme získat čas. - John Steinbeck
Avatar
Fugiczek
Redaktor
Avatar
Odpovídá na karels
Fugiczek:

Jo máš pravdu, jsem si to špatně odvodil z toho že pokaždé to háže jinej výsledek. Možná jsem jen špatně napsal ukázku, v kryptografii se moc nevyznám. MD5 je 100% symetrická :-D Prostě je to taková ukázka na jedno použití, když někoho napadne jak to vyřešit, aby to fungovalo i v nove instanci, budu jen rád :-)

 
Odpovědět 25.1.2013 20:48
Avatar
karels
Člen
Avatar
Odpovídá na Fugiczek
karels:

Já jsem se setkal se stejným problémem ... dělal jsem povinně jako semestrálku takovou apku, jednoduchou simulaci bankomatu, mělo to být konzolově :D ... trošku jsem si to ztížil :D udělal jsem tu simulaci graficky klient-server spojený přes socekt ... usery jsem házel do XML na straně serveu ... a přihlašoval jsem se z bankomatu pomocí ID karty a pinu ... heslo jsem chtěl šifrovat pomocí MD5 ... asi pět hodin jsem seděl na programe :D jelikož mě nešlo se přihlásit ... :D pak když jsem si do konzole nechal vypsat heše bylo mi jasné proč ... heše byli různé ... takže jsem to nechal nešifrované :D i tak to splnilo až moc nad míru zadání :D

tuším že problém byl a je v tom že se to šifruje různýma klíčema v druhém případě, že se to zašifruje jedním a jiným se to snaží dešifrovat ... ale chtělo by to názor někoho zkušenějšího :) já jsem jen takovej malej břídil :D

Odpovědět 25.1.2013 21:05
Nejvíc času promarníme tím, že usilujeme získat čas. - John Steinbeck
Avatar
archenroot
Člen
Avatar
archenroot:

Hoj,
s timhle jsem se lamal taky, vytvoril jsem si takovy prototyp viz nize, je plne funkcni, kryptuje z jakekoli instance, publikovany kod obsahuje pri kompilaci klic a sul primo v kodu, coz by melo byt pro jakekoli produkcni aplikace rozumne osetreno.

package org.archenroot.crypto.aes;

/*
 * @(#)EncryptString.java
 *
 * Summary:     Application for encrypt string variables.
 *        AES(Rijndael) with 256-bit key in CBC mode.
 *        This is just a demonstration piece of code.
 *
 * Copyright:     (C) 2009-2011
 *
 * Licence: MIT
 * Copyright (c) 2011 Ladislav Jech
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Requires: JDK 1.6+
 *
 * Created with: Eclipse Galileo 3.5
 *
 * Version History:
 *      1.1 2011-02-08
 *    Initial version
 *      1.2 2011-12-01
 *    Added JCE Unlimited Strength check
 */

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import static java.lang.System.out;

/**
 * Application for encrypt string using AES with 256-bit key in CBC mode.
 *
 * You need to unlock maximal cryptography level of Java Run-time Environment.
 * It's about replacing local_policy.jar and US_export_policy.jar which can
 * obtained at http://www.oracle.com/technetwork/java/javase/downloads/index.html.
 * Name of extension is: Java Cryptography Extension (JCE) Unlimited Strength
 * Jurisdiction Policy Files 6 (verze pro JRE 6.*).
 *
 * <p/>
 * This version use AES/CBC/PKCS5Padding b/
 * */
public class EncryptString {
    // ------------------------------ CONSTANTS ------------------------------

    /**
     * Configuration of used algorithm.
     * Do not use less secure DES. Setting up another value can prevent of
     * using this software and will require to specify some additional
     * parameters for initial vector.
     */
    private static final String ALGORITHM = "AES";

    /**
     * Configuration of block mode. Do not use less secure ECB mode.
     */
    private static final String BLOCK_MODE = "CBC";

    /**
     * Configuration of "padding".
     */
    private static final String PADDING = "PKCS5Padding";

    /**
     * Encoding used for converting bytes <--> Strings.
     */
    private static final Charset CHARSET = Charset.forName("UTF-8");

    /**
     * 128-bit of salt. Not so secure, but stable bytes for use with AES-CBC mode.
     */
    private static final IvParameterSpec CBC_SALT = new IvParameterSpec(
            new byte[] { 7, 34, 56, 78, 90, 87, 65, 43, 12, 34, 56, 78, -123,
                    87, 65, 43 });
    /**
     * 256-bit static key. Schould be replaced by generated one for better security.
     * But for demonstration purposes it's built-in.
     */
    private static final SecretKeySpec STATIC_KEY = new SecretKeySpec(
            new byte[] { 75, 108, 105, 99, 32, 107, 32, 104, 101, 115, 108,
                    117, 109, 32, 101, 120, 116, 101, 114, 110, 105, 99, 104,
                    32, 115, 121, 115, 116, 101, 109, 117, 32 }, ALGORITHM);

    /*
     * To make it more independent against external library (ArrayUtils), here are defined
     * an empty arrays.
     */

    /** Empty array of bytes. */
    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];

    /** Mask for 0. bit of byte. */
    private static final int BIT_0 = 1;

    /** Mask for 1. bit of byte. */
    private static final int BIT_1 = 0x02;

    /** Mask for 2. bit of byte. */
    private static final int BIT_2 = 0x04;

    /** Mask for 3. bit of byte. */
    private static final int BIT_3 = 0x08;

    /** Mask for 4. bit of byte. */
    private static final int BIT_4 = 0x10;

    /** Mask for 5. bit of byte. */
    private static final int BIT_5 = 0x20;

    /** Mask for 6. bit of byte. */
    private static final int BIT_6 = 0x40;

    /** Mask for 7. bit of byte. */
    private static final int BIT_7 = 0x80;

    /** Mask array. */
    private static final int[] BITS = { BIT_0, BIT_1, BIT_2, BIT_3, BIT_4,
            BIT_5, BIT_6, BIT_7 };

    /**
     * Encrypts message in clear text and write into the XML file, seek for
     * beginning TAG <Heslo>, finishing then </Heslo>.
     *
     * @param cipher
     *            type of cipher used for encrypt.
     * @param key
     *            tajný klíč použitý pro šifrování souboru.
     * @param file
     *            file, do kterého se zapíše zašifrovaná zpráva.
     * @param clearMessage
     *            čistý text zprávy určené k šífrování.
     *
     * @throws InvalidKeyException
     *             když je něco špatně s klíčem. Může být způsobeno tím, že JRE
     *             nepoužívá knihovny pro vysoký stupeň šifrování.
     * @throws IOException
     *             když je nějaký problém se zápisem fileu, nebo obecně s
     *             operacemi vstupu/výstupu.
     * @throws InvalidAlgorithmParameterException
     *             když je problém se "solí", nebo-li s parametrem CBC_SALT.
     * @throws BadPaddingException
     *             když je problém s "vycpávkou" šifry. Vycpávka zvyšuje
     *             zabezpečení při brute-force pokusech o prolomení šifry.
     * @throws IllegalBlockSizeException
     *             když je problém s neplatnou velikostí bloku šifry.
     * @throws ShortBufferException
     *             když je zásobník příliš malý pro zpracovávaná data.
     */
    public static void writeEncrypted(  Cipher cipher,
                                        SecretKeySpec key,
                                        String file,
                                        String clearMessage)
    throws
    InvalidKeyException,
    IOException,
    InvalidAlgorithmParameterException,
    IllegalBlockSizeException,
    BadPaddingException,
    ShortBufferException
    {
        // Objects related to file works.
        FileReader fileReader = new FileReader(new File(file));
        BufferedReader inputBuffer = new BufferedReader(fileReader);
        File temporaryFile = new File("temp.xml");
        FileWriter fileWriter = new FileWriter(temporaryFile);
        BufferedWriter outputBuffer = new BufferedWriter(fileWriter);

        // Initiation of cipher.
        cipher.init(Cipher.ENCRYPT_MODE, key, CBC_SALT);
        byte[] clearMessageByte = clearMessage.getBytes(CHARSET);
        byte[] encryptedMessageByte = cipher.doFinal(clearMessageByte);

        // Encrypt message and transfer it to encoded format Base64.
        final String encodedBase64 = new String(encode(encryptedMessageByte),
                CHARSET);

        /*
         * Inactive part - idea is to make it work directly in RAM instead
         * of file, but for demonstration it is enough.
         * long delka = new File(file).length(); MappedByteBuffer in = new
         * FileInputStream(file).getChannel().map(
         * FileChannel.MapMode.READ_ONLY, 0, delka); int i = 0; while (i <
         * delka) in. System.out.print((char) in.get(i++));
         */

        // Write temporary file, which already consists of encrypted content.
        String row = null;
        while ((row = inputBuffer.readLine()) != null) {
            if (row.indexOf("</Heslo>") > 0) {
                outputBuffer.write("\t<Heslo>");
                outputBuffer.write(encodedBase64);
                outputBuffer.write("</Heslo>");
                outputBuffer.write("\n");
            } else {
                outputBuffer.write(row);
                outputBuffer.write("\n");
            }
        }
        // Explicitly clean memory.
        inputBuffer.close();
        fileReader.close();
        outputBuffer.close();
        fileWriter.close();

        // Write data from temporary to live file.
        File f = new File(file);
        if (f.delete()) {
            FileReader fileReader1 = new FileReader(new File(temporaryFile
                    .getAbsoluteFile().toString()));
            BufferedReader inputBuffer1 = new BufferedReader(fileReader1);
            File outputFile = new File(file);
            FileWriter fileWriter1 = new FileWriter(outputFile);
            BufferedWriter outputBuffer1 = new BufferedWriter(
                    fileWriter1);
            String outputRow = null;
            while ((outputRow = inputBuffer1.readLine()) != null) {
                outputBuffer1.write(outputRow);
                outputBuffer1.write("\n");
            }
            inputBuffer1.close();
            fileReader1.close();
            outputBuffer1.close();
            fileWriter1.close();
        }

        temporaryFile.deleteOnExit();
        temporaryFile = null;
        f = null;

        /*
         * Check encrypting mechanims in a way that encrypted and encoded message
         * is again decoded and decrypted and printed to standard output. If the message
         * is different on input&output then it symptom of corrupted cryptography settings.
         */
        cipher.init(Cipher.DECRYPT_MODE, key, CBC_SALT);
        byte[] original = cipher.doFinal(decode(encodedBase64
                .getBytes("UTF-8")));
        System.out
                .println("Decoded end decrypted message for check: "
                        + new String(original, CHARSET));
    }

    // ------------------------------ POMOCNÉ METODY ------------------------------
    /**
     * Converts bytes to String of hexadecimal values.
     *
     * @param buf
     *            input array of bytes.
     * @return String of hexadecimal values of input buffer
     */
    public static String jakoHexa(byte buf[]) {
        StringBuffer strbuf = new StringBuffer(buf.length * 2);
        int i;

        for (i = 0; i < buf.length; i++) {
            if (((int) buf[i] & 0xff) < 0x10)
                strbuf.append("0");

            strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
        }
        return strbuf.toString();
    }

    /**
     * Converts array of clear binary data to array of ASCII 0 and 1 characters
     * for each bit of argument.
     *
     * @param raw
     *            raw binary data
     * @return array of byte bajtových data 0 a 1 for each bit of argument
     * @see org.apache.commons.codec.BinaryEncoder#encode(byte[])
     */
    public static byte[] doASCIIBajtu(byte[] raw) {
        if (isEmpty(raw)) {
            return EMPTY_BYTE_ARRAY;
        }
        // get length/8 * bytes with 3-bit jump to left from length
        byte[] l_ascii = new byte[raw.length << 3];
        /*
         * Lower index jj by 8 because of not recompute block in case on multiplication
         */
        for (int ii = 0, jj = l_ascii.length - 1; ii < raw.length; ii++, jj -= 8) {
            for (int bits = 0; bits < BITS.length; ++bits) {
                if ((raw[ii] & BITS[bits]) == 0) {
                    l_ascii[jj - bits] = '0';
                } else {
                    l_ascii[jj - bits] = '1';
                }
            }
        }
        return l_ascii;
    }

    /**
     * Decodes array of bytes where each each byte is like ASCII '0' nebo '1'.
     *
     * @param ascii
     *            each byte is like ASCII '0' nebo '1'
     * @return clear coded binary where each bit is like byte from byte array argument
     */
    public static byte[] fromASCII(byte[] ascii) {
        if (isEmpty(ascii)) {
            return EMPTY_BYTE_ARRAY;
        }
        // get length/8 * bytes with 3-bit jump to right from length
        byte[] l_raw = new byte[ascii.length >> 3];
        /*
         * Lower index jj by 8 because of not recompute block in case on multiplication
         */
        for (int ii = 0, jj = ascii.length - 1; ii < l_raw.length; ii++, jj -= 8) {
            for (int bits = 0; bits < BITS.length; ++bits) {
                if (ascii[jj - bits] == '1') {
                    l_raw[ii] |= BITS[bits];
                }
            }
        }
        return l_raw;
    }

    /**
     * Converts array of binary data to array of ASCII 0 a 1characters.
     *
     * @param binary
     *            clear binary data for convert
     * @return array of bytes ASCII of 0 a 1 values, each byt for 1 bit of argument
     * @see org.apache.commons.codec.BinaryEncoder#encode(byte[])
     */
    public static byte[] encode(byte[] binary) {
        return doASCIIBajtu(binary);
    }

    /**
     * Decodes array of bytes where each byte represents ASCII '0' or '1'.
     *
     * @param ascii
     *           each byte represents ASCII '0' or '1'
     * @return clean coded binary data where each bit is related to one byte in input
     *         array of bytes argument
     * @see org.apache.commons.codec.Decoder#decode(Object)
     */
    public static byte[] decode(byte[] ascii) {
        return fromASCII(ascii);
    }

    /**
     * Returns <code>true</code> if input array is <code>null</code> or
     * empty (length 0)
     *
     * @param array
     *            input array
     * @return <code>true</code> if input array is <code>null</code> or
     *         empty (length 0)
     */
    private static boolean isEmpty(byte[] array) {
        return array == null || array.length == 0;
    }

    public static void testEnvironment()
    throws
    NoSuchAlgorithmException,
    NoSuchPaddingException,
    GeneralSecurityException
    {

        // Testing 64-bit block
        byte[] data = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
        // Creates 128-bit key from raw bytes
        SecretKey key128 = new SecretKeySpec(new byte[] { 0x00, 0x01, 0x02,
                0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
                0x0d, 0x0e, 0x0f }, ALGORITHM);
        // Create ciphre and try to encrypt data block with defined key
        Cipher cipher = Cipher.getInstance(ALGORITHM + "/" + BLOCK_MODE + "/"
                + PADDING);
        cipher.init(Cipher.ENCRYPT_MODE, key128, CBC_SALT);
        cipher.doFinal(data);
        System.out.println("128-bit test result: O.K.");
        // Creates 192-bit key from raw bytes
        SecretKey key192 = new SecretKeySpec(new byte[] { 0x00, 0x01, 0x02,
                0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
                0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
                0x17 }, ALGORITHM);
        // Try to encrypt data block with new key
        cipher.init(Cipher.ENCRYPT_MODE, key192, CBC_SALT);
        cipher.doFinal(data);
        System.out.println("192-bit test result: O.K.");
        // Creates 256-bit key from raw bytes
        SecretKey key256 = new SecretKeySpec(new byte[] { 0x00, 0x01, 0x02,
                0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
                0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
                0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
                ALGORITHM);
        // Try to encrypt data block with new key
        cipher.init(Cipher.ENCRYPT_MODE, key256, CBC_SALT);
        cipher.doFinal(data);
        System.out.println("256-bit test result: O.K.");
        System.out.println("Testing JCE restrinctions finished.");
        cipher = null;
    }

    // --------------------------- main() method ---------------------------

    /**
     * Application for encrypt message using AES with 256-bit key in CBC mode.
     *
     * @param args
     *            Input parametric XML file. Message for encrypt.
     *
     * @throws NoSuchAlgorithmException
     *             if AES is not supported.
     * @throws NoSuchPaddingException
     *             if PKCS5 padding is not supported.
     * @throws InvalidKeyException
     *             if there is something bad with key.
     * @throws IOException
     *             if there is issue with file works.
     * @throws java.security.InvalidAlgorithmParameterException
     *             if there is issue with CBC_SALT(salting).
     */
    public static void main(String[] args)
    throws
    InvalidAlgorithmParameterException,
    InvalidKeyException,
    IOException,
    NoSuchAlgorithmException,
    InvalidAlgorithmParameterException,
    NoSuchPaddingException,
    Exception
    {
        // For test purposes
        // String file = "Test.xml";
        // String message = "Some string to encrypt;

        // If no arguments just write out help.
        if (args.length == 0) {
            testEnvironment();
            return;
        } else if (args.length == 2) {
            // Test JCE
            testEnvironment();

            // Initiation of encryption algorithm.
            out.println("Initiation of ciphre AES in CBC mode with \"padding\" PKCS5Padding");
            Cipher cipher = Cipher.getInstance(ALGORITHM + "/" + BLOCK_MODE
                    + "/" + PADDING);
            out.println("Initiation of ciphre O.K.");
            // Initiation of key.
            SecretKeySpec key = STATIC_KEY;
            out.println("Initiation of static key O.K.");
            out.println("Start encrypting >>> ...");
            // Attach and init variables of input parameters.
            String file = args[0].toString();
            String message = args[1].toString();

            // For testing.
            // String file = "/home/zangetsu/file.xml";
            // String message = "AES cifrovani v praxi";

            // Write input message to input file in encrypted and encoded form.
            writeEncrypted(cipher, key, file, message);
            out.println("End of encrypting >>> O.K.");
            cipher = null;
        } else {
            // Bad number or types of arguments.
        }
    }
}
 
Odpovědět 1.7.2013 10:52
Avatar
jnadbela
Člen
Avatar
jnadbela:

Nevím, jestil si to někdo přečte, ale JCE (Java Cryptography Extension) problém finálně NEŘEŠÍ. a proč???Pokud tu aplikaci budu provozovat na počítačí s upravenou JCE, bude všechno ok, šifrování ok. Ale pokud tu aplikaci přesunu na jiný počítač... kde NENÍ upravené JCE... Bude chyba délky klíče!!! A bude výjimka!!! Máte někdo řešení? O tom pochybuji.... Ale já ho mám. Vlastní šifrovací mechanismus. A trubky z politiky, které se montují do Javy, mohou jít... víte kam. Přeji hezký den. Mimochodem, s něčím takovým jsem se v jiných jazycích nesetkal... restrikce na šifrování. Kdo to kdy viděl. Toto mě opravdu zvedlo ze židle.

Odpovědět 11.12.2015 6:27
I kdyby jsi měl žít jen jeden jediný den, pracuj na sobě, protože ukládáš poklad do pokladnice.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 12. Zobrazit vše