xuan's blog


  • 首页

  • 关于

  • 标签

  • 分类

常用的加密算法分析

发表于 2017-11-27 | 分类于 Blockchain

对称加密

常见的对称加密算法有DES,3DES和AES。他们使用的都是Feistel结构。

DES即Data Encryption Standard,由于其使用了过短的key(有效为只有56bits,可被暴力破解),出于安全原因已经不推荐使用。

3DES即同样使用DES的实现,但是使用不同key进行3次链式加密,因此相对于DES更为安全。然而由于DES本身是基于硬件的设计,在软件上的效率太低,3DES采用同样的实现则效率更低。

AES即新一代的Advanced Encryption Standard。AES可以使用128,192或256bits的不同key,目前认为128bits已经足够安全。此外相较3DES或者其他参与NIST竞争的参赛算法性能更好。

非对称加密

常见的非对称加密算法有RSA,DSA和ECC。

RSA是利用了两个质数相乘比较容易,但是对一个大整数进行因数分解非常困难的特点来保证安全性。具体原理可以参考这篇博文。越长的密钥则越安全,2009年公开记录的被破解的密钥长度为768位,因此建议使用1024位甚至2048位的密钥长度。

ECC椭圆曲线加密也是建立在另外一个数学难题上:在射影坐标系上,给定椭圆曲线上的一个点G,给定一个整数k,进行乘法计算求K=kG比较容易;反过来,给定椭圆曲线上的两个点K和G,求k使得K=kG则非常困难。具体原理可以参考这篇博文

RSA在使用较长的密钥长度比如1024或2058位时,加解密的速度大大降低。ECC则具有每比特最高的安全度,其210位的密钥长度安全性相当于2048位的RSA。此外,在CPU和内存消耗方便ECC也比较有优势。

在对大量数据进行处理时,非对称加密相较对称加密而言,效率非常低下;另外非对称加密算法对加密内容的长度有限制,不能超过公钥的长度。因此常用的做法是结合两者一起使用。先使用对称加密如AES对明文进行加密,而后采用非对称加密如ECC对AES的密钥进行加密,这样可以在安全和性能上达到较好的效果

摘要算法

也称HASH算法,从明文生成固定长度的散列值,同时保证不同的输入得到唯一的输出(几率非常小,可参考[哈希碰撞])。
常用的摘要算法有MD5和SHA。
MD5算法和SHA-1算法已经被证明不再安全,不推荐使用。目前NIST建议使用的为SHA-256

同态加密

同态加密是指对密文进行处理得到的结果与对明文进行处理后再加密得到的结果相同。

同态性包括加法同态,乘法同态,减法同态与除法同态。

同时满足加法同态和乘法同态则成为全同态,同时满足四种则成为算数同态。

第一个全同态算法在2009年被Craig Gentry证明,但目前由于需要消耗大量的计算时间,尚且达不到实际应用的水平。

零知识证明

数字证书

数字证书是由可信任的CA机构(Certificate Authority)颁发的,一般包含服务器的公钥,名称以及CA的数字签名。CA为使用非对称加密的服务器发放数字证书,以证明该证书中的公钥匙合法有效的,通常用来防止中间人攻击。

实际应用

HTTPS

具体原理可参考这篇博文

为了保证来自服务器的公钥不被篡改,利用数字证书来保证其有效性。
在实际传输过程中,若使用非对称加密则效率不够高效;因此在握手阶段会产生一个“对话密钥”(session key)用于信息的对称加密,而服务器公钥则用来加密对话密钥本身。

在HTTPS的TLS握手阶段,使用了非对称加密来保证信息传输的安全,具体步骤如下:

  1. 客户端发起请求,并提供如下信息:
    • 客户端支持的协议版本,如TLS 1.2
    • 客户端支持的加密算法
    • 客户端生成的随机数r1
  2. 服务器收到请求,并返回如下信息:
    • 确认使用的协议版本
    • 确认使用的加密算法
    • 服务器端生成的随机数r2
    • 服务器证书(包含了公钥)
  3. 客户端收到服务器回应,首先验证服务器证书是否有效,然后继续发送以下信息:
    • 客户端生成的随机数r3,并用服务器公钥进行加密(之前的随机数都是明文传输)
    • 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
    • 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验
  4. 服务器收到请求,则返回:
    • 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
    • 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验
  5. 至此,握手阶段结束,客户端与服务器端同时拥有三个随机数r1,r2,r3。根据握手阶段商定好的加密算法来生成后续对话的对话密钥,用来加密具体的传输内容

目前大部分网站使用的的非对称加密算法为2048位的RSA,ECC暂时还没大规模普及,但很多CA已经提供ECDSA证书。
具体的传输内容是通过session key来进行加密的,目前最广泛使用的是AES算法。

SSH

