Подтвердить что ты не робот

Как начать работу с BouncyCastle?

Итак, после CodingHorror весело с шифрованием и избивающих комментариев, мы пересматриваем свое собственное шифрование.

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

Вторая служба просматривает информацию об этом пользователе, а затем передает ее обратно сторонней службе.

Мы хотим зашифровать эту информацию пользователя, входящую в стороннюю службу, и расшифровать ее после ее выхода. Таким образом, это не долговечное шифрование.

В статье о ужасном кодировании Кода Хейл рекомендовал BouncyCastle и абстракцию высокого уровня в библиотеке, чтобы сделать шифрование, специфичное для конкретной потребности.

Моя проблема в том, что пространства имен BouncyCastle огромны, а документация не существует. Может ли кто-нибудь указать мне эту библиотеку абстракции высокого уровня? (Или другой вариант, кроме BouncyCastle?)

4b9b3361

Ответ 1

Абстракция высокого уровня? Я полагаю, что абстракции самого высокого уровня в библиотеке Bouncy Castle будут включать:

В основном я знаком с версией библиотеки Java. Возможно, этот фрагмент кода предложит вам достаточно высокую абстракцию для ваших целей (например, используется шифрование AES-256):

public byte[] encryptAES256(byte[] input, byte[] key) throws InvalidCipherTextException {
    assert key.length == 32; // 32 bytes == 256 bits
    CipherParameters cipherParameters = new KeyParameter(key);

    /*
     * A full list of BlockCiphers can be found at http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/BlockCipher.html
     */
    BlockCipher blockCipher = new AESEngine();

    /*
     * Paddings available (http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/paddings/BlockCipherPadding.html):
     *   - ISO10126d2Padding
     *   - ISO7816d4Padding
     *   - PKCS7Padding
     *   - TBCPadding
     *   - X923Padding
     *   - ZeroBytePadding
     */
    BlockCipherPadding blockCipherPadding = new ZeroBytePadding();

    BufferedBlockCipher bufferedBlockCipher = new PaddedBufferedBlockCipher(blockCipher, blockCipherPadding);

    return encrypt(input, bufferedBlockCipher, cipherParameters);
}

public byte[] encrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException {
    boolean forEncryption = true;
    return process(input, bufferedBlockCipher, cipherParameters, forEncryption);
}

public byte[] decrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException {
    boolean forEncryption = false;
    return process(input, bufferedBlockCipher, cipherParameters, forEncryption);
}

public byte[] process(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters, boolean forEncryption) throws InvalidCipherTextException {
    bufferedBlockCipher.init(forEncryption, cipherParameters);

    int inputOffset = 0;
    int inputLength = input.length;

    int maximumOutputLength = bufferedBlockCipher.getOutputSize(inputLength);
    byte[] output = new byte[maximumOutputLength];
    int outputOffset = 0;
    int outputLength = 0;

    int bytesProcessed;

    bytesProcessed = bufferedBlockCipher.processBytes(
            input, inputOffset, inputLength,
            output, outputOffset
        );
    outputOffset += bytesProcessed;
    outputLength += bytesProcessed;

    bytesProcessed = bufferedBlockCipher.doFinal(output, outputOffset);
    outputOffset += bytesProcessed;
    outputLength += bytesProcessed;

    if (outputLength == output.length) {
        return output;
    } else {
        byte[] truncatedOutput = new byte[outputLength];
        System.arraycopy(
                output, 0,
                truncatedOutput, 0,
                outputLength
            );
        return truncatedOutput;
    }
}

Изменить: Упс, я просто прочитал статью, с которой вы связались. Похоже, он говорит о абстракциях более высокого уровня, чем я думал (например, "отправить конфиденциальное сообщение" ). Боюсь, я не совсем понимаю, к чему он стремится.

Ответ 2

Предполагая, что вы пишете свое приложение на Java, я бы рекомендовал вам не использовать конкретный провайдер, но вы разрабатываете свое приложение поверх Sun JCE (расширение криптографии Java). Это может сделать вас независимыми от любых базовых поставщиков, то есть вы можете легко переключаться между поставщиками, пока вы используете широко используемые шифры. Это дает вам определенный уровень абстракции, так как вам не нужно знать все детали реализаций и может немного защитить вас от использования неправильных классов (например, например, с использованием необработанного шифрования без надлежащего заполнения и т.д.). Кроме того, Sun предоставляет достаточное количество документации и образцов кода.

Ответ 3

Одним из примеров высокого (er) -уровневого API в BouncyCastle будет CMS (Cryptographic Message Syntax). Это отправляется в отдельную банку (bcmail) из самого провайдера и записывается в JCE (однако версия С# написана против легкого API).

"Отправить конфиденциальное сообщение" реализовано, грубо говоря, классом CMSEnvelopedDataGenerator, и все, что вам действительно нужно сделать, это дать ему сообщение, выбрать алгоритм шифрования (все данные обрабатываются внутри), а затем указать один или несколько способы, с помощью которых получатель сможет прочитать сообщение: это может быть основано на открытом ключе/сертификате, общем секретном документе, пароле или даже протоколе соглашения о ключах. Вы можете иметь более одного получателя сообщения, и вы можете смешивать и сопоставлять типы получателей.

Вы можете использовать CMSSignedDataGenerator, чтобы аналогично отправлять проверяемое сообщение. Если вы хотите подписать и зашифровать, структуры CMS являются составными/составными (но порядок может быть важен). Там также CMSCompressedDataGenerator и недавно добавлены CMSAuthenticatedData.

Ответ 4

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

BlockCipher blockCipher = new AESEngine();

теперь становится:

BlockCipher blockCipher = new RijndaelEngine(256);

и он работает вместе с моим клиентским приложением. С++ AES256 encryption

Ответ 5

Вы можете использовать:

byte[] process(bool encrypt, byte[] input, byte[] key)
{
    var cipher = CipherUtilities.GetCipher("Blowfish");
    cipher.Init(false, new KeyParameter(key));
    return cipher.DoFinal(input);
}

// Encrypt:
byte[] encrypted = process(true, clear, key);

// Decrypt:
byte[] decrypted = process(false, encrypted, key);

Смотрите: https://github.com/wernight/decrypt-toolbox/blob/master/dtDecrypt/Program.cs

Ответ 6

JCE не будет работать для меня, потому что мы хотим иметь 256-битную силу и не можем изменить конфигурацию java в системе, чтобы это разрешить. Слишком плохо, что Bouncy Castle не имеет API как высокоуровневый, как JCE.

"Обратите внимание, однако, что bouncycastle состоит из двух библиотек, легкой библиотеки крипто и библиотеки интерфейса провайдера JCE. Ограничения на использование ключей выполняются с помощью уровня JCE, но вам не нужно использовать этот слой. легкий API Crypto, у вас нет каких-либо ограничений, независимо от того, какие файлы политики установлены или не установлены". http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography