JAVA数字签名提升权限
2011-01-19 15:17
351 查看
本文描述怎样通过数字签名提升java的访问权限,本文环境:
os:Ubuntu9.10 64b
Firefox:3.5.8 jre环境:JRE 1.6.0_18(64b)
测试java代码和jsp页面代码如下:
Java代码
![](http://skzr-org.javaeye.com/images/icon_copy.gif)
public class TestApplet extends Applet {
private static final long serialVersionUID = 1L;
private void info(String msg) {
System.out.println(msg);
}
@Override
public void init() {
super.init();
readFile("Linux".equalsIgnoreCase(System.getProperty("os.name")) ? "/etc/hostname" : "c://boot.ini");
}
private void readFile(final String filePath) {
info("读取文件:" + filePath);
String text = AccessController.doPrivileged(new PrivilegedAction<String>() {
@Override
public String run() {
StringBuilder buffer = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(filePath));
while(reader.ready()) buffer.append(reader.readLine());
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return buffer.toString();
}
});
info("读取结果为:" + text);
}
}
Html代码
![](http://skzr-org.javaeye.com/images/icon_copy.gif)
<%@ page language="java" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<body>
<applet id="hh" alt="Applet" width="100" height="100"
code="org.skzr.TestApplet"
archive="skzr-applet-sign.jar"
codebase="<%=basePath %>demo" mayscript>
</applet>
</body>
</html>
因为考虑到大家一般是windows 32位环境所以:导出时使用我的linux64下仅有的32位jdk:jdk1.6.0_14-32
把以上类导出为包:skzr-applet.jar
签名:(使用同一个32位jdk:jdk1.6.0_14-32)
1 创建keystore:
/prog/java/jdk1.6.0_14-32/bin/keytool -genkey -keystore skzr-applet.keystore -alias skzr-applet
2 签名:
/prog/java/jdk1.6.0_14-32/bin/jarsigner -keystore skzr-applet.keystore skzr-applet.jar skzr-applet
把demo放入tomcat的webapps下,打开http://localhost:8080/demo/index.jsp测试
index.jsp里面使用未签名包 :skzr-applet.jar在控制台可以发现异常:
java.lang.IllegalStateException: java.security.AccessControlException: access denied (java.io.FilePermission /etc/hostname read),因为我的是linux所以读取此文件
index.jsp里面使用已签名包 :skzr-applet-sign.jar在控制台可以发现正确读取了文件:下面是控制台输出:
Html代码
![](http://skzr-org.javaeye.com/images/icon_copy.gif)
读取文件:/etc/hostname
读取结果为:skzr
basic: Applet initialized
至此权限提升完毕 ^ ^
![](http://dl.javaeye.com/upload/attachment/221107/13132253-0a70-3f5c-a22c-d1963a0c2784.png)
firefox 3.5.8
![](http://dl.javaeye.com/upload/attachment/221105/8420c31b-8c72-39e7-9472-3bd482f48689.png)
至于Windows下是一样的效果
![](http://dl.javaeye.com/upload/attachment/221118/b6476b1d-5f01-3684-b7e7-1a844656eefd.png)
如果真的签名了,客户端加载运行jar时会出现询问是否信任此签名的提示的!
问题在于,你如果签名了整个applet jar那么每一次重新发布都需要重新签名,比较繁琐,好的办法是,把需要提升权限的打为一个jar,一般这个jar不会经常更改的,签名此jar就可以了,其他的(如界面UI)的jar就算修改了也不需要重新签名的
2 要点:需要提升权限的类一定要放入一个jar包,签名一次即可
3 注意执行需要权限的代码需要一个特殊的方法执行,
AccessController.doPrivileged(...)如果信任此签名,将可以执行此代码
os:Ubuntu9.10 64b
Firefox:3.5.8 jre环境:JRE 1.6.0_18(64b)
测试java代码和jsp页面代码如下:
Java代码
![](http://skzr-org.javaeye.com/images/icon_copy.gif)
public class TestApplet extends Applet {
private static final long serialVersionUID = 1L;
private void info(String msg) {
System.out.println(msg);
}
@Override
public void init() {
super.init();
readFile("Linux".equalsIgnoreCase(System.getProperty("os.name")) ? "/etc/hostname" : "c://boot.ini");
}
private void readFile(final String filePath) {
info("读取文件:" + filePath);
String text = AccessController.doPrivileged(new PrivilegedAction<String>() {
@Override
public String run() {
StringBuilder buffer = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(filePath));
while(reader.ready()) buffer.append(reader.readLine());
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return buffer.toString();
}
});
info("读取结果为:" + text);
}
}
public class TestApplet extends Applet { private static final long serialVersionUID = 1L; private void info(String msg) { System.out.println(msg); } @Override public void init() { super.init(); readFile("Linux".equalsIgnoreCase(System.getProperty("os.name")) ? "/etc/hostname" : "c://boot.ini"); } private void readFile(final String filePath) { info("读取文件:" + filePath); String text = AccessController.doPrivileged(new PrivilegedAction<String>() { @Override public String run() { StringBuilder buffer = new StringBuilder(); BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(filePath)); while(reader.ready()) buffer.append(reader.readLine()); } catch (Exception e) { throw new IllegalStateException(e); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return buffer.toString(); } }); info("读取结果为:" + text); } }
Html代码
![](http://skzr-org.javaeye.com/images/icon_copy.gif)
<%@ page language="java" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<body>
<applet id="hh" alt="Applet" width="100" height="100"
code="org.skzr.TestApplet"
archive="skzr-applet-sign.jar"
codebase="<%=basePath %>demo" mayscript>
</applet>
</body>
</html>
<%@ page language="java" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <html> <body> <applet id="hh" alt="Applet" width="100" height="100" code="org.skzr.TestApplet" archive="skzr-applet-sign.jar" codebase="<%=basePath %>demo" mayscript> </applet> </body> </html>
因为考虑到大家一般是windows 32位环境所以:导出时使用我的linux64下仅有的32位jdk:jdk1.6.0_14-32
把以上类导出为包:skzr-applet.jar
签名:(使用同一个32位jdk:jdk1.6.0_14-32)
1 创建keystore:
/prog/java/jdk1.6.0_14-32/bin/keytool -genkey -keystore skzr-applet.keystore -alias skzr-applet
2 签名:
/prog/java/jdk1.6.0_14-32/bin/jarsigner -keystore skzr-applet.keystore skzr-applet.jar skzr-applet
把demo放入tomcat的webapps下,打开http://localhost:8080/demo/index.jsp测试
index.jsp里面使用未签名包 :skzr-applet.jar在控制台可以发现异常:
java.lang.IllegalStateException: java.security.AccessControlException: access denied (java.io.FilePermission /etc/hostname read),因为我的是linux所以读取此文件
index.jsp里面使用已签名包 :skzr-applet-sign.jar在控制台可以发现正确读取了文件:下面是控制台输出:
Html代码
![](http://skzr-org.javaeye.com/images/icon_copy.gif)
读取文件:/etc/hostname
读取结果为:skzr
basic: Applet initialized
读取文件:/etc/hostname 读取结果为:skzr basic: Applet initialized
至此权限提升完毕 ^ ^
效果图:
google chrome for linux![](http://dl.javaeye.com/upload/attachment/221107/13132253-0a70-3f5c-a22c-d1963a0c2784.png)
firefox 3.5.8
![](http://dl.javaeye.com/upload/attachment/221105/8420c31b-8c72-39e7-9472-3bd482f48689.png)
至于Windows下是一样的效果
![](http://dl.javaeye.com/upload/attachment/221118/b6476b1d-5f01-3684-b7e7-1a844656eefd.png)
例子demo
demo.zip其中skzr-applet.jar未签名 skzr-applet-sign.jar是签名后的包
总结:
1 jre的策略文件不需要更改的如果真的签名了,客户端加载运行jar时会出现询问是否信任此签名的提示的!
问题在于,你如果签名了整个applet jar那么每一次重新发布都需要重新签名,比较繁琐,好的办法是,把需要提升权限的打为一个jar,一般这个jar不会经常更改的,签名此jar就可以了,其他的(如界面UI)的jar就算修改了也不需要重新签名的
2 要点:需要提升权限的类一定要放入一个jar包,签名一次即可
3 注意执行需要权限的代码需要一个特殊的方法执行,
AccessController.doPrivileged(...)如果信任此签名,将可以执行此代码
相关文章推荐
- JAVA数字签名提升权限
- java Applet 数字签证提升权限
- Java加密和数字签名消息摘要一
- DSA数字签名原理及JAVA实现
- java加密和数字签名3 公钥加密
- Java2下Applet数字签名具体实现方法
- Java加密和数字签名私钥加密二
- Java2下Applet数字签名具体实现方法
- 详解Java数字签名提供XML安全
- java安全之数字签名及证书
- Java2下Applet数字签名具体实现方法
- 一个基于RSA算法的Java数字签名例子
- Java数字证书对文件/加密/解密/签名/校验签名
- DSA数字签名原理及JAVA实现
- 一个基于RSA算法的Java数字签名例子
- 给自己开发的ocx空间数字签名的方法(青岛金鑫-java技术攻略)
- 用Java数字签名提供XML安全
- Java数字签名相关
- 【graceup系列】--基于Java带数字签名的邮件收发系统
- Java2下Applet数字签名具体实现方法