hello world – Lwxyz https://yun.lwxyz.cn Don't Forget To Be Awesome! Fri, 16 Jun 2023 22:20:57 +0000 zh-CN hourly 1 https://wordpress.org/?v=5.1.13 rabbitmq安装 https://yun.lwxyz.cn/2018/11/09/rabbitmq%e5%ae%89%e8%a3%85/ https://yun.lwxyz.cn/2018/11/09/rabbitmq%e5%ae%89%e8%a3%85/#respond Fri, 09 Nov 2018 06:35:23 +0000 https://blog.lwxyz.org/?p=223 阅读更多]]> 转自:https://blog.csdn.net/qq_22075041/article/details/78855708

]]>
https://yun.lwxyz.cn/2018/11/09/rabbitmq%e5%ae%89%e8%a3%85/feed/ 0
基于TOTP的双向认证算法 https://yun.lwxyz.cn/2018/09/18/%e5%9f%ba%e4%ba%8etotp%e7%9a%84%e5%8f%8c%e5%90%91%e8%ae%a4%e8%af%81%e7%ae%97%e6%b3%95/ https://yun.lwxyz.cn/2018/09/18/%e5%9f%ba%e4%ba%8etotp%e7%9a%84%e5%8f%8c%e5%90%91%e8%ae%a4%e8%af%81%e7%ae%97%e6%b3%95/#respond Tue, 18 Sep 2018 06:02:12 +0000 https://blog.lwxyz.org/?p=217 阅读更多]]> 转自:https://www.jianshu.com/p/e1031d36888b

基于otp算法的双向认证

先举例一个应用场景吧,我们应该都用U盾,或者将军令这种生成动态密钥的工具,其实它内部就是基于OTP算法来实现的。

谷歌也有开源这样的开源项目,本文就是博主通读了谷歌开源项目源码来实现的,项目地址:

Google Android端项目源码

Google 后台项目源码

算法概要

TOTP(基于时间的一次性密码算法)是支持时间作为动态因素基于HMAC一次性密码算法的扩展。

本算法是一个对称算法,也就是说,后台和移动端采用同样的密钥,同时这个算法是依赖于当前的系统时间的,所以可以用于动态验证。

TOTP = HMAC-SHA-1(K, (T – T0) / X)

  • K 共享密钥
  • T 当前时间戳
  • T0 开始的时间戳
  • X 时间步长

多唠叨几句:我们整体算法采用处理密钥的方式,是要将密钥转换成byte数组之后进行操作的,还有就是谷歌的这套双向认证算法中严格的采用了Base32字符串的方式,Base32中只有A-Z和2-7这些字符。

代码效果:

2017/08/09 20:39:56
983452
2017/08/09 20:39:57
983452
2017/08/09 20:39:58
983452
2017/08/09 20:39:59
983452
2017/08/09 20:40:00
977560
2017/08/09 20:40:01
977560
2017/08/09 20:40:02
977560
2017/08/09 20:40:03
977560
2017/08/09 20:40:04
977560

应用在app中的效果图:

应用在app中的效果图:

核心代码算法:

算法GitHub地址:https://github.com/linsir6/TOTP

算法的核心类:

/**
 * Created by linSir
 * date at 2017/8/8.
 * describe: 算法的核心类
 */

public class PasscodeGenerator {
    private static final int MAX_PASSCODE_LENGTH = 9;

    private static final int[] DIGITS_POWER
            // 0 1  2   3    4     5      6       7        8         9
            = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

    private final Signer signer;
    private final int codeLength;

    interface Signer {
        byte[] sign(byte[] data) throws GeneralSecurityException;
    }

    public PasscodeGenerator(Signer signer, int passCodeLength) {
        if ((passCodeLength < 0) || (passCodeLength > MAX_PASSCODE_LENGTH)) {
            throw new IllegalArgumentException(
                    "PassCodeLength must be between 1 and " + MAX_PASSCODE_LENGTH
                            + " digits.");
        }
        this.signer = signer;
        this.codeLength = passCodeLength;
    }

    private String padOutput(int value) {
        String result = Integer.toString(value);
        for (int i = result.length(); i < codeLength; i++) {
            result = "0" + result;
        }
        return result;
    }

    public String generateResponseCode(long state)
            throws GeneralSecurityException {
        byte[] value = ByteBuffer.allocate(8).putLong(state).array();
        return generateResponseCode(value);
    }

    public String generateResponseCode(byte[] challenge)
            throws GeneralSecurityException {
        byte[] hash = signer.sign(challenge);

        int offset = hash[hash.length - 1] & 0xF;
        int truncatedHash = hashToInt(hash, offset) & 0x7FFFFFFF;
        int pinValue = truncatedHash % DIGITS_POWER[codeLength];
        return padOutput(pinValue);
    }