SSH同样使用了非对称加密。
用户通过把自己的公钥存储到远程主机上,在登录时,远程主机发送一个随机数,用户用私钥加密并传给远程主机,如果远程主机用公钥可以解密并匹配上就可以登录成功

bitcoin

比特币中的非对称算法采用的是secp256k1 ECDSA。其中私钥是使用SHA-256生成的32字节的随机数。通过私钥得到公钥后,经过双哈希(SHA256, RIPPLE160)和BASE58CHECK编码生成地址,即可进行交易。

常用共识算法

发表于 2017-11-23 | 分类于 Blockchain

Proof of Work

给予一个随机数,在其前面补齐N位0,然后首个求出一个解使得hash之后等于这个值的矿工将获得这个新增区块的记账权,同时给予该矿工一定的奖励。

Proof of Stake

获得下一个区块记账权的概率随着拥有的代币的数量和时间增长而增长,同时根据持有的代币来返还利息。

Delegated Proof of Stake

通过投票产生代表,获得投票数前100位的代表按照既定顺序轮流产生区块,且每个代表的投票权都是相等的;

Pratical Byzentine Fault Torerence

假设f为拜占庭错误节点的个数,那么最少节点为2f + 1
一个共识的过程具体如下:

  1. 客户端向leader发送一个请求,leader负责把该请求通过一次pre-prepare请求广播到所有的节点上,并附上本次请求的序列号n和当前的视图v;
  2. 所有节点收到 2f + 1个pre-prepare请求并验证无误,则向所有节点广播prepare请求;
  3. 所有节点收到 2f + 1个prepare请求并验证无误,则向所有节点广播commit请求;
  4. 所有节点收到 2f + 1 个commit请求并验证无误,则执行客户端发送过来的请求,并向客户端返回执行结果;
  5. 客户端收到 2f + 1个执行结果时,则表示该请求执行成功

Paxos

(适用于非拜占庭模型,即可信环境)
参考Paxos Made Simple
prepare 阶段

  • proposer发出一个带有序号为n的proposal的prepare请求;
  • acceptor收到该prepare请求,若已响应过序号大于n的prepare请求,则拒绝;若没有则响应该prepare请求并承诺不再接受其他序号小于n的prepare请求,且当曾经响应过序号小于n的prepare请求(值为v),顺带返回序号最大的v做为本次的共识value;

accept 阶段

  • proposer收到acceptor对其prepare请求的响应,选其返回的value做为共识的value(若没有则任选);向acceptor发出accepte请求,带上其序列号n和值v
  • acceptor收到一个序号为n的accept请求,若没有收到其他prepare请求序号大于n,则接受该accept请求。

Raft

演示
论文
raft算法可以分成三个部分来理解:

  • Leader选举
    每个节点分别有三种状态:leader, candidate 和 follower。当集群中不存在leader时,follower会将自己变更成leader进行一轮选举,选举成功的则为leader。
  • 日志复制
    leader收到客户端传来的指令时,负责把该指令复制到所有follower节点上
  • Safety
  1. 被选举权限制
    只有与集群中大部分的节点同样’up-to-date’的candidate,才能获得选票;此外还保证了日志只会单向的从leader到follower,简化了复杂度;
  2. 拒绝提交遗留entry
    一个新的leader不会因为大部分节点包含了某个来自于上个term的entry而对其进行提交;

raft的特性:

  • 在一个任期(term)内最多只能有一个leader;
  • leader不会覆盖或者删除在其log中的entries;只会新增;
  • 在两个节点的log中,如果存在一个entry,他们的序号(index)和任期都相等,那么在这个index之前的所有log都是相同的;
  • 如果一个entry在term n 内已经被提交(committed),那么n+1 term的leader都会有该entry;
  • 如果一个节点在index i 已经把entry提交,那么不会存在另外一个节点在同样的index i 提交了不同的entry

Docker 1.13 新特性top10

发表于 2017-01-13 | 分类于 其他

原文:https://blog.nimbleci.com/2016/11/17/whats-coming-in-docker-1-13/
翻译:laiyuXuan
学习docker过程中看到这篇文章,介绍了docker1.13中的新功能,觉得不错就翻译了过来,若有错漏欢迎拍砖。

Docker 1.13 马上就要发布了,下面是最值得期待的新功能top 10:

  • Docker stacks 结束实验阶段,正式发布
    从docker-compose文件部署docker stacks
  • 密钥管理
  • 新加入针对swarm集群的 ‘-attachable’ 参数
  • 插件功能结束实验阶段,正式发布
  • 通过docker daemon -experimental来开启处于实验阶段的功能
  • 在service update中 加入 -force参数
  • 在docker service create中加入-port参数
  • 在创建镜像时缓存层(layers)
  • 其他改进

Docker stacks 结束实验阶段,正式发布

