Как зашифровать long или int с помощью крипто-подпрограмм Bouncy Castle для BlackBerry? - PullRequest
1 голос
/ 18 марта 2010

Как зашифровать / расшифровать long или int, используя криптографические процедуры Bouncy Castle для BlackBerry?Я знаю, как зашифровать / расшифровать строку.Я могу зашифровать длинное, но не могу заставить длинное правильно расшифровать.

Часть этого плохо сделана, но сейчас я просто пробую кое-что.включил весь мой криптографический движок здесь:

import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;

public class CryptoEngine
{

    // Global Variables

    // Global Objects
    private static AESFastEngine engine;

    private static BufferedBlockCipher cipher;

    private static KeyParameter key;

    public static boolean setEncryptionKey(String keyText)
    {
        // adding in spaces to force a proper key
        keyText += "                  ";

        // cutting off at 128 bits (16 characters)
        keyText = keyText.substring(0, 16);

        keyText = HelperMethods.cleanUpNullString(keyText);
        byte[] keyBytes = keyText.getBytes();
        key = new KeyParameter(keyBytes);
        engine = new AESFastEngine();
        cipher = new PaddedBufferedBlockCipher(engine);

        // just for now
        return true;
    }

    public static String encryptString(String plainText)
    {
        try
        {
            byte[] plainArray = plainText.getBytes();
            cipher.init(true, key);
            byte[] cipherBytes = new byte[cipher.getOutputSize(plainArray.length)];
            int cipherLength = cipher.processBytes(plainArray, 0, plainArray.length, cipherBytes, 0);
            cipher.doFinal(cipherBytes, cipherLength);
            String cipherString = new String(cipherBytes);
            return cipherString;
        }
        catch (DataLengthException e)
        {
            Logger.logToConsole(e);
        }
        catch (IllegalArgumentException e)
        {
            Logger.logToConsole(e);
        }
        catch (IllegalStateException e)
        {
            Logger.logToConsole(e);
        }
        catch (InvalidCipherTextException e)
        {
            Logger.logToConsole(e);
        }
        catch (Exception ex)
        {
            Logger.logToConsole(ex);
        }
        // else
        return "";// default bad value
    }

    public static String decryptString(String encryptedText)
    {
        try
        {
            byte[] cipherBytes = encryptedText.getBytes();
            cipher.init(false, key);
            byte[] decryptedBytes = new byte[cipher.getOutputSize(cipherBytes.length)];
            int decryptedLength = cipher.processBytes(cipherBytes, 0, cipherBytes.length, decryptedBytes, 0);
            cipher.doFinal(decryptedBytes, decryptedLength);
            String decryptedString = new String(decryptedBytes);

            // crop accordingly
            int index = decryptedString.indexOf("\u0000");
            if (index >= 0)
            {
                decryptedString = decryptedString.substring(0, index);
            }
            return decryptedString;
        }
        catch (DataLengthException e)
        {
            Logger.logToConsole(e);
        }
        catch (IllegalArgumentException e)
        {
            Logger.logToConsole(e);
        }
        catch (IllegalStateException e)
        {
            Logger.logToConsole(e);
        }
        catch (InvalidCipherTextException e)
        {
            Logger.logToConsole(e);
        }
        catch (Exception ex)
        {
            Logger.logToConsole(ex);
        }
        // else
        return "";// default bad value
    }

    private static byte[] convertLongToByteArray(long longToConvert)
    {
        return new byte[] { (byte) (longToConvert >>> 56), (byte) (longToConvert >>> 48), (byte) (longToConvert >>> 40), (byte) (longToConvert >>> 32), (byte) (longToConvert >>> 24), (byte) (longToConvert >>> 16), (byte) (longToConvert >>> 8), (byte) (longToConvert) };
    }

    private static long convertByteArrayToLong(byte[] byteArrayToConvert)
    {
        long returnable = 0;
        for (int counter = 0; counter < byteArrayToConvert.length; counter++)
        {
            returnable += ((byteArrayToConvert[byteArrayToConvert.length - counter - 1] & 0xFF) << counter * 8);
        }
        if (returnable < 0)
        {
            returnable++;
        }
        return returnable;
    }

    public static long encryptLong(long plainLong)
    {
        try
        {
            String plainString = String.valueOf(plainLong);
            String cipherString = encryptString(plainString);
            byte[] cipherBytes = cipherString.getBytes();
            long returnable = convertByteArrayToLong(cipherBytes);
            return returnable;
        }
        catch (Exception e)
        {
            Logger.logToConsole(e);
        }
        // else
        return Integer.MIN_VALUE;// default bad value
    }

    public static long decryptLong(long encryptedLong)
    {
        byte[] cipherBytes = convertLongToByteArray(encryptedLong);
        cipher.init(false, key);
        byte[] decryptedBytes = new byte[cipher.getOutputSize(cipherBytes.length)];
        int decryptedLength = cipherBytes.length;
        try
        {
            cipher.doFinal(decryptedBytes, decryptedLength);
        }
        catch (DataLengthException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IllegalStateException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (InvalidCipherTextException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        long plainLong = convertByteArrayToLong(decryptedBytes);

        return plainLong;
    }

    public static boolean encryptBoolean(int plainBoolean)
    {
        return false;
    }

    public static boolean decryptBoolean(int encryptedBoolean)
    {
        return false;
    }

    public static boolean testLongToByteArrayConversion()
    {
        boolean returnable = true;
        // fails out of the bounds of an integer, the conversion to long from byte
        // array does not hold, need to figure out a better solution
        for (long counter = -1000000; counter < 1000000; counter++)
        {
            long test = counter;
            byte[] bytes = convertLongToByteArray(test);
            long result = convertByteArrayToLong(bytes);
            if (result != test)
            {
                returnable = false;
                Logger.logToConsole("long conversion failed");
                Logger.logToConsole("test = " + test + "\n result = " + result);
            }
            // regardless
        }
        // the end
        Logger.logToConsole("final returnable result = " + returnable);
        return returnable;
    }
}

Ответы [ 2 ]

1 голос
/ 20 марта 2010

Я только что понял, что с сильными шифрами длина результата обычно / всегда больше, чем длина оригинала. Если это не так, можно использовать таблицу поиска. Таким образом, невозможно шифровать long в long каждый раз, особенно если он использует все 64 бита. Если это не имеет смысла, обратитесь ко мне за дополнительной информацией:

Как зашифровать строку и получить зашифрованную строку равной длины?

1 голос
/ 18 марта 2010

Это, вероятно, преобразование long -> byte [] -> String, в частности преобразование из String обратно в byte []. Вы не передаете кодировку для String.getBytes (), поэтому она будет использовать кодировку символов по умолчанию, которая может изменить ваши данные.

Я предлагаю использовать методы шифрования / дешифрования, которые принимают в качестве аргумента byte [], чтобы избежать преобразования String / byte [].

Также вы можете взглянуть на собственные классы RIM AES, AESEncryptorEngine и AESDecryptorEngine , которые могут быть быстрее BouncyCastle (поскольку они являются собственными API) и требуют меньше кода.

...