찾다
Javajava지도 시간Java 이중 MD5 암호화로 보안 로그인을 달성하는 방법

One: 문제 소개

데이터베이스에 저장된 비밀번호를 해독합니다:

Java 이중 MD5 암호화로 보안 로그인을 달성하는 방법

Java 이중 MD5 암호화로 보안 로그인을 달성하는 방법

내 비밀번호가 성공적으로 해독된 것을 볼 수 있습니다. 이는 저를 놀라게 했습니다. MD5 알고리즘은 되돌릴 수 없기 때문입니다. 이는 해시 함수이며 해시 알고리즘을 사용합니다. 계산 과정에서 원본 정보의 일부가 손실됩니다. 그러면 왜 내 비밀번호가 웹사이트에서 해독될 수 있나요?

몇번의 검색 끝에 온라인 복호화 도구의 복호화 원리는 매우 간단하다는 것을 알았습니다. 원칙은 사용자가 일반적으로 사용하는 간단한 비밀번호를 수집하여 비밀번호 사전을 만든 다음 사전에 있는 비밀번호를 MD5로 암호화하여 저장하는 것입니다. 소위 "해독"할 때 실제 사용자 비밀번호 암호화의 암호문을 저장된 암호와 비교합니다. 암호문이 사전에 있으면 "해독"될 수 있습니다. 따라서 단순히 MD5를 사용하여 사용자 비밀번호를 암호화하는 것은 안전하지 않습니다. 비밀번호를 설정할 때 일반적으로 보안상의 이유로 비밀번호에는 영어 숫자 등이 포함되어야 합니다.

복호화 원리를 알고 나면 "복호화"가 가능한지 확인하기 위해 더 복잡한 비밀번호를 시도합니다. 먼저 비밀번호 "qweasd666"을 암호화합니다.

Java 이중 MD5 암호화로 보안 로그인을 달성하는 방법

암호화 후 32자리 소문자 암호문을 선택합니다. 복호화 작업:

Java 이중 MD5 암호화로 보안 로그인을 달성하는 방법

복호화 실패는 일치 및 크래킹을 위해 일반적으로 사용되는 암호문을 수집하는 것이 원칙임을 나타냅니다. "qweasd666" 비밀번호는 크랙이 불가능하므로 안전하며 모두 이 비밀번호를 사용하시면 됩니다(doge).

본론으로 돌아가서, 이 웹사이트는 내가 신중하게 설정한 비밀번호를 성공적으로 해독했고, 이로 인해 나는 매우 불안감을 느꼈고 로그인 보안 수준을 향상시켜야 한다고 느꼈습니다.

위에 언급한 암호 해독 작업 외에도 또 다른 큰 문제는 프런트 엔드가 데이터를 전송할 때 http가 일반 텍스트 전송을 사용한다는 것입니다. 전송 데이터 패킷이 가로채면 백엔드에 있는 암호화 알고리즘이 아무리 많아도 마찬가지입니다. 복잡하므로 귀하의 비밀번호는 다른 사람에게 알려지게 됩니다.

둘: 해결책

2.1: 첫 번째 암호화

문제를 찾은 후 올바른 약을 처방할 수 있습니다. 우선 http 일반 텍스트 전송 문제를 해결해야 한다고 생각합니다. 왜냐하면 이 위험이 가장 크고 일반적이기 때문입니다. 패킷 캡쳐로 캡쳐할 수 있는데 비밀번호 알아내기 무섭지 않나요? 일반 텍스트 전송에는 보안 문제가 있으므로 암호화를 통해 전송 보안을 보장할 수 있습니다

저는 여전히 MD5 암호화 방식을 사용하지만 비밀번호를 암호화하기 전에 고정된 솔트 값을 추가합니다. 소금? 소금을 넣는 건가요? 사실은 '조미료'를 조금 더 넣는다는 표현이 더 맞을 것 같습니다. 기본 아이디어는 다음과 같습니다. 사용자가 처음으로 비밀번호를 제공할 때(보통 등록 시) 프로그램은 개발 부담을 줄이기 위해 비밀번호에 일부 "소스"를 뿌립니다. 그런 다음 이 양념은 모든 사용자에게 동일합니다. 다시 해시합니다. 이렇게 하면 전송 중에 일반 텍스트 비밀번호가 유출되는 것을 방지할 수 있습니다.

2.2: 2차 암호화

참고로 제가 위에서 언급한 것은 일반 텍스트 비밀번호의 유출을 방지하기 위한 것이지만, 이것이 http나 데이터베이스를 통해 전송된 암호화된 비밀번호를 해커가 가로채더라도 암호문이 유출되지 않는다는 의미는 아닙니다. 해커는 유출이 발생하고 암호화된 비밀번호를 훔칩니다. 해커는 프런트엔드 js 파일을 파싱하여 프런트엔드 고정 솔트 값을 획득합니다. 그러면 해커는 레인보우 테이블을 통해 역질의를 수행하여 해당 값을 얻을 수 있습니다. 원래 비밀번호. 이때 2차 암호화의 중요성이 나옵니다. 2차 암호화의 구현 원리는 프런트 엔드에서 전달된 암호화된 비밀번호를 임의의 Salt 값과 결합한 후 암호화하는 것입니다(이번에는 임의의 솔트입니다). 값은 사용자가 로그인할 때 무작위로 생성되어 데이터베이스에 저장됩니다.

