2

私のJavaベースのWebアプリでは、DBに書き込まれる前にデータを暗号化し、メモリにロードされたら復号化したいと考えています。そのために、bouncycastle API を使用して、次のようなクラスを作成しました。

public class BlowfishEnrypter implements IEncrypter {

    /*--- Members ---*/

    private BufferedBlockCipher cipher;
    private KeyParameter key;

    /*--- Constructors ---*/

    /**
     * Initialize the cryptographic engine. The key array should be at least 8
     * bytes long.
     * 
     * @param key
     */
    public BlowfishEnrypter(byte[] key) {
    cipher = new BufferedBlockCipher(new CBCBlockCipher(new BlowfishEngine()));
    this.key = new KeyParameter(key);
    }

    /**
     * Initialize the cryptographic engine. The key array should be at least 8
     * bytes long.
     * 
     * @param key
     */
    public BlowfishEnrypter(String key) {
    this(key.getBytes());
    }

    /*--- Public ---*/

    /**
     * {@inheritDoc}
     */
    public String encrypt(String input) throws EncryptionException {
    if (StringUtils.hasText(input)) {
        byte[] bytes = Hex.decode(input);
        try {
        return new String(encrypt(bytes));
        } catch (CryptoException e) {
        throw new EncryptionException("Error occured while trying to encrypt", e);
        }
    } else {
        throw new EncryptionException("Illegal argument for encryption: " + input);
    }
    }

    /**
     * {@inheritDoc}
     */
    public String decrypt(String input) throws EncryptionException {
    if (StringUtils.hasText(input)) {
        byte[] bytes = Hex.decode(input);
        try {
        return new String(decrypt(bytes));
        } catch (CryptoException e) {
        throw new EncryptionException("Error occured while trying to decrypt", e);
        }
    } else {
        throw new EncryptionException("Illegal argument for decryption: " + input);
    }
    }

    /*--- Private ---*/

    /**
     * Encrypt arbitrary byte array, returning the encrypted data in a different
     * byte array.
     * 
     * @param data
     * @return Encrypted byte array
     * @throws CryptoException
     */
    private synchronized byte[] encrypt(byte[] data) throws CryptoException {
    if (data == null || data.length == 0) {
        return new byte[0];
    }

    cipher.init(true, key);
    return callCipher(data);
    }

    /**
     * Decrypts arbitrary data
     * 
     * @param data
     *            To decrypts
     * @return Decrypted byte array
     * @throws CryptoException
     */
    private synchronized byte[] decrypt(byte[] data) throws CryptoException {
    if (data == null || data.length == 0) {
        return new byte[0];
    }

    cipher.init(false, key);
    return callCipher(data);
    }

    /**
     * Private routine that does the gritty work.
     * 
     * @param data
     *            Data to operate on
     * @return Processed byte array
     * @throws CryptoException
     */
    private byte[] callCipher(byte[] data) throws CryptoException {
    int size = cipher.getOutputSize(data.length);
    byte[] result = new byte[size];
    int olen = cipher.processBytes(data, 0, data.length, result, 0);
    olen += cipher.doFinal(result, olen);

    if (olen < size) {
        byte[] tmp = new byte[olen];
        System.arraycopy(result, 0, tmp, 0, olen);
        result = tmp;
    }

    return result;
    }
}

ここまではとても良いです (私はそう思います。このクラスについて何かコメントがあればどうぞ)。このクラスを初期化するには、キーを提供する必要があります。私の質問は、このキーをどのように管理すればよいですか?

もう少し詳しく言うと:

  • 特定の技法を使用して作成する必要がありますか?
  • どこに保管すればよいですか?プロパティファイルで?DBで?私のコードのどこかに?
  • このキー (ここでは文字列について話していますよね?) を暗号化し、ロードまたは使用後に復号化する必要がありますか? もしそうなら、どうすればいいですか?
4

2 に答える 2

1

いくつかのものに依存します:

  1. あなたのコードは、他の人が見たりアクセスしたりできない安全な場所に保存されていますか? もしそうなら、私はそれをコードに入れます。
  2. キーを時々変更することを想定していますか (この方法でより安全になります)? そうであり、ポイント 1 がまだ当てはまる場合は、それをプロパティ ファイルに貼り付けます。
  3. それ以外の場合は、データベースに入れて、データベースのユーザー名/パスワードを秘密にしてください!

ただし、元のキーを保護するためにキーをどこに置くので、実際のキーを暗号化する必要があるのか​​ わかりません。

ただし、Java SE セキュリティを調べて、Java Keystore などで何ができるかを確認することをお勧めします。さらに、役に立つかもしれない弾む城のウェブサイトでリソースを読むこともできます.

于 2012-09-18T08:28:15.443 に答える
1

多くの Web アプリで同様の暗号化を使用しています。通常、キーはソース コードのプロパティ ファイルに文字列として保持されます。キーは暗号化されておらず、強力にするためだけに特殊文字とその他の文字列の組み合わせを含む文字列です (数字、大文字など)。ライブになると、キーは通常、ビジネス ユーザーによって約 6 か月に 1 回変更されます。

于 2012-09-18T08:48:14.807 に答える