JAVA APPLET读本地文件权限问题及解决办法

来源:互联网 发布:sql语言培训 编辑:程序博客网 时间:2024/04/30 04:55

综合网络上的资料有2中方法:
1,使用数字签名。
2,修改策略文件。

这里使用的方法是修改策略文件:

首先要确定IE所使用的Jre安装在哪个目录下。但没有找到比较好的方法,一般默认是C:/Program Files/Java/下。从IE的Internet选项中可以看到目前使用的版本,那就进入C:/Program Files/Java/中对应版本的文件夹。本机是C:/Program Files/Java/j2re1.4.2_05/

然后,进入到./lib/security下,打开java.policy文件。在grant的括号中填写
permission java.io.FilePermission "<<ALL FILES>>", "read,write";
本机修改的结果就是:

  1. // Standard extensions get all permissions by default   
  2.   
  3. grant codeBase  "file:${java.home}/lib/ext/*" {   
  4. permission java.security.AllPermission;   
  5. };    
  6.   
  7. // default permissions granted to all domains   
  8.   
  9. grant {    
  10. // Allows any thread to stop itself using the java.lang.Thread.stop()  
  11. // method that takes no argument.  
  12. // Note that this permission is granted by default only to remain  
  13. // backwards compatible.  
  14. // It is strongly recommended that you either remove this permission  
  15. // from this policy file or further restrict it to code sources  
  16. // that you specify, because Thread.stop() is potentially unsafe.  
  17. // See " http://java.sun.com/notes " for more information.  
  18. permission java.lang.RuntimePermission  "stopThread";    
  19.   
  20. // allows anyone to listen on un-privileged ports  
  21. permission java.net.SocketPermission  "localhost:1024-" "listen" ;    
  22.   
  23. // "standard" properies that can be read by anyone   
  24.   
  25. permission java.util.PropertyPermission  "java.version" "read" ;   
  26. permission java.util.PropertyPermission  "java.vendor" "read";   
  27. permission java.util.PropertyPermission  "java.vendor.url" "read" ;   
  28. permission java.util.PropertyPermission  "java.class.version" "read";   
  29. permission java.util.PropertyPermission  "os.name" "read" ;   
  30. permission java.util.PropertyPermission  "os.version" "read";   
  31. permission java.util.PropertyPermission  "os.arch" "read" ;   
  32. permission java.util.PropertyPermission  "file.separator" "read";   
  33. permission java.util.PropertyPermission  "path.separator" "read" ;   
  34. permission java.util.PropertyPermission  "line.separator" "read";    
  35.   
  36. permission java.util.PropertyPermission  "java.specification.version" "read";   
  37. permission java.util.PropertyPermission  "java.specification.vendor" "read" ;   
  38. permission java.util.PropertyPermission  "java.specification.name" "read";    
  39.   
  40. permission java.util.PropertyPermission  "java.vm.specification.version" "read";   
  41. permission java.util.PropertyPermission  "java.vm.specification.vendor" "read" ;   
  42. permission java.util.PropertyPermission  "java.vm.specification.name" "read";   
  43. permission java.util.PropertyPermission  "java.vm.version" "read" ;   
  44. permission java.util.PropertyPermission  "java.vm.vendor" "read";   
  45. permission java.util.PropertyPermission  "java.vm.name" "read" ;   
  46. permission java.io.FilePermission  "<<ALL FILES>>" "read,write";    
  47.   
  48. };    
  49.   

这样就可以让applet读写本地文件了。(也许需要重起一下IE)

