我正在开发一个新的软件,我希望加密数据库中的值。我们正在使用OrientDB,并尝试使用tinkerpop库实现该项目。在这里,我陷入了一点点。
对于一个函数,我需要拉出一个类型的所有顶点的列表并返回它们。我有一个用于person对象的带注释的接口,我现在添加了加密和解密必要字段的方法。但是当我解密它们时,它会将解密的值保存回数据库。
有没有办法覆盖getter和setter来处理那时的加密/解密,还是我需要在执行解密之前从db中分离模型?
这是我的界面代码:
public interface iPerson {
@Property("firstName")
public void setFirstName(String firstName);
@Property("firstName")
public String getFirstName();
@Property("lastName")
public String getLastName();
@Property("lastName")
public void setLastName(String lastName);
@Property("id")
public String getId();
@Property("id")
public void setId(String id);
@Property("dateOfBirth")
public String getDateOfBirth();
@Property("dateOfBirth")
public void setDateOfBirth(String dateOfBirth);
@JavaHandler
public void encryptFields() throws Exception;
@JavaHandler
public void decryptFields() throws Exception;
public abstract class Impl implements JavaHandlerContext<Vertex>, iPerson {
@Initializer
public void init() {
//This will be called when a new framed element is added to the graph.
setFirstName("");
setLastName("");
setDateOfBirth("01-01-1900");
setPK_Person("-1");
}
/**
* shortcut method to make the class encrypt all of the fields that should be encrypted for data storage
* @throws Exception
*/
public void encryptFields() throws Exception {
setLastName(Crypto.encryptHex(getLastName()));
setFirstName(Crypto.encryptHex(getFirstName()));
if(getDateOfBirth() != null) {
setDateOfBirth(Crypto.encryptHex(getDateOfBirth()));
}
}
/**
* shortcut method to make the class decrypt all of the fields that should be decrypted for data display and return
* @throws Exception
*/
public void decryptFields() throws Exception {
setLastName(Crypto.decryptHex(getLastName()));
setFirstName(Crypto.decryptHex(getFirstName()));
if(getDateOfBirth() != null) {
setDateOfBirth(Crypto.decryptHex(getDateOfBirth()));
}
}
}
}
答案 0 :(得分:0)
(我假设)当设置了Vertex的属性时,数据会持久保存到数据库中。如果要在数据库中存储加密值,则需要确保在设置属性时加密值。
如果你想覆盖@Property
getter / setter方法的默认行为(这样你可以添加en / decryption),我建议使用自定义处理程序(例如@JavaHandler
)。
例如:
@JavaHandlerClass(Person.class)
public interface IPerson extends VertexFrame {
@JavaHandler
public void setFirstName(String firstName);
@JavaHandler
public String getFirstName();
}
abstract class Person implements JavaHandlerContext<Vertex>, IPerson {
@Override
void setFirstName(String firstName) {
asVertex().setProperty('firstName', encrypt(firstName))
}
@Override
String getFirstName() {
return decrypt(asVertex().getProperty('firstName'))
}
static String encrypt(String plain){
return plain.toUpperCase(); // <- your own implementation here
}
static String decrypt(Object encrypted){
return encrypted.toString().toLowerCase(); // <- your own implementation here
}
}
// setup
IPerson nickg = framedGraph.addVertex('PID1', IPerson)
IPerson jspriggs = framedGraph.addVertex('PID2', IPerson)
nickg.setFirstName('nickg')
jspriggs.setFirstName('jspriggs')
// re-retrieve from Frame vertices sometime later...
IPerson nickg2 = framedGraph.getVertex(nickg.asVertex().id, IPerson)
IPerson jspriggs2 = framedGraph.getVertex(jspriggs.asVertex().id, IPerson)
// check encrypted values (these are stored in the DB)...
assert nickg2.asVertex().getProperty('firstName') == 'NICKG'
assert jspriggs2.asVertex().getProperty('firstName') == 'JSPRIGGS'
// check decrypted getters...
assert nickg2.getFirstName() == 'nickg'
assert jspriggs2.getFirstName() == 'jspriggs'
如果使用Groovy
,您可以以编程方式拦截对这些方法的调用(这样会很好,因为您可以继续使用@Property
注释)。
我不确定是否有Tinkerpop
解决方案拦截这些来电,除了编写自己的自定义处理程序(可能尝试扩展JavaHandlerModule
?)。
答案 1 :(得分:0)
感谢您的评论,我应该早点回复,但我最近找到了一个更好的答案来解决我的问题。我一直在寻找一种方法来实现加密/解密而不会产生开销,而开发人员却没有注意到它的发生。
解决这个问题的更好方法实际上是在插入/更新之前和读取之后编写钩子,以便在数据库层处理它。我能够在java中编写它,为它打包一个jar文件并将其安装在我们的orientDB实例上,完美地拾取并帮助我们加密必要的字段而不会注意到速度的降低。