Oracle存储Blob保护数据安全(oracle保存blob)
Oracle存储Blob:保护数据安全
Blob(Binary Large Object)是指二进制大型对象,可以用于存储各种二进制数据,比如视频、音频、图像等等。在企业应用中,Blob往往被用作存储重要的机密数据,比如客户资料、财务数据等等。因此,对Blob的安全性要求非常高。本文将介绍Oracle数据库中如何存储Blob,并保证数据的安全。
1. 创建Blob表
在Oracle中,可以通过以下SQL语句创建一个Blob表:
“`sql
CREATE TABLE blob_table (
id NUMBER PRIMARY KEY,
name VARCHAR2(50),
data BLOB
);
其中,id和name是普通字段,data是BLOB类型的字段。
2. 存储Blob数据
在Java中,可以使用JDBC API将二进制数据存储到Oracle数据库中。以下是一个简单的示例:
```javaimport java.io.*;
import java.sql.*;
public class BlobTest { public static void mn(String[] args) throws Exception {
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "user", "password"); PreparedStatement pstmt = conn.prepareStatement("INSERT INTO blob_table (id, name, data) VALUES (?, ?, ?)");
pstmt.setInt(1, 1); pstmt.setString(2, "test");
pstmt.setBinaryStream(3, new FileInputStream("test.jpg"));
pstmt.executeUpdate(); pstmt.close();
conn.close(); }
}
在以上示例中,我们使用了PreparedStatement的setBinaryStream方法将test.jpg文件的二进制数据存储到了Blob字段中。
3. 读取Blob数据
在Java中,可以使用JDBC API将Blob数据从Oracle数据库中读取出来。以下是一个简单的示例:
“`java
import java.io.*;
import java.sql.*;
public class BlobTest {
public static void mn(String[] args) throws Exception {
Connection conn = DriverManager.getConnection(“jdbc:oracle:thin:@localhost:1521:xe”, “user”, “password”);
PreparedStatement pstmt = conn.prepareStatement(“SELECT data FROM blob_table WHERE id = ?”);
pstmt.setInt(1, 1);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
InputStream is = rs.getBinaryStream(1);
OutputStream os = new FileOutputStream(“test2.jpg”);
byte[] buffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
is.close();
}
rs.close();
pstmt.close();
conn.close();
}
}
在以上示例中,我们使用了ResultSet的getBinaryStream方法将Blob字段中的数据读取出来,并保存为test2.jpg文件。
4. 保护Blob数据安全
在上述示例中,我们已经成功地将Blob数据存储到Oracle数据库中,并从数据库中读取出来。但是,在实际应用中,我们需要保护Blob数据的安全性,防止未授权的访问和篡改。
4.1 使用DBMS_CRYPTO加密Blob数据
Oracle数据库提供了DBMS_CRYPTO包,可以用于加密Blob数据。以下是一个简单的示例:
```sqlCREATE OR REPLACE FUNCTION encrypt_blob(p_data IN BLOB, p_key IN RAW) RETURN BLOB IS
l_result BLOB;BEGIN
l_result := DBMS_CRYPTO.ENCRYPT( rawtohex(p_key),
DBMS_CRYPTO.HASH_SH256, p_data
); RETURN l_result;
END;/
CREATE OR REPLACE FUNCTION decrypt_blob(p_data IN BLOB, p_key IN RAW) RETURN BLOB IS l_result BLOB;
BEGIN l_result := DBMS_CRYPTO.DECRYPT(
rawtohex(p_key), DBMS_CRYPTO.HASH_SH256,
p_data );
RETURN l_result;END;
/
在以上示例中,我们定义了两个函数:encrypt_blob和decrypt_blob。encrypt_blob函数接收两个参数:p_data和p_key。p_data是待加密的Blob数据,p_key是加密用的密钥。encrypt_blob函数返回一个加密后的Blob数据。decrypt_blob函数接收两个参数:p_data和p_key。p_data是加密后的Blob数据,p_key是解密用的密钥。decrypt_blob函数返回一个解密后的Blob数据。
在Java中,我们可以使用如下代码进行Blob数据的加密和解密:
“`java
import java.io.*;
import java.sql.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class BlobTest {
public static void mn(String[] args) throws Exception {
Connection conn = DriverManager.getConnection(“jdbc:oracle:thin:@localhost:1521:xe”, “user”, “password”);
PreparedStatement pstmt = conn.prepareStatement(“UPDATE blob_table SET data = ? WHERE id = ?”);
pstmt.setBinaryStream(1, encryptBlob(new FileInputStream(“test.jpg”), “key”));
pstmt.setInt(2, 1);
pstmt.executeUpdate();
pstmt = conn.prepareStatement(“SELECT data FROM blob_table WHERE id = ?”);
pstmt.setInt(1, 1);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
InputStream is = new ByteArrayInputStream(decryptBlob(rs.getBytes(1), “key”));
OutputStream os = new FileOutputStream(“test2.jpg”);
byte[] buffer = new byte[1024];
int bytesRead = -1;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
is.close();
}
rs.close();
pstmt.close();
conn.close();
}
public static byte[] encryptBlob(InputStream is, String key) throws Exception {
SecretKey sk = new SecretKeySpec(key.getBytes(), “AES”);
Cipher c = Cipher.getInstance(“AES”);
c.init(Cipher.ENCRYPT_MODE, sk);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
CipherOutputStream cos = new CipherOutputStream(bos, c);
byte[] buffer = new byte[1024];
int bytesRead = is.read(buffer);
while (bytesRead != -1) {
cos.write(buffer, 0, bytesRead);
bytesRead = is.read(buffer);
}
cos.close();
is.close();
return bos.toByteArray();
}
public static byte[] decryptBlob(byte[] data, String key) throws Exception {
SecretKey sk = new SecretKeySpec(key.getBytes(), “AES”);
Cipher c = Cipher.getInstance(“AES”);
c.init(Cipher.DECRYPT_MODE, sk);
ByteArrayInputStream bis = new ByteArrayInputStream(data);
CipherInputStream cis = new CipherInputStream(bis, c);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead = cis.read(buffer);
while (bytesRead != -1) {
bos.write(buffer, 0, bytesRead);
bytesRead = cis.read(buffer);
}
cis.close();
bos.close();
return bos.toByteArray();
}
}
在以上示例中,我们使用了Java的加密库javax.crypto来进行Blob数据的加密和解密。encryptBlob函数接收两个参数:is和key。is是待加密的输入流,key是加密用的密钥。encryptBlob函数返回一个加密后的Blob数据。decryptBlob函数接收两个参数:data和key。data是加密后的Blob数据,key是解密用的密钥。decryptBlob函数返回一个解密后的Blob数据。
4.2 使用Oracle VPD限制Blob数据的访问权限
除了加密Blob数据,我们还可以使用Oracle的Virtual Private Database(VPD)功能来限制Blob数据的访问权限。以下是一个简单的示例:
```sqlCREATE OR REPLACE FUNCTION blob_policy (p_schema IN VARCHAR2, p_table IN VARCHAR2)
RETURN VARCHAR2 ISBEGIN
RETURN 'data IS NOT NULL';END;
/
BEGIN DBMS_RLS.ADD_POLICY (
object_schema => 'user', object_name => 'blob_table',
policy_name => 'blob_policy', policy_function => 'blob_policy',
statement_types => 'SELECT, UPDATE' );
END;/
在以上示例中,我们定义了一个名为blob_policy的函数,用于限制blob_table表中的数据访问权限。在函数中,我们返回了一个非空的条件,即data字段不为NULL。然后,我们使用DBMS_RLS.ADD_POLICY函数将blob_policy应用到blob_table表的SELECT和UPDATE语句中。
通过以上步骤,我们成功将Blob数据存储到了Oracle数据库中,并保证了数据的安全性。但是,在实际应用中,还需要进一步优化和完善数据安全策略,以确保企业数据的最佳保护。