    private int hashToInt(byte[] bytes, int start) {
        DataInput input = new DataInputStream(
                new ByteArrayInputStream(bytes, start, bytes.length - start));
        int val;
        try {
            val = input.readInt();
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
        return val;
    }
}

]]>
https://yun.lwxyz.cn/2018/09/18/%e5%9f%ba%e4%ba%8etotp%e7%9a%84%e5%8f%8c%e5%90%91%e8%ae%a4%e8%af%81%e7%ae%97%e6%b3%95/feed/ 0
maven中scope详解 https://yun.lwxyz.cn/2018/09/06/maven%e4%b8%adscope%e8%af%a6%e8%a7%a3/ https://yun.lwxyz.cn/2018/09/06/maven%e4%b8%adscope%e8%af%a6%e8%a7%a3/#respond Thu, 06 Sep 2018 03:21:20 +0000 https://blog.lwxyz.org/?p=212 阅读更多]]> 参考:https://blog.csdn.net/cd18333612683/article/details/66478332

scope的分类

compile、test、runtime、provided、system、import (2.0.9之后新增)

1.compile:默认值 他表示被依赖项目需要参与当前项目的编译,还有后续的测试,运行周期也参与其中,是一个比较强的依赖。打包的时候通常需要包含进去

2.test:依赖项目仅仅参与测试相关的工作,包括测试代码的编译和执行,不会被打包,例如:junit

3.runtime:表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过了编译而已。例如JDBC驱动,适用运行和测试阶段

4.provided:打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。相当于compile,但是打包阶段做了exclude操作

5.system:从参与度来说,和provided相同,不过被依赖项不会从maven仓库下载,而是从本地文件系统拿。需要添加systemPath的属性来定义路径

6.import:从它只使用在<dependencyManagement>中,表示从其它的pom中导入dependency的配置

]]>
https://yun.lwxyz.cn/2018/09/06/maven%e4%b8%adscope%e8%af%a6%e8%a7%a3/feed/ 0
npm安装成功,却找不到命令 https://yun.lwxyz.cn/2018/09/05/npm%e5%ae%89%e8%a3%85%e6%88%90%e5%8a%9f%ef%bc%8c%e5%8d%b4%e6%89%be%e4%b8%8d%e5%88%b0%e5%91%bd%e4%bb%a4/ https://yun.lwxyz.cn/2018/09/05/npm%e5%ae%89%e8%a3%85%e6%88%90%e5%8a%9f%ef%bc%8c%e5%8d%b4%e6%89%be%e4%b8%8d%e5%88%b0%e5%91%bd%e4%bb%a4/#respond Wed, 05 Sep 2018 13:24:47 +0000 https://blog.lwxyz.org/?p=207 阅读更多]]>

设置一个环境变量

echo -e “export PATH=$(npm prefix -g)/bin:$PATH >> ~/.bashrc && source ~/.bashrc

]]>
https://yun.lwxyz.cn/2018/09/05/npm%e5%ae%89%e8%a3%85%e6%88%90%e5%8a%9f%ef%bc%8c%e5%8d%b4%e6%89%be%e4%b8%8d%e5%88%b0%e5%91%bd%e4%bb%a4/feed/ 0
关于Vue实例的生命周期created和mounted的区别 https://yun.lwxyz.cn/2018/09/05/%e5%85%b3%e4%ba%8evue%e5%ae%9e%e4%be%8b%e7%9a%84%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9fcreated%e5%92%8cmounted%e7%9a%84%e5%8c%ba%e5%88%ab/ https://yun.lwxyz.cn/2018/09/05/%e5%85%b3%e4%ba%8evue%e5%ae%9e%e4%be%8b%e7%9a%84%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9fcreated%e5%92%8cmounted%e7%9a%84%e5%8c%ba%e5%88%ab/#respond Wed, 05 Sep 2018 02:15:33 +0000 https://blog.lwxyz.org/?p=202 阅读更多]]> 转自:https://segmentfault.com/a/1190000008570622

生命周期先上图

什么是生命周期

Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。

在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册js方法,可以让我们用自己注册的js方法控制整个大局,在这些事件响应方法中的this直接指向的是vue的实例。

再上图,对生命周期图的标注

特别值得注意的是created钩子函数和mounted钩子函数的区别

每个钩子函数都在啥时间触发

beforeCreate

在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。

created

实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

beforeMount

在挂载开始之前被调用:相关的 render 函数首次被调用。

mounted

el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。

beforeUpdate

数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。

updated

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。

该钩子在服务器端渲染期间不被调用。

beforeDestroy

实例销毁之前调用。在这一步,实例仍然完全可用。

destroyed

Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。

]]>
https://yun.lwxyz.cn/2018/09/05/%e5%85%b3%e4%ba%8evue%e5%ae%9e%e4%be%8b%e7%9a%84%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9fcreated%e5%92%8cmounted%e7%9a%84%e5%8c%ba%e5%88%ab/feed/ 0
redis安装 https://yun.lwxyz.cn/2018/09/04/redis%e5%ae%89%e8%a3%85/ https://yun.lwxyz.cn/2018/09/04/redis%e5%ae%89%e8%a3%85/#respond Tue, 04 Sep 2018 15:17:34 +0000 https://blog.lwxyz.org/?p=199 转自:  http://www.cnblogs.com/qhbm/p/9448198.html

]]>
https://yun.lwxyz.cn/2018/09/04/redis%e5%ae%89%e8%a3%85/feed/ 0
rpm安装mysql8.0.12 https://yun.lwxyz.cn/2018/09/04/rpm%e5%ae%89%e8%a3%85mysql8-0-12/ https://yun.lwxyz.cn/2018/09/04/rpm%e5%ae%89%e8%a3%85mysql8-0-12/#respond Tue, 04 Sep 2018 14:22:02 +0000 https://blog.lwxyz.org/?p=192 阅读更多]]> 1.删除所有的mysql、mariadb

