虽然全站已经 HTTPS 了,但是因为某些原因,不允许明文传输用户名密码,也就意味着需要在客户端做一层加密,然后在服务端解密。 了解下来只能选择 RSA 的方式了。
准备工作,首先需要生成秘钥:
# 生成 1024 位的 RSA 私钥
openssl genrsa -out key.pem 1024
# 导出相对应的公钥
openssl rsa -in key.pem -pubout -out pubkey.pem
# 复制出来备用
cat key.pem
cat pubkey.pem
打开 wp-login.php 文件,将以下代码补充到 loginform 后面,我是放在 $login_script
后面。
主要是为了捕获登录表单,在 submit 的时候,把 user_login 和 user_pass 各自加密后再发送到服务端。
<script src="https://cdn.jsdelivr.net/npm/jsencrypt@3.2.1/bin/jsencrypt.min.js" type="text/javascript"></script>
<script type="text/javascript">
(function($) {
var user_pass = $("#user_pass");
var user_login = $("#user_login");
var loginform = $("#loginform");
var sign = '公钥';
var encrypt = new JSEncrypt();
encrypt.setPublicKey(sign);
// encrypt loginform user_pass
loginform.submit(function(e) {
e.preventDefault();
// get user_login & user_pass value
var user_login_val = user_login.val();
var user_pass_val = user_pass.val();
// encrypt user_login & user_pass
var user_login_encrypted = encrypt.encrypt(user_login_val);
var user_pass_encrypted = encrypt.encrypt(domprops);
// set user_login & user_pass
user_login.val(user_login_encrypted);
user_pass.val(user_pass_encrypted);
loginform.unbind('submit').submit();
});
})(jQuery);
</script>
对应的,服务端拿到加密的 user_login 和 user_pass,需要解密后才能继续走下面的流程。
WordPress 的登录方式在放在 wp-includes/pluggable.php
文件里面。
打开 pluggable.php
找到 wp_authenticate 方法,并修改成类似下面的方式:
function wp_authenticate( $username, $password ) {
$username = sanitize_user( $username );
$password = trim( $password );
// -- 开始增加代码 --
$private_key = "私钥";
$decrypt_data_user = '';
$decrypt_data_pass = '';
// 判断私钥是否是可用的,可用返回资源id
$pi_key = openssl_pkey_get_private($private_key);
// 解密数据, 这里要进行 base64 解码是因为浏览器会默认帮你的数据进行编码
// 用户名
openssl_private_decrypt(base64_decode($username), $decrypt_data_user, $private_key);
$username = $decrypt_data_user;
// 密码
openssl_private_decrypt(base64_decode($password), $decrypt_data_pass, $private_key);
$password = $decrypt_data_pass;
// -- 增加代码结束 --
// 后续原有代码
// ...
}
这样就能完成一次完成的加密解密了,推荐公钥私钥不要硬编码,最好通过配置的形式读进来(题外话,安全建议)。
–EOF–