机密可以隐藏在提供访问凭据的“安全” Java类中吗?
|
这是关于(或没有)Java可能实现的一个集思广益的问题。我想知道是否有可能在一个类中隐藏一个秘密,并阻止它不再使用Java代码或仅使用其任何功能(安全性,自反性,序列化,类加载器,you-name-it ...)来访问它。
到目前为止,我的想法是:
public final class Safe {
private String secret;
private HashMap<String, Credentials> validCertificates
= new HashMap<String, Credentials>();
public Safe(String aSecret) {
this.secret = aSecret;
}
public final class Credentials {
private String user;
private Credentials(String user) {
this.user = user;
}
}
public final Credentials getCredential(String user) {
// Following test is just for illustrating the intention...
if ( \"accepted\".equals(user) ) {
return new Credentials(user);
} else {
return null;
}
}
public String gimmeTheSecret(Credentials cred) {
if ( this.validCertificates.get(cred.user) == cred ) {
return secret;
} else {
return null;
}
}
private void writeObject(ObjectOutputStream stream) throws IOException {
throw new RuntimeException(\"No no no no no no no!!!\");
}
}
可以改善吗?应该改进吗?将秘密锁定在安全类别中的想法是不可能实现的吗?
编辑
关联:
有人质疑我在这里提出的问题的相关性。尽管我要提出一个一般性问题以触发公开对话,但该类有一个非常具体的应用程序:
如果要解密某些消息,则需要将私钥数据加载到类中。如果我不能阻止其他Java代码访问它,那么就不可能创建一个安全的系统。当然,如果我想解密一条消息,我宁愿在类中完成它,也不要泄露秘密,但是,保险箱必须保持牢不可破。
澄清:
该类的实例仅在运行时创建,而不是在编译时创建
代码可以在Web服务器应用程序或任何桌面或设备应用程序中运行
该类仅用于在运行时将秘密存储在内存中,没有计划对其进行持久化(出于持久性考虑,可以/应该使用经典的加密技术)
事实:
为了在Java应用程序中实现安全性,应设置一个SecurityManager实例,在该实例中可以根据需要覆盖检查方法
该应用程序可以使用安全的类加载器加载不受信任的代码,并为其加载的类分配保护域。该域不应包含RuntimePermission(\“ setSecurityManager \”)。
不受信任的代码可以尝试更改SecurityManager,但是由于安全类加载程序未授予setSecurityManager权限,因此将引发SecurityException。
解决的问题:
关于执行环境,我们需要区分两种情况:
受控环境:我们开始启动应用程序,该应用程序将使用不受信任的代码来试图破坏我们的“安全”。
如果我们设置适当的SecurityManager来禁用反射并限制对任何已加载的不受信任代码的权限,则我们的机密是安全的。
不受控制的环境:黑客开始使用不可信的代码尝试破坏我们的“安全”的应用程序。
黑客可以使用自己的安全管理器和Secure Class loader创建自己的应用程序。它可以从类路径中加载我们的代码,并像执行我们自己的应用程序一样执行它。在这种情况下,他可能会破坏保险柜。
如一个单独的问题中所述,sun.misc.Unsafe无法破坏安全管理器
没有找到相关结果
已邀请:
12 个回复
嘘崇蔡对
的实例中检索您的秘密,如下所示:
更新:如果您控制要隐藏秘密的其他Java代码的加载,则可以使用自定义
或
以防止对其进行访问。您需要控制运行的环境,例如您限制访问的服务器。 但是,您编辑的问题提到该代码可以在任何台式机或设备上运行。在那种情况下,您实际上无能为力,无法保护机密不受可能做任何事情的其他进程的侵害。即使您在内存中对其进行加密,另一个过程也可以截获该密钥,甚至截获该密钥时还会截获纯文本秘密。 如果您无法控制环境,则需要安全的东西,那么您可能需要考虑采用其他方法。也许您可以避免将秘密完全存储在内存中?
攫怂绵十
献导外拘
昧伎
。
眠缝
届甸衬丝蚕
丧泉缝锋
逝媳蘑贩茄
,它可能就在其中。 如果您仅尝试验证它,则可以执行此操作的一种方法是在其中存储哈希。一旦要验证输入,就可以对其进行哈希处理并比较哈希值。
刷遍派戳
貉骂
厦惫
公藕