如果你有关注docker的最新发展,那么你应该知道”dab”(distributed application bundle)文件。他可以从一个docker-compose.yml文件生成,用来定义一个docker swarm集群的一个或者多个services。对于自动化部署来说这是非常便利的,因为不再需要通过docker service create和docker service update命令来更新集群中service的定义。

延伸阅读Docker Stacks and Why We Need Them

随着docker 1.13的发布,docker stacks 现已结束实验阶段,所有人都可以用上这个功能。

从docker-compose文件部署docker stacks

以往若需要使用docker stack deploy命令,我们必须先生成一个.dab文件。在docker 1.13中,不再需要把docker-compose.yml文件转换成一个.dab文件,直接使用docker-compose.yml即可。下面是具体用法:

1
2
3
$ docker stack deploy \
--compose-file ./docker-compose.yml \
mystack

这样就可以在swarm集群中通过docker-compose.yml中的定义创建/更新services。

密钥管理

密钥管理让我们可以把密钥保存到swarm集群中,并给相应的services分配使用特定密钥的权限。

四个新加入的指令:

  • docker secret create
  • docker secret insepect
  • docker secret ls
  • docker secret rm

举个栗子,首先把一个密钥加入到swarm集群中:

1
$ echo "my-sensitive-password" | docker secret create login-password

然后启动一个带密钥的service

1
2
3
4
$ docker service create \
--name myapp \
--secret login-password \
ubuntu

这个密钥会被挂载到容器内的/run/secrets/login-password路径下

1
2
$ docker exec -it myapp cat /run/secrets/login-password
my-sensitive-password

现在我们可以使用这个功能来给运行中的services提供密钥,但是仅限docker service模式下。通过docker run来启动的容器暂时不支持该功能,不过已经在开发中了。同样在开发中的还有在创建时加入密钥的功能。

更多详情可以查看添加了这个功能的PR

新加入针对swarm集群的 ‘-attachable’ 参数

新加入到docker network create中的–attachable参数可以把通过docker run启动的单个容器附属到swarm集群的网络中,从而与集群中的services进行通信。在以往这是没办法做到的,这对于需要和swarm集群中的services进行通信的单一任务来说非常便利,比如备份、手动debug。

下面是具体的用法:

1
2
3
4
$ docker network create \
--driver overlay \
--attachable \
my-attachable-network

接下来可以以下使用docker run指令连接到这个网络:

1
2
3
$ docker run --rm -it \
--net my-attachable-network \
ping google.com

引入这个功能的PR可以参考这里

插件功能结束实验阶段,正式发布

Docker的插件功能之前一直处于实验阶段,在docker 1.13 版本中终于结束实验阶段,所有用户都可以使用这个功能了。

插件功能使得其他应用可以嵌入docker,增强docker的功能。当当前存在的插件如:Flocker, Weave

这里可以找到更多的插件。

通过docker daemon -experimental来开启处于实验阶段的功能

现在稳定的docker版本中会同时包含了尚处于实验阶段的功能。以往若要使用这些功能需要另外下载一个特定的版本,现在我们只需要在启动docker daemon的时候加上–experimental参数即可。

引入这个功能的PR可以参考这里

在service update中 加入-force参数

如果你在非开发环境使用 docker 1.12 版本的swarm 集群,可能会有一些问题,比如当有一个新的节点加入到集群中,是没有办法重新分配swarm集群中的services的。

新加入的--force参数会强制重新拉取镜像以及重启容器。只要设置了--update-parallelism 1和--update-deplay 5s,那么每个容器会逐个重启,并且每个容器之间会有5s的间隔,保证无缝更新(Rolling updates)。

Note:以往使用docker service update --image myimage:latest命令时会有一个bug,无法拉取到最新的tag的镜像。这个bug已经被修复了,所以只要运行service update命令即可让镜像更新到最新的版本(无需加上--force参数)

引入这个功能的PR可以参考这里

在docker service create中加入-port参数

在docker service create中新加入的--port参数是用来取代--publish参数的。
旧的用法如下:

1
$ docker service create --publish 8080:80 my-service

如上所示,通过这样可以把swarm集群中每个节点里外部可以访问的8080端口映射到容器内的80端口。

--port参数遵循了“csv”格式规范(参考--mount参数)。这样使得可以在一个--port参数中进行多项设定,而不是分别使用多个参数。下面我们来看一下用--port参数进行设定的一个栗子:

1
2
3
$ docker service create \
--name my-service \
--port mode=ingress,target=80,published=8080,protocol=tcp

这种把多项设定放在一个参数内进行的语法显得更加灵活以及更加清晰。

在创建镜像时缓存层(layers)