yum remove mariadb-libs

2.安装必要依赖

wget http://mirror.centos.org/centos-7/7.5.1804/os/x86_64/Packages/libaio-0.3.109-13.el7.x86_64.rpm

rpm -ivh libaio-0.3.109-13.el7.x86_64.rpm

yum -y install numactl

yum install -y net-tools

3.安装mysql

rpm -ivh mysql-community-common-8.0.12-1.el7.x86_64.rpm

rpm -ivh mysql-community-libs-8.0.12-1.el7.x86_64.rpm

rpm -ivh mysql-community-client-8.0.12-1.el7.x86_64.rpm

rpm -ivh mysql-community-server-8.0.12-1.el7.x86_64.rpm

4.初始化mysql

mysqld –initialize –user=mysql

5.获取mysql初始化密码

cat /var/log/mysqld.log

6.启动mysql服务

 

systemctl start mysqld.service

或者

service mysqld start

 

或者使用mysql启动脚本

/etc/inint.d/mysqld start

7.登陆mysql修改用户密码

8.0之前使用

alter user ‘root’@’%’ identified by ‘123456’;

 

8.0之后使用

ALTER USER ‘root’@’%’ IDENTIFIED WITH mysql_native_password BY ‘YUwei.12345’;

8.防火墙放行3306端口

/sbin/iptables -I INPUT -p tcp –dport 3306 -j ACCEPT

9.创建新用户

CREATE USER `shs`@`%` IDENTIFIED BY ‘cJcow9sLKurO’;

10.授予权限

GRANT ALL PRIVILEGES ON *.* TO `shs`@`%`;

]]>
https://yun.lwxyz.cn/2018/09/04/rpm%e5%ae%89%e8%a3%85mysql8-0-12/feed/ 0
Centos下部署firekylin博客系统 https://yun.lwxyz.cn/2018/08/13/centos%e4%b8%8b%e9%83%a8%e7%bd%b2firekylin%e5%8d%9a%e5%ae%a2%e7%b3%bb%e7%bb%9f/ https://yun.lwxyz.cn/2018/08/13/centos%e4%b8%8b%e9%83%a8%e7%bd%b2firekylin%e5%8d%9a%e5%ae%a2%e7%b3%bb%e7%bb%9f/#respond Mon, 13 Aug 2018 14:51:44 +0000 https://blog.lwxyz.org/?p=182 阅读更多]]> 转自:https://blog.csdn.net/llhwin2010/article/details/78694802

]]>
https://yun.lwxyz.cn/2018/08/13/centos%e4%b8%8b%e9%83%a8%e7%bd%b2firekylin%e5%8d%9a%e5%ae%a2%e7%b3%bb%e7%bb%9f/feed/ 0
mysql 安装后设置 https://yun.lwxyz.cn/2018/08/13/mysql-%e5%ae%89%e8%a3%85%e5%90%8e%e8%ae%be%e7%bd%ae/ https://yun.lwxyz.cn/2018/08/13/mysql-%e5%ae%89%e8%a3%85%e5%90%8e%e8%ae%be%e7%bd%ae/#respond Mon, 13 Aug 2018 14:35:27 +0000 https://blog.lwxyz.org/?p=180 阅读更多]]>

1.修改mysql密码

i.mysql8
ALTER USER ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘YUwei.12345’;

ii.mysql7

alter user ‘root’@’localhost’ identified by ‘123456’;
2.设置root账号远程访问
update user set host = ‘%’ where user = ‘root’;
3.设置防火墙放行3306端口
/sbin/iptables -I INPUT -p tcp –dport 3306 -j ACCEPT

]]>
https://yun.lwxyz.cn/2018/08/13/mysql-%e5%ae%89%e8%a3%85%e5%90%8e%e8%ae%be%e7%bd%ae/feed/ 0
各种学习网站 https://yun.lwxyz.cn/2018/08/10/%e5%b9%b6%e5%8f%91%e7%bc%96%e7%a8%8b%e7%bd%91/ https://yun.lwxyz.cn/2018/08/10/%e5%b9%b6%e5%8f%91%e7%bc%96%e7%a8%8b%e7%bd%91/#respond Fri, 10 Aug 2018 01:34:38 +0000 https://blog.lwxyz.org/?p=176 阅读更多]]> 1.并发编程网

http://ifeve.com/

 

2.spring学习网站

http://www.spring4all.com/

]]>
https://yun.lwxyz.cn/2018/08/10/%e5%b9%b6%e5%8f%91%e7%bc%96%e7%a8%8b%e7%bd%91/feed/ 0