web-dev-qa-db-ja.com

BouncyCastleの使用を開始するにはどうすればよいですか?

したがって、 CodingHorrorの暗号化の楽しみ とスラッシングコメントの後で、独自の暗号化を行うことを再検討しています。

この場合、ユーザーを特定する情報をサードパーティのサービスに渡す必要があります。サードパーティのサービスは、情報とハッシュを使用してWebサイト上のサービスにコールバックします。

2番目のサービスは、そのユーザーに関する情報を検索し、それをサードパーティのサービスに返します。

サードパーティのサービスに入るこのユーザー情報を暗号化し、公開後に復号化します。したがって、これは長続きする暗号化ではありません。

コーディングホラーの記事で、Coda Haleは、特定のニーズに固有の暗号化を行うために、BouncyCastleとライブラリ内の高レベルの抽象化を推奨しました。

私の問題は、BouncyCastle名前空間が巨大であり、ドキュメントが存在しないことです。誰かが私にこの高レベルの抽象化ライブラリを教えてもらえますか? (またはBouncyCastle以外の別のオプション?)

27
Jeff Martin

高レベルの抽象化? BouncyCastleライブラリの最高レベルの抽象化には次のものが含まれると思います。

私はライブラリの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;
    }
}

編集:おっと、あなたがリンクした記事を読みました。彼は私が思っていたよりもさらに高いレベルの抽象化について話しているようです(たとえば、「機密メッセージを送信する」)。彼が何をしているのかよくわからないのではないかと思います。

12
Adam Paynter

アプリケーションをJavaで作成することをお勧めしますが、特定のプロバイダーを使用しないことをお勧めしますが、SunのJCE(Java Cryptography Extension)上でアプリケーションを開発することをお勧めします。基盤となるプロバイダーから独立させることができます。つまり、広く実装されている暗号を使用している限り、プロバイダーを簡単に切り替えることができます。実装の詳細をすべて知る必要がないため、ある程度の抽象化が可能です。また、間違ったクラスの使用から少し保護する場合があります(たとえば、適切なパディングなしで生の暗号化を使用するなど)。さらに、Sunは適切な量のドキュメントとコードサンプルを提供します。

3
Accipitridae

BouncyCastleの高レベルAPIの一例は、CMS( 暗号化メッセージ構文 )パッケージです。これは、プロバイダー自体とは別のjar(bcmail)で出荷され、JCEに書き込まれます(ただし、C#バージョンは軽量APIに対して書き込まれます)。

「機密メッセージの送信」は、大まかに言えば、CMSEnvelopedDataGeneratorクラスによって実装されます。実際に行う必要があるのは、メッセージを送信し、暗号化アルゴリズム(すべての詳細は内部で処理される)を選択してから、1つ以上の方法を指定することです。受信者はメッセージを読むことができます。これは、公開鍵/証明書、共有秘密、パスワード、または鍵共有プロトコルに基づくことができます。 1つのメッセージに複数の受信者を含めることができ、受信者のタイプを組み合わせて組み合わせることができます。

CMSSignedDataGeneratorを使用して、同様に検証可能なメッセージを送信できます。署名と暗号化を行う場合、CMS構造はネスト可能/構成可能です(ただし、順序が重要になる場合があります)。 CMSCompressedDataGeneratorと最近追加されたCMSAuthenticatedDataもあります。

2
Peter Dettman

次のものを使用できます。

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

1
Wernight

このサンプルでは、​​256ビットではなくデフォルトの128ビット暗号化を使用していることが実際にわかりました。私は少し変更を加えました:

BlockCipher blockCipher = new AESEngine();

今になる:

BlockCipher blockCipher = new RijndaelEngine(256);

そしてそれは私のクライアントアプリケーションC++ AES256暗号化と一緒に動作します

1
user188766

256ビットの強度が必要であり、システムのJava構成を変更して許可できないため、JCEは機能しません。残念ながら、BouncyCastleのAPIはそれほど高くありません。 -JCEとしてのレベル。

「ただし、bouncycastleは、軽量暗号ライブラリとJCEプロバイダーインターフェイスライブラリの2つのライブラリで構成されていることに注意してください。キーサイズの制限はJCEレイ​​ヤーによって適用されますが、このレイヤーを使用する必要はありません。軽量暗号APIのみを使用する場合どのポリシーファイルがインストールされているかどうかに関係なく、直接制限はありません。」 http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography

0
kevin

Javaで暗号化を始める は、弾む城のライブラリに基づいた非常に役立つ例と説明が含まれています

0
iffi