对于时常在不同的服务器上构建镜像的情况,这是一个持续集成上重要的更新。 目前为止并没有一个比较简便的方法可以在多个服务器上共享镜像的构造层(build layers),导致每一次构建镜像时都需要把所有层都构建一遍。在近期版本的docker中,处于安全问题的考虑,一次简单的拉取是无法拉取到缓存的。因为我们无法确保我们所拉取回来的镜像就是我们所期望的那个镜像,有可能已经被篡改了,具体的issuce可以参考这里(注:在早期版本的docker中,构建镜像时会出现“using cache…”,当时docker默认会使用缓存来进行镜像的构建。在最近的版本中(1.10+),这个功能被禁用了,出于以上安全性问题的考虑。在本次更新中会加入--cache-from参数来让使用者选择是否基于缓存构建镜像。)

具体用法:

1
2
docker pull myimage:v1.0
docker build --cache-from myimage:v1.0 -t myimage:v1.1 .

引入这个功能的PR可以参考这里

其他改进

1.13版本修复了成吨的bug以及带来了大量的改进,下面是一些上文没有提及但是也较为重要的地方:

  • Dockerfiles中的MAITAINER 指令已经被弃用了,现在可以使用labels来记录maintainer。
  • 新加入了docker service logs命令来查看service中的日志(实验阶段)
  • 在docker service update中加入–rollback参数来回滚到上一个版本。
  • 新版本的docker inspect命令可以可以用来查看各种各样的东西
  • 使用docker build –squash来合并镜像层
  • 使用docker system命令来清除不再使用的容器

安装

通过以下命令可以使用最新的RC版本的Docker 1.13

1
$ curl -fsSL https://test.docker.com/ | sh

(注:或直接在Docker github官网下载)

总结

总而言之,docker 1.13 带来了大量的新功能和bugfixes。随着service update命令的完善以及stacks功能的推出,在生产环境部署swarm集群也更加简便了。

maven 笔记

发表于 2016-01-16 | 分类于 其他

生成项目骨架

1
mvn archetype:generate

自动生成符合maven规定的项目框架结构,即:

主代码在 src/main/java目录下;
测试代码在src/main/test目录下;
资源文件在src/main/resources目录下;
在根目录下的pom.xml文件

这些都是在超级pom文件内配置好的,因为每个pom文件都默认继承一个超级pom文件,故默认生成的目录都会按照这个格式。遵照这个约定的好处就是可以较少许多配置,不用手动配置各个路径。(约定优于配置理念)
超级pom的路径在 $MAVEN_HOME/lib/maven-model-builder-x.x.x.jar 中的org/apache/maven/model/pom-4.0.0.xml

依赖范围

依赖配置中scope标签各值的范围

依赖调解

  • 路径最短者优先原则
  • 第一声明者优先原则
    e.g : 存在依赖关系A operation-web->trade-service->autopart-service.1.0 和 B operation-web -> autoparts-service.2.0,此时operation-web取的应该是autoparts-service.2.0。
    1
    mvn dependency:list

以上命令可以列出所有已解析的依赖,当存在多个依赖时可用于检查是否解析到正确的依赖。

镜像

修改settings.xml中的mirror标签,可以配置相关的镜像仓库。配合镜像的一些特殊配置,可以用来搭建maven私服。
e.g:

1
2
3
4
5
6
7
8
<!--匹配所有仓库,通常用来搭建私服,构建区域网内的中央仓库-->
<mirrorOf>*</mirrorOf>
<!--匹配不在本机上的仓库-->
<mirrorOf>external:*</mirrorOf>
<!--匹配repo1和repo2-->
<mirrorOf>repo1,repo2</mirrorOf>
<!--匹配所有仓库,除了repo1-->
<mirrorOf>*, !repo1</mirrorOf>

生命周期

  • clean生命周期:pre-clean, clean, post-clean
  • default生命周期:validate, initialize, … complie, … test-compile, … test, … install, deploy(部分阶段被省略)
  • site生命周期:pre-site, site, post-site, site-deploy

绑定插件与生命周期

通常生命周期的每个阶段都会与一个插件的目标进行,e.g: default-clean阶段 默认与maven-complier-plugin的complie进行绑定。没有绑定目标的阶段将不会有实际性的操作。常见的生命周期,maven都会默认绑定了插件。此外,还可以自定义绑定。
e.g:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>attah-source</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>

裁剪反应堆

反应堆指在一个多模块的maven项目中,所有模块组成的构建结构。

可以通过以下命令构建指定的模块:

  • -am --also-make 构建所列模块和依赖模块
  • -amd --also-make-dependents 同时构建依赖于构建模块的模块
  • - pl --projects 构建指定模块,多个模块用逗号隔开
  • - rf - resume-from 从指定模块恢复反应堆
laiyuXuan

laiyuXuan

4 日志
2 分类
6 标签
© 2017 laiyuXuan
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.3