jsf的安全问题

news/2024/7/5 12:57:13 标签: jsf, string, byte, 数据库, permissions, 加密

如果破解一个系统的代价比系统本来内容的价值还要高,则系统就是安全的。
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());
        }     
     }
   


http://www.niftyadmin.cn/n/1425404.html

相关文章

并联系统的失效率公式推导步骤_小学数学一类求阴影部分周长和面积,记住两个公式就够了...

同学们好&#xff0c;我是小升初数学课堂。在小学数学学习的过程当中&#xff0c;我们要学会不断的总结。如果把一类题目&#xff0c;总结到位&#xff0c;下次再碰到这类题目就很轻松的解决了&#xff0c;比如说在学习六年级圆的当中&#xff0c;有一类求阴影部分周长和面积的…

selenium设置元素等待(python)

WebDriver提供了两种类型的元素等待&#xff1a;显式等待和隐式等待。 显式等待&#xff1a;WebDriver等待某个条件成立则继续执行&#xff0c;否则在达到最大时长时抛出超时异常(TimeoutException) WebDriverWait类是WebDriver提供的等待方法。在设置的时间内&#xff0c;默认…

MyEclipse 快捷键大全

CtrlQ跳到最后一次的编辑处F7由函数内部返回到调用处。F8一直执行到下一个断点。CtrlShiftS保存所有未保存的文件。Ctrl1 快速修复AltEnter 显示当前选择资源(工程,or 文件 or文件)的属性 ShiftEnter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)S…

docker 覆盖 entrypoint_Docker基础教程(2)-如何创建一个定制镜像并上传到DockerHub

如果对Docker还不是很了解的同学可以先看一下我之前的文章Docker基础教程(1)定制镜像的两种方式将容器打包成镜像容器和镜像之间是可以互相转变的,镜像可以运行成容器,容器也可以打包成镜像,可以将所有数据打包起来,原封不动的变成一个镜像 首先了解一下打包的命令docker commi…

结构体中函数应该怎样定义才能返回值_单片机编程时可变参函数的实现

新的多功能使用主控模块块的设计&#xff0c;板与板之间使用自定的协议来传递数据&#xff0c;在程序书写上&#xff0c; 我希望写成一个通用的数据协议&#xff0c;这样这个协议可以在后续直接移植我以后相当长一个时间内的其它产品上&#xff0c;这其中就需要用到可变参函数。…

jsf上下文取request

通过faces上下文和外部上下文获得request对象FacesContext facesContextFacesContext.getCurrentInstance();HttpServletRequest request (HttpServletRequest)facesContext.getExternalContext().getRequest(); 获得session对象HttpSession sessionrequest.getSession(); St…

Fixture_pytest

Fixture通常用来对测试方法&#xff0c;测试函数&#xff0c;测试类&#xff0c;和整个测试文件进行初始化或还原测试环境。 setup_module/teardown_module&#xff1a;在当前文件中&#xff0c;在所有测试用例执行之前与之后执行 setup_class/teardown_class&#xff1a;在当前…

*jsf的错误的提示

FacesMessage msg new FacesMessage(); msg.setSummary("两次输入的新密码不相同。"); msg.setDetail("两次输入的新密码不相同。"); //为了与原来例子保持一致&#xff0c;这里设置了消息的严重等级 …