方法2:数字签名  
数字签名常被用来校验软件及软件制造者,以保证软件代码没有被任何方式玷污。或者通俗地讲,使用数字签名可以确保软件的“清洁”和“正宗”,即软件    
     
  从其制造者或出版商处直到最终用户手中这段时间里未被他人篡改过。    
     
  本文在对数字签名的有关概念进行简单回顾后,给出了用JAVA来创建和使用    
     
  数字签名的具体方法。    
     
  一、数字签名及其功能    
     
  数字签名算法(DSA)   是“公共密钥加密算法”中的一种,因此让我们从    
     
  “私有密钥/公共密钥”开始进行简单回顾。    
     
  1.   私有密钥加密及其局限性    
     
  私有密钥加密系统使用唯一的密钥(即私有密钥)进行加密和解密。该密钥    
     
  必须为发送者和接收者所共享。即,若甲要向乙发一个加密邮件,甲需用一密钥    
     
  将信息加密;乙收到邮件后,须用同样的密钥将信息解密。    
     
  该方法显然有非常严重的缺点。例如,接收双方必须拥有同样的密钥,这要    
     
  求一定要有一种安全的协议来保证密钥传送的可靠;第二,有紧急的加密消息需    
     
  要发送时,可能因接收方没有密钥而不能完成传送;第三,若要将消息发给许多    
     
  不同的团体,就需要与各个团体对应,维护许多不同的密钥。    
     
  为克服私有密钥加密系统的这些弱点,人们引进了公共密钥加密系统。    
     
  2.   公共密钥加密    
     
  公共密钥加密不需要一条信息的发送者和接收者知道对方的密钥,就能访问    
     
  该加密信息。    
     
  公共密钥加密系统使用密钥对(公共密钥和私有密钥)来加密和解密信息。    
     
  其加密思想也非常简单:用公共密钥加密的信息只能用与之对应的私有密钥解开;    
     
  而用私有密钥加密的信息,任何拥有与之对应的公共密钥的人均可解开。因此,私    
     
  有密钥总为个人保管而无须外传,公共密钥则可授权给他人使用而不会破坏安全    
     
  性,公共密钥和私有密钥之间永远存在着一对一的关系。具体地讲即:    
     
  第一,若信息是用接收方的公共密钥加密的,则只有应该收到此消息的人    
     
  才能对之解密(即只有拥有与该公共密钥对应的私有密钥的人才可解密)。例如,    
     
  甲要向乙发一个加密邮件,甲必须用乙的公共密钥加密信息后再传给乙。    
     
  第二,若信息是用发送方的私有密钥加密的,则任何拥有发送方公共密钥的    
     
  接收者都可以对信息进行解密,从而确定该信息确实是来自该发送者,并且信息    
     
  内容未遭到任何无意或恶意的破坏。    
     
  上述第二点正是数字签名的含义。    
     
  3.   数字签名的功能    
     
  一个数字签名是一个定长的二进制数字流,其内容附着于被签名的数据之上。    
     
  它可以和任何种类的数字数据一起使用,除最普通的代码软件外。还可用在口令、    
     
  电子邮件及电子文档中。数字签名的主要功能为:防止原始文档被污染或变更;    
     
  防止别有用心者使用他人名字散布欺骗性消息;以及,提供谁是文件原作者的证    
     
  据,等等。    
     
  二、用JAVA创建及使用数字签名    
     
  除了上面提到的功能外,用JAVA做数字签名还有更现实的意义。最常见的是:    
     
  应用数字签名可以突破浏览器在安全性方面的某些限制。例如,你的浏览器一般    
     
  会拒绝网上的JAVA程序读写你本地硬盘的文件或获取你的本地信息(如你的用户    
     
  名称等),哪怕你确认该JAVA程序是“可靠的”(其实你不可能完全确认来自网    
     
  上的某个程序真的是“可靠的”)。若你确要运行该JAVA程序,你必须关闭浏览    
     
  器的安全检查功能,但这无异于将本地系统置为“不设防的城池”。使用数字签    
     
  名可完美地解决这个问题:当浏览器“感觉”到你使用的是签名后的JAVA小程序后,    
     
  它会自动搜索与之匹配的数字签名并进行校验,若成功则浏览器认定该JAVA小程序    
     
  是“值得信任的”,于是放行。这样,既保证了安全性,又可以让真正“可信的”的JAVA程序拥有许多特权(见下述JAVA程序)。    
     
  在   JDK1.1   中,与数字签名有关的工作是由工具程序   javakey   来完成的。    
     
  javakey   是   Sun   提供的一个命令行工具,用来为存档文件(jar   文件)生成数    
     
  字签名并管理密钥数据库。    
     
  下面我们将通过一个具体例子来看一看创建和使用数字签名的步骤,有关概    
     
  念和解释将在例子中给出。    
     
  1.   Java   程序及数字签名的创建   (加密方或签字者应执行的步骤)    
     
  下面的JAVA小程序非常简单,它的主要功能为:获取   Win95/98系统当前登录    
     
  用户的名称字符串,然后将之写入本地硬盘当前目录的   Test.Txt   文件上。

  1. import   java.awt.*;        
  2.        
  3. import   java.io.*;        
  4.        
  5. import   java.lang.*;        
  6.        
  7. import   java.applet.*;        
  8.        
  9. public    class   MyApp    extends   Applet   {        
  10.        
  11. DataOutputStream   out_file;        
  12.        
  13. public    void   paint(Graphics   g)   {        
  14.        
  15. try   {        
  16.        
  17. String   YourName   =   System.getProperty( "user.name" );        
  18.        
  19. out_file   =    new   DataOutputStream( new   FileOutputStream( "Test.Txt"));        
  20.        
  21. out_file.writeChars( "Your   Name:   "+YourName+ "/n");        
  22.        
  23. out_file.close();        
  24.        
  25. g.drawString( "Your   Name   has   been   written   to   file   <Test.Txt>",    20,    20);        
  26.        
  27. }        
  28.        
  29. catch   (IOException   e)   {        
  30.        
  31. g.drawString( "File   i/o   error",    12,    12);        
  32.        
  33. }        
  34.        
  35. catch   (SecurityException   se)   {        
  36.        
  37. g.drawString( "You   can   NOT   write   to   disk   or   get   User   Name.",    12,    12);        
  38.        
  39. }        
  40.        
  41. }        
  42.        
  43. }        
  44.        
  45. //   End   of   MyApp.java       


      
  将   MyApp.java   编译为   MyApp.class   后,用下面的   MyApp.html   送往浏览器    
     
  (命令为   appletviewer   MyApp.html)。

  1. <html>         
  2.        
  3. <title>    Java   Security   Example:   MyApp </title>         
  4.        
  5. <h1>    Java   Security   Example:   My   Application    </h1>         
  6.        
  7. <p>         
  8.        
  9. <applet    code= MyApp.class    width= 500    height= 200>         
  10.        
  11. </applet>         
  12.        
  13. <p>         
  14.        
  15. Here's   the    <a    href= "MyApp.java"  mce_href= "MyApp.java"> source </a> .          
  16.        
  17. <p>         
  18.        
  19. /*   End   of   MyApp.html   */       


      
  我们发现浏览器上显示的是“You   can   NOT   write   to   disk   or   get   User   Name”。    
     
  这是因为获取用户名和写本地硬盘均是系统安全特性所禁止的。    
     
  下面我们创建一个数字签名,以便该程序的使用者无须变更浏览器的安全检查    
     
  特性就能完成程序功能(即:读用户名,写入文件)。    
     
  第一步:创建一个实体,并将之设为“可信的”。    
     
  javakey   -cs   Kompass   true     
     
  此处的实体是指签字者(个人、公司或组织),这里假定为“Kompass”。参    
     
  数“-cs”告诉   javakey创建一个签字者并将之放入数据库中(不带参数运行javakey    
     
       
     
  将得到详细帮助信息)。可选参数“true”表示签字者“Kompass”是“可信    
     
  的”(缺省值是“不可信”)。    
     
  第二步:生成密钥对(公共密钥和私有密钥)并输出至文件(可选)。    
     
  javakey   -gk   Kompass   DSA   512   Kompass_pub   Kompass_priv    
     
  其中“DSA”是加密算法的名字,“512”是密钥的长度,“Kompass_pub”、    
     
  “Kompass_priv”分别是两个密钥输出文件的名字。    
     
  第三步:生成一个许可证(certificate)。    
     
  javakey   -gc   cert_directive_Kompass     
     
  这里的许可证即为可以交给接收方的数字签名。    
     
  上面的参数“cert_directive_Kompass”并不是输出文件名,而是一个缺省    
     
  参数配置文件名。通俗地讲,它象是一个“.ini”文件,javakey   根据该文件的    
     
  内容决定如何生成一个许可证。因此,签字者在执行本步骤之前必须用文本编辑    
     
  器先生成这个配置文件(学名叫指示文件--directive   file)。    
     
  以下给出文件   cert_directive_Kompass   的内容:    
     
  issuer.name=Kompass    
     
  issuer.cert=1    
     
  subject.name=Kompass    
     
  subject.real.name=Kompass    
     
  subject.org.unit=JavaSoft      
     
  subject.org=Sun   MicroSystems    
     
  subject.country=US    
     
  start.date=31   May   1999    
     
  end.date=30   May   2012    
     
  serial.number=1001    
     
  out.file=Kompass.key    
     
  /*   End   of   cert_directive_Kompass   */
    
     
  从上面最后一行可以看出,输出文件的名字被定义为“Kompass.key”,即:    
     
  数字签名“Kompass.key”连同签字后的文件将一同被发给接收者。    
     
  上述文件包括的其它信息主要有:发行者信息(issuer)、主题信息    
     
  (subject)、许可证信息(有效期限及序列号)等。    
     
  第四步:创建存档文件(   jar   文件)。    
     
  jar   cf   signMyApp.jar   MyApp.class   MyApp.html     
     
  这里需要说明的是,jar是   Sun提供的另一个命令行工具,用于生成和维护    
     
  存档文件(   .jar   文件)。   jar是一个打包工具,它可将JAVA小程序连同有关的    
     
  声音、图像、动画等文件一起打包成一个文件以便于JAVA产品的发布和传输。与    
     
  WinZip等工具一样,   jar在打包时也能对文件进行压缩。有关   jar的详细信息可    
     
  参阅   Sun的有关资料。    
     
  上述命令的功能是将文件“MyApp.class”与“MyApp.html”打包为存档文件    
     
  “signMyApp.jar”。    
     
  之所以需要本步操作,是因为   javakey只能对存档文件进行签名。    
     
  第五步:对存档文件进行签名。    
     
  javakey   -gs   sign_directive_Kompass   signMyApp.jar    
     
  与上面第三步一样,“sign_directive_Kompass”也是一个配置文件(指示    
     
  文件),用来告诉   javakey如何对文件进行签字。“sign_directive_Kompass”    
     
  的内容如下:    
     
  signer =Kompass    
     
  cert=1    
     
  chain=0    
     
  signature.file=KpsSig    
     
  /*   End   of   sign_directive_Kompass   */
    
     
  第六步:更改文件名。    
     
  ren   signMyApp.jar.sig   signMyApp.jar    
     
  我们注意到上面第五步的配置文件中未指定输出文件名。这种情况下   javakey    
     
       
     
  在被签文件的名字后面加上“.sig”作为输出文件名。    
     
  若要指定输出文件,应在“sign_directive_Kompass”中加入一行:    
     
  out.file=signMyApp.jar     
     
  至此,我们完成了数字签名的工作。将“Kompass.key”(数字签名)和    
     
  “signMyApp.jar”(签名后的文件)传给使用者即可。    
     
  2.   数字签名的使用   (解密方或使用者应执行的步骤)    
     
  第一步:得到许可证(即数字签名   --   Kompass.key)和签名后的文件。    
     
  第二步:创建签名者实体,并将之设为“可信的”。    
     
  javakey   -c   Kompass   true    
     
  第三步:将许可证倒入数据库。    
     
  javakey   -ic   Kompass   Kompass.key     
     
  最后一步:运行JAVA程序。    
     
  appletviewer   signMyApp.html    
     
  我们注意到这里的“.html”不是上面给出的“MyApp.html”。其实这二者    
     
  的差别很小,“signMyApp.html”只是多了一个参数:    
     
  archive="signMyApp.jar"     
     
  它告诉浏览器所有有用的文件(这里的   MyApp.class)均在存档文件中而不    
     
  在其它地方。    
     
  signMyApp.html   的内容如下:

  1.        
  2. <html>         
  3.        
  4. <title>    Java   Security   Example:   MyApp,signed </title>         
  5.        
  6. <h1>    Java   Security   Example:   The   Signed   Application    </ h1 >        
  7.        
  8. <p>         
  9.        
  10. <applet    code= MyApp.class    archive= "signMyApp.jar"    width= 500    height= 200>         
  11.        
  12. </applet>         
  13.        
  14. <p>         
  15.        
  16. Here's   the    <a    href= "MyApp.java"  mce_href= "MyApp.java"> source </a> .          
  17.        
  18. <p>         
  19.        
  20. /*   End   of   signMyApp.html   */       


      
  现在,我们终于看到了期待已久的结果:浏览器打出了“Your   Name   has    
     
  been   written   to   file   <Test.Txt>”;而文件“Test.Txt”确实被创建,并且    
     
  其内容正是用户登录   Win95/98   时的名字:    
     
  Y   o   u   r   N   a   m   e   :   M   a   w   e   n   q   i   a   n  

 

