前言
现在市面上密码加密方式很多,常用的加密方式比如AES,RSA。还有一些通过散列算法生成摘要的方式,比如md5、sha1等等,我们最常用的是md5,但是md5是不可逆的,而且跟用户的操作习惯有很大的关联,如果密码过于简单很不安全,所以我们能不能用其他的加密方式来生成密文呢?
md5剖析
在用户登录时需要将密码加密,不能以明文发送。所以就涉及到加密,我们一贯的用法是使用md5,但是对于md5网上众说纷纭,说md5加密不安全,容易被暴力破解,首先MD5都不能称之为加密,它是不可逆的,所以本质它是对文件本身的一种破坏,其次它不安全的原因不出在加密原理是公开的这一点上面。不安全主要是碰撞的问题,比如说123456对应的摘要49ba59abbe56e057,它有一个对应的彩虹表然后根据这个彩虹表去反查每个字符,在经历过很多次碰撞后,得出明文,这是弱密码的情况下,很容易被暴力破解。但是在密码复杂的情况下比如@#sadsSA123,就算现在常用的md5密码库有6.7亿之多,破解它可能需要很多年,这里是可能,甚至一万年之久,所以说md5安全不安全还是跟用户的操作习惯有关系的,仅属于个人见解。这时候可能就会有人说md5始终是存在安全隐患的,这时候我要说的就是不存在不能被破解的加密。所以考虑到用户的操作习惯所以我们尽量采用rsa加密。
RSA加解密流程:
A要传给B一句话(需要保密),就由B生成一对公钥和私钥存好,公钥就好比一把锁,钥匙就是私钥。B只需要把锁给A,A把那句话锁起来,交还给B,在这过程中,即使大家都能看到公钥(锁),也是不知道那句话是啥的,然后B拿到锁好的机密,拿只有自己才有的私钥(钥匙)解开,这个差不多就是非对称加密。
市面上的登录注册加密一般都是RSA加密又叫非对称加密,前提是需要先生成一对公钥私钥,生成公钥私钥对的网址: http://web.chacuo.net/netrsakeypair。
前端代码
公钥放在文件中导出
<template>
<div class="register-main">
<div class="earth-bg"></div>
<div id="register-container">
<el-card class="box-card">
<el-form :model="ruleForm" :rules="rules" ref="registerForm">
<el-form-item>
<h2 class="sys-title">注册</h2>
</el-form-item>
<el-form-item prop="username">
<el-input
type="text"
placeholder="用户名"
v-model="ruleForm.username"
prefix-icon="iconfont iconyonghuming"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
type="password"
placeholder="密码"
v-model="ruleForm.password"
prefix-icon="iconfont iconmima"
></el-input>
</el-form-item>
<el-form-item style="text-align: center">
<el-button
type="primary"
class="register-btn"
@click.native.prevent="register()"
>{{ status.txt }}</el-button
>
<el-button class="reset-btn">重置</el-button>
</el-form-item>
<p class="to-login">
<span>已有账号,请去</span>
<a href="javascript:;" class="login" @click="toLogin()">登陆</a>
</p>
</el-form>
</el-card>
</div>
</div>
</template>
<script>
import { ref, reactive, toRefs } from "vue";
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import JSEncrypt from "jsencrypt/bin/jsencrypt";
import { publicKey } from "../../config/key";
import { registerAjax } from "../../http/api";
import { useStore } from "vuex";
export default {
setup() {
const registerForm = ref(null);
const router = useRouter();
const store = useStore();
const toLogin = () => {
router.push("/login");
};
const state = reactive({
ruleForm: {
username: "",
password: "",
},
status: {
txt: "提交",
},
rules: {
username: [
{ required: true, message: "请输入用户名!", trigger: "blur" },
{ min: 3, max: 15, message: "长度在3-15之间", trigger: "blur" },
],
password: [
{ required: true, message: "请输入密码!", trigger: "blur" },
{ min: 3, max: 15, message: "长度在3-15之间", trigger: "blur" },
],
},
});
const register = () => {
let encryptor = new JSEncrypt(); // 新建JSEncrypt对象
registerForm.value.validate(async (valid) => {
if (valid) {
// let publicKey = store.state.user.pubkey;
// console.log("后台公钥" + publicKey)
encryptor.setPublicKey(publicKey); // 设置公钥
let rsaPassWord = encryptor.encrypt(state.ruleForm.password); // 对需要加密的数据进行加密
let registerParam = {
username: state.ruleForm.username,
password: rsaPassWord,
};
state.status.txt = "提交中...";
let registerResult = await registerAjax(registerParam);
setTimeout(() => {
ElMessage.success({
message: registerResult.msg,
type: "success",
});
state.status.txt = "提交";
registerForm.value.resetFields();
}, 1000);
} else {
ElMessage.error("输入有问题,请检查!");
}
});
};
return {
toLogin,
registerForm,
...toRefs(state),
register,
};
},
};
</script>
<style lang="less" scoped>
</style>
后端代码
var NodeRSA = require("node-rsa");
const _priKey =
`
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAPBtHeIXsISdaY23
InqEp+7fHWYBYr2gqgrFQ0pWD6ScD8bWX5QxfBbDXHGNf+e1ffsByR75rlV1FycG
XMpNF4qyfvcT0ohfKIx+AEapY0gzlEEuaqmWXV+2yQronKbEfsHxyb/yq37sXkQt
9NlTG8fhteU8GYVEDo83UcbvO8MhAgMBAAECgYBixqGpWsw1n6pXA69RoKCR3e5p
ExarC4/wvtyHdNYWbdt5eGdqLe5qN7cKG/U5j/IDJtenNzMtft6VNOL4ZjXOBNcL
+1vP3y6OK8vgYYGjF7f/6OhKtRfpn4rTvEObWb0cWBQRQ1LcqCDxGnrT30spT3tl
P4jznC0fDFv+BDn0BQJBAP+9slVkwWEEB4GE3SATl/r3iE5XF9iAUus1OfQmXH8u
TlJrsGOOd/YI6quQQzunieFtF04/pDy83YpW3NqrttMCQQDwq3MZub5BSvdOSZu0
tIOMt9ebDoY25J73GaprJ8SiUOqwJRryHi2GvjqfqxpdQE3pRMGxb6B/T6+NBhK0
mY27AkBmigPH82cJ5BiyWLhklRaZ3Mf9STRZbVJR1nyPJRZvM/zZVS5bLJNyxa55
7ZTXhVxmU1xF1oSeicd2IU/aKYFbAkEAsGXJ2Eo2855hw0TaVkmUvfgllGXB48wP
46cxLJcaXaoXSgH4TQvnbIJTb6I2kbDHKjmWClp59bZPQnr4DN0bbwJAbtJ1JwpV
8kSV1VDtiC7FooRi45dzKvqg28Co+z+x5SBh53xuxFxPPKSjk9IWkhS4CamdRMMY
B7JJ2M5uoLJbyg==
-----END PRIVATE KEY-----
`
const privateKey = new NodeRSA(_priKey);
privateKey.setOptions({encryptionScheme: 'pkcs1'});
var dePassword = privateKey.decrypt(password, 'utf8');//解密 用在登录接口