이때, 처음에 했던 것과 같은 의문이 드실 수 있는데, 즉 랜덤 솔트 값을 데이터베이스에 저장해 두었는데, 데이터베이스가 유출되면 랜덤 솔트 값은 어떻게 될까요? 해커가 암호화된 데이터를 복호화하고 솔트 값을 제거하면 비밀번호를 알아내는 것이 가능하지 않을까? 예, 해커가 그러한 수단을 통해 비밀번호를 얻는 것이 가능하지만, 이를 해독할 수 있는 경우에만 가능합니다. 당신이 알아야 할 것은 MD5는 직접 크랙할 수 없으며 철저한 방법을 통해서만 해독될 수 있다는 것입니다. 해커가 데이터베이스에서 암호화된 비밀번호를 알아냈지만 백엔드 암호화 과정을 알지 못한다면, 해커가 암호화 과정을 동시에 알고 있더라도 2차 솔팅으로 인해 이를 파싱할 수 없게 됩니다. 암호화된 데이터의 복잡성이 증가함에 따라 크래킹 비용이 기하급수적으로 증가하므로 이때의 암호문은 파싱하기가 어렵습니다. 시도 해봐. 물론 꼭 앞부분이나 끝부분에 소금을 넣을 필요는 없고 중간에 넣거나 따로 넣거나 역순으로 넣을 수도 있다. 프로그램 설계 시 유연하게 조정할 수 있어 난이도가 기하급수적으로 높아질 수 있다. 열분해.

2.3: 특정 구현

2.3.1: 사용자 등록

  • 프런트 엔드는 사용자가 입력한 비밀번호(고정 솔트)에 대해 md5 암호화를 수행하고

  • 암호화된 비밀번호를 백엔드에 전달합니다

  • 끝은 무작위로 솔트를 생성합니다

  • 생성된 솔트를 이용해 프런트엔드에서 전달된 비밀번호를 암호화한 후, 암호화된 비밀번호와 솔트를 함께 db에 저장합니다

2.3.2: 사용자 로그인

  • 프런트엔드에서 사용자에게 입력된 비밀번호는 md5 암호화(고정솔트)

  • 암호화된 비밀번호는 백엔드로 전달됩니다

  • 백엔드는 사용자 계정을 사용해 사용자 정보를 검색합니다

  • 백엔드 암호화된 비밀번호에 대해 md5를 수행하고(솔트 제거) 데이터베이스에 저장된 비밀번호와 비교합니다.

  • 일치하면 로그인이 성공하고, 그렇지 않으면 로그인이 실패합니다.

세 가지: 코드 구현

3.1: 첫 번째 암호화

3.1.1: 프런트엔드

