Jér*_*nge 8 java security protection class
这是一个头脑风暴的问题,关于Java(或不是)的可能性.我想知道是否可以隐藏类中的秘密并防止再使用Java代码或其任何功能(安全性,反射,序列化,类加载器,你的名字......)来访问它.
以下是我到目前为止的想法:
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!!!");
}
}
Run Code Online (Sandbox Code Playgroud)
可以改进吗?它应该改进吗?是否无法实现在安全级别中锁定秘密的想法?
编辑
关联:
有些人质疑我在这里提出的问题的相关性.虽然我要问一个普遍的问题,以便触发一个开放的对话,但这个课程有一个非常具体的应用:
澄清:
事实:
解决的问题:
关于执行环境,我们需要区分两种情况:
如果我们设置一个适当的SecurityManager禁用反射并限制任何加载的不受信任代码的权限,那么我们的秘密是安全的.
黑客可以使用自己的安全管理器和安全类加载器创建自己的应用程序.它可以从类路径加载我们的代码并执行它,就好像它是我们自己的应用程序一样.在这种情况下,他可以打破保险箱.
Whi*_*g34 12
不,它与其他Java代码不安全.您的秘密可以从这样的实例中检索Safe:
Field field = safe.getClass().getDeclaredField("secret");
field.setAccessible(true);
String secret = (String) field.get(safe);
Run Code Online (Sandbox Code Playgroud)
更新:如果您控制要隐藏其他Java代码的加载,则可能使用自定义SecurityManager或ClassLoader阻止访问它.您需要控制其运行的环境才能工作,例如您限制访问的服务器.
但是,您编辑的问题提到代码可以在任何桌面或设备上运行.在那种情况下,你真的无法做任何事情来保护秘密免受其他可以做任何事情的进程.即使你在内存中加密它,另一个进程也可以直接拦截密钥甚至是明文秘密.
如果您不控制环境,那么您需要一些安全的环境,那么您可能需要考虑不同的方法.也许你可以避免将秘密存储在内存中?
Vla*_*hev 12
这种"安全"是可笑的.
它在哪里运行?在我的桌面上?我用调试器连接到JVM并以明文形式查看所有秘密.
或者我将代码放在旁边并使用反射来转储内容.
或者我通过BCEL注入我自己的代码修改,并修改Safe的构造函数以将"secret"值转储到文件中.
或者我只需将整个包替换为我的同名,将其放入bootstrap类加载器中.
或者我甚至可以修改和编译java源代码以获得修改后的JVM.
或者......我可以列出几种从运行时实例中提取值的方法!
任何安全设计中的真正问题是:谁是攻击者?什么是威胁模型?没有回答这个问题,这个话题毫无意义.
| 归档时间: |
|
| 查看次数: |
2782 次 |
| 最近记录: |