2009-07-30 1 views
2

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

Проблема, с которой я сейчас сталкиваюсь, заключается в поиске способа активировать функции шифрования/дешифрования в сгенерированном с помощью Hibernate SQL везде, где это поле ссылается и прозрачно для моего кода приложения. Это возможно? Я рассмотрел поддержку Hibernate для «полученных» свойств, но, к сожалению, этот подход не поддерживает поля чтения и записи. Любые идеи оценили.

+0

Можете ли вы уточнить бит типа «простой текст»? Означает ли это, что вы делаете что-то вроде 'SELECT my_field FROM my_table ORDER BY decrypt (my_field)'? – ChssPly76

+0

Да, но больше похоже на SELECT decrypt (my_field) FROM my_table ORDER BY decrypt (my_field). Во всяком случае, это один из примеров. Мне также нужно делать нечувствительные к регистру поиски (вызов UPPER по дешифрованному значению) и частичные совпадения строк с использованием оператора LIKE. Все эти вещи требуют, чтобы база данных могла выполнять дешифрование. –

ответ

1

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

-1

Если у вас есть доступ к шифрования/дешифрования алгоритма внутри Java, я создал свой отображенный класс что-то вроде

public class encryptedTable { 
    @Column(name="encrypted_field") 
    private String encryptedValue; 

    @Transient 
    private String value; 

    public String getEncryptedValue() { 
     return encryptedValue; 
    } 

    public String getValue() { 
     return value; 
    } 

    public void setEncryptedValue(String encryptedValue) { 
     this.encryptedValue = encryptedValue; 
     this.value = decrypt(encryptedValue); 
    } 

    public void setValue(String value) { 
     this.value = value; 
     this.encryptedValue = encrypt(value); 
    } 
} 

И затем использовать получить/установить значение как аксессору в вашей программе и оставить get/set EncryptedValue для использования в спящем режиме при доступе к базе данных.

+0

Это не относится к моему желанию, чтобы Hibernate автоматически вызывал функцию дешифрования базы данных, когда поле ссылается на запрос (например, для сортировки). –

1

У вас может быть триггер, внутренний для базы данных, который извлекает, расшифровывает значение и заменяет возвращенный результат, а при вставке шифрует значение и заменяет сохраненный результат на зашифрованное значение. Вы также можете сделать это с помощью оболочки представления, т. Е. Иметь триггер insert в представлении и иметь представление, автоматически расшифровывающее значение.

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

+0

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

+0

Мы используем аналогичный подход к этому, но у нас есть наша база данных, а затем мы реконструируем его. Вы можете иметь схему для представлений/триггеров как отдельную часть, если вы устанавливаете базу данных из объектов, а затем устанавливаете ее как часть сценария установки/выполнения. – aperkins

+0

Триггеры базы данных вызывается, когда данные вставлены, обновлены или удалены, а не выбраны. – HLGEM

4

Я не думаю, что есть способ сделать шифрование, как вы описали его полностью прозрачно для вашего приложения. Самое близкое, что вы можете получить, это сделать его прозрачным вне объекта. В своем классе сущностей:

@Entity 
@SQLInsert(sql="INSERT INTO my_table(my_column, id) VALUES(encrypt(?),?)") 
@SQLUpdate(sql="UPDATE my_table SET my_column = encrypt(?) WHERE id = ?") 
public class MyEntity { 

    private String myValue; 

    .... 

    @Formula("decrypt(my_column)") 
    public String getValue() { 
    return myValue; 
    } 

    public void setValue(String value) { 
    myValue = value; 
    } 

    @Column (name="my_column") 
    private String getValueCopy() { 
    return myValue; 
    } 

    private void setValueCopy(String value) { 
    } 

} 

value отображается как производное свойство, вы должны быть в состоянии использовать его в запросах.
valueCopy является закрытым и используется для получения производного имущества, доступного только для чтения.
SQLInsert и SQLUpdate - это черная магическая магия вуду для принудительного шифрования при вставке/обновлении. Обратите внимание, что для параметра порядка IS важно узнать, в каком порядке Hibernate будет генерировать параметры без использования пользовательской вставки/обновления, а затем повторить его.

+0

Мы сделали доказательство такой концепции. Я не сумасшедший о «поддельном» свойстве, но мне нравится идея использования явных INSERT и UPDATE в сочетании с представлением. Благодарю. –

-1

Почему бы просто не использовать шифрование сервера SQl, которое, похоже, уже существует, вызывая хранимый процесс в Hibernate вместо того, чтобы позволить Hibernate генерировать запрос?

+0

Хранимая процедура не решает проблему автоматического дешифрования поля, когда на него ссылается запрос. –

Смежные вопросы