BouncyCastle J2ME RSA с использованием пользовательских ключей - PullRequest
2 голосов
/ 02 марта 2012

Я хотел бы использовать BouncyCastle J2ME / RIM Crypto в своем приложении Blackberry.

Проблема, с которой я столкнулся, заключается в том, что я хотел бы создать открытый ключ для шифрования из программы C # .NET, которая отправляет ключ в BlackBerry.

Можно ли зашифровать сообщение с использованием необработанной строки? Кроме того, мне нужно знать другую общую переменную, такую ​​как модуль и т. Д.? Извинения, но я совершенно новичок в алгоритмах криптографии.

Нужен ли мне BouncyCastle для этого или можно сделать это с помощью RIM Crypto?

Спасибо, Конор

Ответы [ 2 ]

3 голосов
/ 11 марта 2012

Открытый ключ RSA состоит из двух компонентов, а не только одного, как я думал.

Существует Exponent и Modulus.Они оба числа, но я передаю их Blackberry из клиента .NET в виде строк Base64 и декодирую их в байтовые массивы, когда они используются функцией шифрования RIM, поскольку они принимают байтовые массивы в качестве параметров.

byte[] exponent = Base64InputStream.decode("exponent base64 string");
byte[] modulus = Base64InputStream.decode("modulus base64 string");

NoCopyByteArrayOutputStream cipherUserData = new NoCopyByteArrayOutputStream();             
RSACryptoSystem cryptoSystem = new RSACryptoSystem(1024);

// Create Public key using your variables from before
RSAPublicKey publicKey = new RSAPublicKey( cryptoSystem, exponent, modulus);

// Encryption engine objects
RSAEncryptorEngine eEngine = new RSAEncryptorEngine(publicKey);
PKCS1FormatterEngine fEngine = new PKCS1FormatterEngine(eEngine);
BlockEncryptor cryptoStream = new BlockEncryptor(fEngine, cipherUserData);  


// Read the user data and encrypt while doing so. Remember, cryptoStream writes its data to
// cipherUserData so this is where the encrypted version of userData will end up.
cryptoStream.write( userData, 0, userData.length );

cryptoStream.close();
cipherUserData.close();

String encryptedUserData = new String(cipherUserData.toByteArray());

ЭтоВ общем, все, что есть, ребята, это просто, но мне потребовалось много времени, чтобы получить это из документации API:)

Важное замечание RSA ограничен в целях шифрования, так как выможет только зашифровать сообщение, которое <= размер ключа.Это 117 байтов для 1024-битного RSA и 245 байтов для 2048-битного RSA.Для шифрования больших сообщений принятым способом является шифрование сообщения с использованием AES или аналогичного, а затем шифрование ключа AES с помощью открытого ключа RSA.Вы отправите зашифрованный текст AES, а также зашифрованный текст RSA, содержащий ключ для дешифрования зашифрованного текста AES. </p>

То, что я написал выше, заняло несколько дней работы и чтения.Надеюсь, это поможет кому-то быстрее достичь своей цели.:)

3 голосов
/ 02 марта 2012

Я сделал это с помощью Bouncycastle, но с RIM Crypto похож.Следуй примеру.Как видите, ключи - это строки ...:

    public CypherDecypherExample()
   {        
    String plain    ="a plain string";
    String cipher   = null;
    String decipher = null;
    byte [] byte_cipher = null;
    byte [] byte_plain  = null;

    // key           |-- 128 bit -->|-- 256 bit --->|
    String key    = "aaaaaaaaaaaaaaaacccccccccccccccc";
    String iv     = "bbbbbbbbbbbbbbbb";

System.out.println("bouncycastle.plain: " + plain);

    try {
        byte_cipher = encrypt(plain.getBytes(), key.getBytes(), iv.getBytes());
        cipher = new String(byte_cipher);
        System.out.println("bouncycastle.cipher: " + cipher);

    } catch (Exception e) {
        e.printStackTrace();
    }


    try {
        byte_plain = decrypt(byte_cipher, key.getBytes(), iv.getBytes());
        decipher = new String(byte_plain);
        System.out.println("bouncycastle.decipher: " + decipher);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

} 

private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
throws Exception
{
    String plain = new String(data);
    System.out.println("bouncycastle.cipherData: " + plain);

    int minSize = cipher.getOutputSize(data.length);
    byte[] outBuf = new byte[minSize];
    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
    int length2 = cipher.doFinal(outBuf, length1);
    int actualLength = length1 + length2;
    byte[] result = new byte[actualLength];
    System.arraycopy(outBuf, 0, result, 0, result.length);

System.out.println("bouncycastle.cipherData returning");

    return result;
}

private static byte[] decrypt(byte[] cipher, byte[] key, byte[] iv) throws Exception
{
    PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher((BlockCipher) new CBCBlockCipher(
            new AESEngine()));
    CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
    aes.init(false, ivAndKey);
    return cipherData(aes, cipher);
}

private static byte[] encrypt(byte[] plain, byte[] key, byte[] iv) throws Exception
{       
    PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
            new AESEngine()));

    CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);

    aes.init(true, ivAndKey);

    return cipherData(aes, plain);
}
...