改变/jre1.5.0_06/lib/security/java.security。打开文件里面有policy.url.1和 policy.url.2,我们可以创建自己的policy.url.3,我们需要一个.policy文件,此文件的作用指定对客户端的文件的操作权限。可以使用policytool工具自己创建.policy.

一个扩展自Applet的类,里边有个方法写文件,一个方法读文件。

  1. import java.awt.BorderLayout;   
  2. import java.awt.Container;   
  3. import java.awt.event.ActionEvent;   
  4. import java.awt.event.ActionListener;   
  5. import java.awt.event.WindowAdapter;   
  6. import java.awt.event.WindowEvent;   
  7. import java.io.BufferedReader;   
  8. import java.io.FileNotFoundException;   
  9. import java.io.FileReader;   
  10. import java.io.FileWriter;   
  11. import java.io.IOException;   
  12. import java.io.PrintWriter;   
  13.   
  14. import javax.swing.JButton;   
  15. import javax.swing.JFrame;   
  16. import javax.swing.JPanel;   
  17. import javax.swing.JScrollPane;   
  18. import javax.swing.JTextArea;   
  19.   
  20. public  class MyFrame  extends JFrame  implements ActionListener{   
  21.   
  22.  JButton btRead =  new JButton( "Read");   
  23.  JButton btWrite =  new JButton( "Write");   
  24.  JTextArea txt1 =  new JTextArea( null, 8 , 35 );   
  25.  JScrollPane jspPanel =  new JScrollPane(txt1,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);   
  26.  JPanel jp =  new JPanel();   
  27.   public MyFrame(String title) {   
  28.    super(title);     
  29.  }   
  30.   public  void init()   
  31.  {   
  32.   Container con =  this.getContentPane();   
  33.   con.setLayout( new BorderLayout());   
  34.   jp.add(btRead);   
  35.   jp.add(btWrite);   
  36.   con.add(jp,BorderLayout.NORTH);     
  37.   con.add(jspPanel,BorderLayout.CENTER);   
  38.   btRead.addActionListener( this);   
  39.   btWrite.addActionListener( this);   
  40.  }   
  41.   
  42.   public  void actionPerformed(ActionEvent arg0) {   
  43.    if(arg0.getActionCommand().equals( "Read"))   
  44.   {   
  45.       
  46.    BufferedReader in =  null;   
  47.     try {   
  48.     in =  new BufferedReader( new FileReader( "d://dbase//humor.txt"));   
  49.    }  catch (FileNotFoundException e) {   
  50.     e.printStackTrace();   
  51.    }      
  52.    String s;   
  53.     try {   
  54.      while((s=in.readLine())!= null)   
  55.     {   
  56.      txt1.append(s+ "/n");   
  57.     }   
  58.     in.close();   
  59.    }  catch (IOException e) {   
  60.     e.printStackTrace();   
  61.    }     
  62.   }   
  63.    if(arg0.getActionCommand().equals( "Write"))   
  64.   {   
  65.    PrintWriter out =  null;   
  66.     try {   
  67.     out =  new PrintWriter( new FileWriter( "d://dbase//humor.txt"));   
  68.    }  catch (IOException e) {   
  69.     e.printStackTrace();   
  70.    }   
  71.    out.println( "it is a humor");   
  72.    out.close();   
  73.    txt1.append( "Write OK/n");   
  74.   }   
  75.  }   
  76. }   

转自:http://blog.csdn.net/gyflyx/article/details/6450941

原创粉丝点击