- Java安全类库常见问题
- Q:有几种方式可以启动安全管理器?
- Q:如果我不设置安全管理器,直接跑System.getProperty,会报权限错误吗?
- Q: 隐式启动中,如果只配了-Djava.security.manager ,但没有配-Djava.security.policy, 那么上面的文件以及系统配置是都允许读,还是都不允许读?
- Q:如果我之前有隐式启动,此时new了一个新的SecurityManager放进去,此时是否还有该属性的read权限?
- 常见的java 安全权限
- Q: 详细讲讲安全管理器的应用场景?
- Q: 上面这个例子中, 如果恶意调用者自己在安全管理器中增加这种权限的处理怎么办?
- Q: 假设某服务实现了一个自定义classLoader, 支持从网络获取信任客户传来的jar包并在自己的服务中执行, 那么应该如何防止加载不可信的jar包呢?
- Q:不加盐值的哈希口令哈希有什么缺陷?
- Q:对口令做哈希加盐值时有什么要求?
[toc]
Java安全类库常见问题#
Q:有几种方式可以启动安全管理器?#
A:两种方式
隐式启动: 启动命令里加-Djava.security.manager, 即可开启安全管理器。
显示启动: 代码里自己new一个SecurityManager或者继承一个新子类, 然后用System.setSecurityManager(xxxSecurityManager)来设置
看以下代码:
1 | public class SecurityManagerTest { |
Q:如果我不设置安全管理器,直接跑System.getProperty,会报权限错误吗?#
A:
不会报错误。 如果隐式和显示启动都没做,那么System里的SecurityManager就是null,那么就不会进行检查。
可以看下System.getProperty里的源码:
Q: 隐式启动中,如果只配了-Djava.security.manager ,但没有配-Djava.security.policy, 那么上面的文件以及系统配置是都允许读,还是都不允许读?#
A:
都不允许读。 即开启后,不在policy允许范围内的,都默认不允许读。
-
如果要允许读文件以及读file.encoding那个系统配置, 需要加上-Djava.security.policy=xxx.policy , 指明policy文件。
-
文件里大概长这样
注意policy是拼在-Djava.security.manager的后面
显示启动,就是自己new一个SecurityManager,并set进去。
Q:如果我之前有隐式启动,此时new了一个新的SecurityManager放进去,此时是否还有该属性的read权限?#
A:没有了,之前由启动参数配进去的安全管理器已经被你覆盖掉了
对于隐式启动和显示启动, 都是默认没有任何可用权限!
都是白名单机制, 无黑名单机制。
常见的java 安全权限#
都是能从名字就知道什么作用的,瞄一眼有个印象就行,大概知道java里这些功能可能都会有权限。
-
java.security.AllPermission 所有权限的集合
-
java.util.PropertyPermission 系统/环境属性权限
就是System.getProperty(xxx.xxx.xxx)的权限 -
java.lang.RuntimePermission 运行时权限
这个安卓用的很多, -
java.net.SocketPermission Socket权限
-
java.io.FilePermission 文件权限,包括读写,删除,执行
-
java.io.SerializablePermission 序列化权限
-
java.lang.reflect.ReflectPermission 反射权限
-
java.security.UnresolvedPermission 未解析的权限
-
java.net.NetPermission 网络权限
-
java.awt.AWTPermission AWT权限
-
java.sql.SQLPermission 数据库sql权限
-
java.security.SecurityPermission 安全控制方面的权限
-
java.util.logging.LoggingPermission 日志控制权限
-
javax.net.ssl.SSLPermission 安全连接权限
-
javax.security.auth.AuthPermission 认证权限
-
javax.sound.sampled.AudioPermission 音频系统资源的访问权限
关于上面的permission权限,有一个重要的应用,就是在ClassLoader中。
如果JVM开启了SecurityManager, ClasserLoader就会在加载类的时候调用Policy.getPermissions来获取代码权限集, 并将代码来源和权限集封装到保护域。
1 | public class MyClassLoader extends URLClassLoader { |
Q: 详细讲讲安全管理器的应用场景?#
A:
- 如果你是某个平台开发者,提供了某个SDK给其他人使用, 这里面涉及了某个文件读取或者文件写入操作。
但是你只希望他用这个sdk去操作平台下特定目录的文件,而不是去动其他的位置(比如根目录之类的)
于是你就可以给sdk代码封装上一层权限, 在这个代码块中只能读特定目录(就像上面的filePermission) - 或者你通过的公开类中有个高危方法deleteXXX, 你希望拥有管理员权限的人才能调用,其他人不能调用, 于是可以在高危方法中加一层权限, 下面的例子来自安全编码规范, removeEncryt就是高危方法, 调用前会检查一下是否具有这个自定义的权限类型
1 | public class SensitiveHash { |
Q: 上面这个例子中, 如果恶意调用者自己在安全管理器中增加这种权限的处理怎么办?#
A: setSecurityManager方法API也是需要权限的。 作为客户端程序一般没有权限去设置SDK的安全管理器。 java默认的policy配置文件也没有放开这个权限。需要支持在policy里setSecurityManager才行。
Q: 假设某服务实现了一个自定义classLoader, 支持从网络获取信任客户传来的jar包并在自己的服务中执行, 那么应该如何防止加载不可信的jar包呢?#
A :
- 取出jar包中的证书资源
- 获取服务自身的密钥
- 校验证书是否是这些密钥的受信任签名(即我要识别你的这个证书是不是从我这里签发出去的)
注意,不要使用URLClassLoaer和java.util.jar里的自动签名校验机制,他只是检查jar包中的签名和公钥是否匹配,这仅仅是完整性校验, 这2者是可以被全部替换的
Q:不加盐值的哈希口令哈希有什么缺陷?#
A:
生日判定,可以快速找到一个口令
可以利用事先计算好的哈希列表几秒钟破解。
Q:对口令做哈希加盐值时有什么要求?#
A:
盐值至少应该包含8字节而且必须是由安全随机数产生。( 例如如果问你,sha256+4字节盐值,那肯定就是错误的!)
应使用强哈希函数,推荐使用SHA-256或者更加安全的哈希函数。
迭代次数默认推荐10000次,对于性能有特殊要求(比如嵌入式系统)的产品低可迭代1000次。
对于单向哈希时,其输出长度应该不小于256比特