В базе данных SQL Server 2012 у меня есть таблица с столбцом varbinary (128), в которой хранятся данные, зашифрованные с помощью ключа подписи (AppCert) (Secret_Key) и аутентификатор, используя хэш SHA2_512 первичного ключа:Hibernate/JPA и MS SQL Server - открыть симметричный ключ до DecryptByKey
CREATE TABLE [Lookup].[SecretStuff] (
[Id] tinyint NOT NULL,
[Secret] varbinary(128) NOT NULL
CONSTRAINT [PK_Lookup-SecretStuff_Id] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [UN_Lookup-SecretStuff_Secret] UNIQUE NONCLUSTERED ([Secret])
);
OPEN SYMMETRIC KEY [Secret_Key] DECRYPTION BY CERTIFICATE [AppCert];
INSERT INTO [Lookup].[SecretStuff] ([Id], [Secret]) VALUES (1, ENCRYPTBYKEY(KEY_GUID('Secret_Key'), CONVERT(nvarchar(512), 'I have a secret'), 1, HASHBYTES('SHA2_512', CONVERT(varbinary(128), CONVERT(tinyint, 1)))));
CLOSE SYMMETRIC KEY [Secret_Key];
OPEN SYMMETRIC KEY [Secret_Key] DECRYPTION BY CERTIFICATE [AppCert];
SELECT [Id], CONVERT(nvarchar, DECRYPTBYKEY([Secret], 1, HASHBYTES('SHA2_512', CONVERT(varbinary, [Id])))) AS [Secret] FROM [Lookup].[SecretStuff];
CLOSE SYMMETRIC KEY [Secret_Key];
Все это прекрасно работает. Теперь у меня есть приложение Spring Boot, использующее JPA/Hibernate, который подключен и проверен/проверен для работы с этой базой данных. Класс SecretStuff:
@Entity
@Table(name="SecretStuff", schema="Lookup")
public class SecretStuff {
@Id
@Column(name = "Id",
nullable = false)
private Integer id;
@Column(name = "Secret",
nullable = false,
unique = true)
@Size(min = 1, max = 255)
@ColumnTransformer(
read = "CONVERT(nvarchar(89), DECRYPTBYKEY([Secret], 1,
HASHBYTES('SHA2_512', CONVERT(varbinary(128), [Id]))))")
private String secret;
// getters/setter omitted
}
Когда я проверить класс SecretStuff, я вижу следующее Hibernate генерируется SQL:
select
secretstuf0_.Id as Id1_7_0_,
CONVERT(nvarchar(89), DECRYPTBYKEY(secretstuf0_.[Secret],
1,
HASHBYTES('SHA2_512',
CONVERT(varbinary(128),
secretstuf0_.[Id])))) as Secret2_7_0_
from
Lookup.SecretStuff secretstuf0_
where
secretstuf0_.Id=?
Совершенно разумный запрос, который выполняется и возвращает 1 строку с Id = 1 Тайной = NULL, потому что SYMMETRIC KEY не открывается до выполнения запроса.
Мой вопрос: Как я могу выполнить команду ОТКРЫТЬ SYMMETRIC KEY ... в той же самой транзакции перед запросом и ЗАКРЫТЬ СИММЕТРИЧНОМ KEY ... команды в той же самой транзакции после запроса?
Я использовал Hibernate.initialize внутри методов класса обслуживания для ленивого извлечения во многие отношения внутри транзакций. Использую ли я здесь подобный подход? Как?
Я видел this article, так как я набирал этот вопрос, но ему пару лет, и он использует подход EntityManager с NativeQuery. Есть ли обновленный способ управления этим с помощью JPA/Hibernate?