const params = {
    ...this.ruleForm,
    sex: this.ruleForm.sex === '女' ? '0' : '1',
    //设置密码加密(加上固定salt值)
    password: md5(this.ruleForm.password + this.salt)
}
addEmployee(params).then(res => {
    if (res.code === 1) {
        this.$message.success('员工添加成功!')
        if (!st) {
            this.goBack()
        } else {
            this.ruleForm = {
                username: '',
                'name': '',
                'phone': '',
                password: '',
                // 'rePassword': '',/
                'sex': '男',
                'idNumber': ''
            }
        }
    } else {
        this.$message.error(res.msg || '操作失败')
    }
}

3.1.2: 백엔드

/**
* 添加员工
*/
@PostMapping
public R<String> save(@RequestBody Employee employee){
    //生成随机salt值
    String salt = RandomStringUtils.randomAlphanumeric(5);
    //设置随机盐值
    employee.setSalt(salt);
    //设置密码二次加密
    employee.setPassword(DigestUtils.md5DigestAsHex((salt + employee.getPassword()).getBytes()));
 
    boolean save = employeeService.save(employee);
    if(save){
        return R.success("添加成功!");
    }
    return R.error("添加失败!");
}

3.2: 두 번째 암호화

3.2.1: 프런트엔드

const params = {
    ...this.loginForm,
    //登录密码加上固定盐值后发送
    password: md5(this.loginForm.password + this.salt),
}
let res = await loginApi(params)
if (String(res.code) === &#39;1&#39;) {
    localStorage.setItem(&#39;userInfo&#39;, JSON.stringify(res.data))
    window.location.href = &#39;/backend/index.html&#39;
} else {
    this.$message.error(res.msg)
    this.loading = false
}

3.2.2: 백엔드

/**
 * 员工登录
 */
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){
    //1.获取传输过来的加密后的密码值
    String encryPassword = employee.getPassword();
 
    //2.从数据库中获取用户信息
    LambdaQueryWrapper<Employee> lqw = new LambdaQueryWrapper<>();
    lqw.eq(Employee::getUsername,employee.getUsername());
    Employee emp = employeeService.getOne(lqw);
 
    //3.如果没有查询到则返回登陆失败查询结果
    if(emp == null){
        return R.error("没有查询到该用户信息!");
    }
 
    //4.获取注册时保存的随机盐值
    String salt = emp.getSalt();
 
    //5.将页面提交的密码password进行md5二次加密
    String password = DigestUtils.md5DigestAsHex((salt + encryPassword).getBytes());
 
    //6.密码比对,如果不一致则返回登陆失败结果
    if(!emp.getPassword().equals(password)){
        return R.error("密码错误!");
    }
 
    //7.查看员工状态是否可用
    if(emp.getStatus() == 0){
        return R.error("该员工已被禁用!");
    }
    
    //8.登录成功,将员工id存入Session对象并返回登录成功结果
    request.getSession().setAttribute("employee",emp.getId());
    return R.success(emp);
}

위 내용은 Java 이중 MD5 암호화로 보안 로그인을 달성하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 亿速云에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
Intellij Idea는 로그를 출력하지 않고 스프링 부팅 프로젝트의 포트 번호를 어떻게 식별합니까?Intellij Idea는 로그를 출력하지 않고 스프링 부팅 프로젝트의 포트 번호를 어떻게 식별합니까?Apr 19, 2025 pm 11:45 PM

IntellijideAultimate 버전을 사용하여 봄을 시작하십시오 ...

데이터베이스 쿼리 조건을 구축하기 위해 엔티티 클래스 변수 이름을 우아하게 얻는 방법은 무엇입니까?데이터베이스 쿼리 조건을 구축하기 위해 엔티티 클래스 변수 이름을 우아하게 얻는 방법은 무엇입니까?Apr 19, 2025 pm 11:42 PM

데이터베이스 작업에 MyBatis-Plus 또는 기타 ORM 프레임 워크를 사용하는 경우 엔티티 클래스의 속성 이름을 기반으로 쿼리 조건을 구성해야합니다. 매번 수동으로 ...

Redis 캐시 솔루션을 사용하여 제품 순위 목록의 요구 사항을 효율적으로 실현하는 방법은 무엇입니까?Redis 캐시 솔루션을 사용하여 제품 순위 목록의 요구 사항을 효율적으로 실현하는 방법은 무엇입니까?Apr 19, 2025 pm 11:36 PM

Redis 캐싱 솔루션은 제품 순위 목록의 요구 사항을 어떻게 인식합니까? 개발 과정에서 우리는 종종 a ... 표시와 같은 순위의 요구 사항을 처리해야합니다.

Java 객체를 어레이로 안전하게 변환하는 방법은 무엇입니까?Java 객체를 어레이로 안전하게 변환하는 방법은 무엇입니까?Apr 19, 2025 pm 11:33 PM

Java 객체 및 배열의 ​​변환 : 캐스트 유형 변환의 위험과 올바른 방법에 대한 심층적 인 논의 많은 Java 초보자가 객체를 배열로 변환 할 것입니다 ...

분류를 구현하고 그룹의 일관성을 유지하기 위해 이름을 숫자로 변환하려면 어떻게합니까?분류를 구현하고 그룹의 일관성을 유지하기 위해 이름을 숫자로 변환하려면 어떻게합니까?Apr 19, 2025 pm 11:30 PM

많은 응용 프로그램 시나리오에서 정렬을 구현하기 위해 이름으로 이름을 변환하는 솔루션, 사용자는 그룹으로, 특히 하나로 분류해야 할 수도 있습니다.

전자 상거래 플랫폼 SKU 및 SPU 데이터베이스 설계 : 사용자 정의 속성과 귀속없는 제품을 모두 고려하는 방법은 무엇입니까?전자 상거래 플랫폼 SKU 및 SPU 데이터베이스 설계 : 사용자 정의 속성과 귀속없는 제품을 모두 고려하는 방법은 무엇입니까?Apr 19, 2025 pm 11:27 PM

전자 상거래 플랫폼에서 SKU 및 SPU 테이블의 디자인에 대한 자세한 설명이 기사는 전자 상거래 플랫폼에서 SKU 및 SPU의 데이터베이스 설계 문제, 특히 사용자 정의 판매를 처리하는 방법에 대해 논의 할 것입니다 ...

팀 구성원이 공유 할 수있는 아이디어에서 SpringBoot 프로젝트의 기본 실행 구성 목록을 설정하는 방법은 무엇입니까?팀 구성원이 공유 할 수있는 아이디어에서 SpringBoot 프로젝트의 기본 실행 구성 목록을 설정하는 방법은 무엇입니까?Apr 19, 2025 pm 11:24 PM

SpringBoot 프로젝트를 설정하는 방법 Intellij를 사용하여 Idea에서 기본 실행 구성 목록 ...

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

PhpStorm 맥 버전

PhpStorm 맥 버전

최신(2018.2.1) 전문 PHP 통합 개발 도구

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

WebStorm Mac 버전

WebStorm Mac 버전

유용한 JavaScript 개발 도구

맨티스BT

맨티스BT

Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.