jsf的安全问题

如果破解一个系统的代价比系统本来内容的价值还要高,则系统就是安全的。
1口令加密存储   相同的密码在数据库中显示的值不一定相同,这就是加盐的效果。
知识补充:
1)JAVA密码架构(JCA)是由java.security包和子包中的一系列类组成。
这些类提供了像消息摘要(MessageDigest)和数字签名(Signature)这样的
API函数。
2)加密服务提供者(provider)不同算法的集合。Sun提供者包含如下一些算法的实现:
MD5消息摘要,SHA-1消息摘要,随机数的产生,DSA数字签名的签署和证书,DSA密钥
对的产生,DSA密钥的转换,DSA算法的参数,DSA算法参数的产生,等等

3)图解:

MessageDigest->MessageDigestSPI->提供者1 MD5,提供者2 SHA-1
这里的MessageDigestSPI程序开发者不需要关心它,国为只有提供者才会用到它。

例:
MessageDigest md=MessageDigest.getInstance("MD5");
消息摘要和口令认证(看书p543两图解)
*权限管理应用的口令加密示例如下:
 1)数据库中口令类型为varbinary型。
2)Person.java中 private byte[] password;
映射文件中   <property name="password" type="byte[]">
            <column name="password" length="50" not-null="true" />
        </property>
3)加密码方法madeBytes(..),口令验证方法validPwd(..)  (可重用的方法 使用消息摘要,盐等知识)
详细见附
4)写到数据库
 注册用户
 用户输入密码password
 byte[] pwdBytes=null;
 pwdBytes=madeBytes(password); //调用加密方法
 person.setPssword(pwdBytes);
5)从数据库取出
 用户的登录
String valid=validPwd(password,person.getPassword);//第一个值是输入的值,第二个值是从数据库取出的值
 ...异常省略
 if("match".equals(valid)){登录成功};

 

2防止用户绕过登录的方法
isLogin.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%
if(((String)session.getAttribute("userId"))==null){
%>
<jsp:forward page="/login.faces"/>
<%
}
%>

其他页中引用<%@ include file="isLogin.jsp" %>

 


  //取得用户的口令加密byte[]   
    private byte[] madeBytes(String str)throws
          NoSuchAlgorithmException, UnsupportedEncodingException{
        //随机数生成器
     SecureRandom random=new SecureRandom();
     //声明盐数组变量
        byte[] salt=new byte[12];
        //声明加密后的口令数组变量
        byte[] pwd=null;
        //将随机数放入盐变量中
        random.nextBytes(salt);
        //声明消息摘要对象
        MessageDigest md=null;
  //创建消息摘要
  md = MessageDigest.getInstance("MD5");
  //将盐的数据传给消息摘要对象
  md.update(salt);
  //将口令的数据传给消息摘要对象 
  md.update(str.getBytes("UTF-8"));
  //获得消息摘要的字节数组 
  byte[] digest=md.digest();
        //因为要在口令的字节数组中存放盐,因此加上盐的字节长度
  pwd=new byte[digest.length+12];
        //将盐的字节拷贝到生成后的口令字节数组的前12个字节
  //以便在验证口令时会将盐取出
  System.arraycopy(salt,0,pwd,0,12);
  //将消息摘要拷贝到口令数组的从第13个字节开始的字节
  System.arraycopy(digest,0,pwd,12,digest.length);
        //返回生成的口令字节
        return pwd;
    }
   
    //检验口令是否相等
    private String validPwd(String str,byte[] pwdInDb) throws
           NoSuchAlgorithmException, UnsupportedEncodingException{
        //声明是否匹配的字符串变量
        String validated="";
     //声明盐变量
     byte[] salt=new byte[12];
     //将盐从数据库中保存的口令字节数组中拷贝出来
        System.arraycopy(pwdInDb,0,salt,0,12);
        //创建消息摘要对象
        MessageDigest md=MessageDigest.getInstance("MD5");
        //将盐的数据传给消息摘要对象
        md.update(salt);
        //将口令数据传给消息摘要对象
        md.update(str.getBytes("UTF-8"));
       
        //生成输入口令的消息摘要
        byte[] digest=md.digest();
        //声明一个保存数据库中口令消息摘要的变量
        byte[] digestInDb=new byte[pwdInDb.length-12];
        //取得数据库中口令的消息摘要
        System.arraycopy(pwdInDb,12,digestInDb,0,pwdInDb.length-12);
        //比较数组中的值是否相等
        if(Arrays.equals(digest, digestInDb))
        {
          //口令正确返回口令匹配信息
          validated = "match";
          return validated;

        }
        else
        {
          //口令不正确返回口令不匹配信息
          return validated;
        }
       
    }


 //处理用户注册
    public Person register(String personId, String password,
      String pwd,String personName,Departments department,
      String email,String telephone)
                 throws UserException {
     //构建一个新用户
        Person person=new Person();
        try {
            //判断口令 
            if(password.equals(pwd)){
                //设置用户属性
                person.setPersonId(personId);
                byte[] pwdBytes=null;
                try{
                    //将口令从字符串转换为字节数组
                    pwdBytes=madeBytes(password);
                }
                catch(NoSuchAlgorithmException ne){
                 //处理加密方法的异常
                 ne.printStackTrace();
                }
                catch(UnsupportedEncodingException ue){
                 //处理加密方法的错误
                 ue.printStackTrace();
                }
                person.setPassword(pwdBytes);
                person.setPersonName(personName);
                person.setDepartment(department);
                person.setEmail(email);
                person.setTelephone(telephone);
                //用dao在数据库表中创建一个用户记录
                userDao.create(person);
            }
            else{
                
                //表示欲注册的用户名不合乎要求,不能返回用户对象
                person=null;
            }
           
            //返回用户对象
            return person;
        }
        //处理数据库访问异常
        catch(DataAccessException daoe){
         
            //判断是否是因为该用户名已经注册过
            try{
                userDao.find(personId);
            }
            catch(DataAccessException daoe1){                        
             throw new DbException(daoe.getMessage());
            }             
           daoe.printStackTrace();                    
           //如果该用户名已经注册,则抛出重复的用户异常   
           throw new DuplicateUserException(personId);
        }       
     }
 //处理用户登录
    public Person login(String personId, String password) throws UserException {
     //构建一个新用户
        Person person=new Person();     
        try {
         //调用DAO查找用户
            person=userDao.find(personId);
            if(person!=null){                
               //判断口令是否匹配
               String valid="";
               try{
                valid=validPwd(password,person.getPassword());
               }
               catch(NoSuchAlgorithmException ne){
                //处理加密方法的异常
                ne.printStackTrace();
               }
               catch(UnsupportedEncodingException ue){
                //处理加密方法的错误
                ue.printStackTrace();
               }
               if("match".equals(valid)){                         
                   //加入所有部门列表
                   List departments=findAllDepartments();
                   person.setDepartments(departments);                 
                 
                   //加入登录用户的权限
                   List permissions=findPermission(personId);
                   person.setPermissions(permissions);
                }
                else{
                   //表示用户名和口令合乎要求的用户不存在
                   person=null;
                }
            }   
            else{
             //如果数据库中找不到用户记录抛出异常
                throw new DataNotFoundException(personId);
            }
            //如果通过验证,返回与该人员标识对应的人员对象
            return person;
        }
        //处理数据访问异常
        catch(DataNotFoundException ue){ 
           ue.printStackTrace();
           throw new UserNotExistException(personId);
        }
        catch(DataAccessException daoe){
           daoe.printStackTrace();          
           throw new DbException(daoe.getMessage());
        }     
     }
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值