导航:首页 > 源码编译 > linuxhash算法

linuxhash算法

发布时间:2025-04-13 02:13:38

1. 密码学系列之:bcrypt加密算法详解

简介

今天要给大家介绍的一种加密算法叫做bcrypt,bcrypt是由NielsProvos和DavidMazières设计的密码哈希函数,他是基于Blowfish密码而来的,并于1999年在USENIX上提出。

除了加盐来抵御rainbowtable攻击之外,bcrypt的一个非常重要的特征就是自适应性,可以保证加密的速度在一个特定的范围内,即使计算机的运算能力非常高,可以通过增加迭代次数的方式,使得加密速度变慢,从而可以抵御暴力搜索攻击。

bcrypt函数是OpenBSD和其他系统包括一些Linux发行版(如SUSELinux)的默认密码哈希算法。

bcrypt的工作原理

我们先回顾一下Blowfish的加密原理。blowfish首先需要生成用于加密使用的K数组和S-box,blowfish在生成最终的K数组和S-box需要耗费一定的时间,每个新的密钥都需要进行大概4KB文本的预处理,和其他分组密码算法相比,这个会很慢。但是一旦生成完毕,或者说密钥不变的情况下,blowfish还是很快速的一种分组加密方法。

那么慢有没有好处呢?

当然有,因为对于一个正常应用来说,是不会经常更换密钥的。所以预处理只会生成一次。在后面使用的时候就会很快了。

而对于恶意攻击者来说,每次尝试新的密钥都需要进行漫长的预处理,所以对攻击者来说要破解blowfish算法是非常不划算的。所以blowfish是可以抵御字典攻击的。

Provos和Mazières利用了这一点,并将其进一步发展。他们为Blowfish开发了一种新的密钥设置算法,将由此产生的密码称为"Eksblowfish"("expensivekeyscheleBlowfish")。这是对Blowfish的改进算法,在bcrypt的初始密钥设置中,salt和password都被用来设置子密钥。然后经过一轮轮的标准Blowfish算法,通过交替使用salt和password作为key,每一轮都依赖上一轮子密钥的状态。虽然从理论上来说,bcrypt算法的强度并不比blowfish更好,但是因为在bcrpyt中重置key的轮数是可以配置的,所以可以通过增加轮数来更好的抵御暴力攻击。

bcrypt算法实现

简单点说bcrypt算法就是对字符串OrpheanBeholderScryDoubt进行64次blowfish加密得到的结果。有朋友会问了,bcrypt不是用来对密码进行加密的吗?怎么加密的是一个字符串?

别急,bcrpyt是将密码作为对该字符串加密的因子,同样也得到了加密的效果。我们看下bcrypt的基本算法实现:

FunctionbcryptInput:cost:Number(4..31)log2(Iterations).e.g.12==>212=4,096iterationssalt:arrayofBytes(16bytes)randomsaltpassword:arrayofBytes(1..72bytes)UTF-8encodedpasswordOutput:hash:arrayofBytes(24bytes)////P:arrayof18subkeys(UInt32[18])//S:Foursubstitutionboxes(S-boxes),S0...S3.EachS-boxis1,024bytes(UInt32[256])P,S<-EksBlowfishSetup(cost,salt,password)//Repeatedlyencryptthetext"OrpheanBeholderScryDoubt"64timesctext<-"OrpheanBeholderScryDoubt"//24bytes==>three64-bitblocksrepeat(64)ctext<-EncryptECB(P,S,ctext)////24-(cost,salt,ctext)

上述函数bcrypt有3个输入和1个输出。

在输入部分,cost表示的是轮循的次数,这个我们可以自己指定,轮循次数多加密就慢。

salt是加密用盐,用来混淆密码使用。

password就是我们要加密的密码了。

最后的输出是加密后的结果hash。

有了3个输入,我们会调用EksBlowfishSetup函数去初始化18个subkeys和4个1K大小的S-boxes,从而达到最终的P和S。

然后使用P和S对"OrpheanBeholderScryDoubt"进行64次blowfish运算,最终得到结果。

接下来看下EksBlowfishSetup方法的算法实现:

FunctionEksBlowfishSetupInput:password:arrayofBytes(1..72bytes)UTF-8encodedpasswordsalt:arrayofBytes(16bytes)randomsaltcost:Number(4..31)log2(Iterations).e.g.12==>212=4,096iterationsOutput:P:arrayofUInt32arrayof18per-roundsubkeysS1..S4:;eachSBoxis256UInt32(i.e.1024KB)//InitializeP(Subkeys),andS(Substitutionboxes)withthehexdigitsofpiP,S<-InitialState()//,S<-ExpandKey(P,S,salt,password)//Thisisthe"Expensive"partofthe"ExpensiveKeySetup".//.repeat(2cost)P,S<-ExpandKey(P,S,0,password)P,S<-ExpandKey(P,S,0,salt)returnP,S

代码很简单,EksBlowfishSetup接收上面我们的3个参数,返回最终的包含18个子key的P和4个1k大小的Sbox。

首先初始化,得到最初的P和S。

然后调用ExpandKey,传入salt和password,生成第一轮的P和S。

然后循环2的cost方次,轮流使用password和salt作为参数去生成P和S,最后返回。

最后看一下ExpandKey的实现:

FunctionExpandKeyInput:password:arrayofBytes(1..72bytes)UTF-8encodedpasswordsalt:Byte[16]randomsaltP:..S4:UInt32[1024]Four1KBSBoxesOutput:P:arrayofUInt32Arrayof18per-roundsubkeysS1..S4:UInt32[1024]Four1KBSBoxes//<-1to18doPn<-Pnxorpassword[32(n-1)..32n-1]//treatthepasswordascyclic//Treatthe128-bitsaltastwo64-bithalves(theBlowfishblocksize).saltHalf[0]<-salt[0..63]//Lower64-bitsofsaltsaltHalf[1]<-salt[64..127]//Upper64-bitsofsalt//Initializean8-byte(64-bit)bufferwithallzeros.block<-0//MixinternalstateintoP-boxesforn<-1to9do//xor64-bitblockwitha64-bitsalthalfblock<-blockxorsaltHalf[(n-1)mod2]//[0],andsaltHalf[1]//<-Encrypt(P,S,block)P2n<-block[0..31]//lower32-bitsofblockP2n+1<-block[32..63]//upper32-bitsblock//-boxesofstatefori<-1to4doforn<-0to127doblock<-Encrypt(state,blockxorsalt[64(n-1)..64n-1])//asaboveSi[2n]<-block[0..31]//lower32-bitsSi[2n+1]<-block[32..63]//upper32-bitsreturnstate

ExpandKey主要用来生成P和S,算法的生成比较复杂,大家感兴趣的可以详细研究一下。

bcrypthash的结构

我们可以使用bcrypt来加密密码,最终以bcrypthash的形式保存到系统中,一个bcrypthash的格式如下:

$2b$[cost]$[22charactersalt][31characterhash]

比如:

$2a$10$\__//\____________________/\_____________________________/AlgCostSaltHash

上面例子中,$2a$表示的hash算法的唯一标志。这里表示的是bcrypt算法。

10表示的是代价因子,这里是2的10次方,也就是1024轮。

N9qo8uLOickgx2ZMRZoMye是16个字节(128bits)的salt经过base64编码得到的22长度的字符。

最后的是24个字节(192bits)的hash,经过bash64的编码得到的31长度的字符。

hash的历史

这种hash格式是遵循的是OpenBSD密码文件中存储密码时使用的MolarCryptFormat格式。最开始的时候格式定义是下面的:

$1$:MD5-basedcrypt('md5crypt')

$2$:Blowfish-basedcrypt('bcrypt')

$sha1$:SHA-1-basedcrypt('sha1crypt')

$5$:SHA-256-basedcrypt('sha256crypt')

$6$:SHA-512-basedcrypt('sha512crypt')

但是最初的规范没有定义如何处理非ASCII字符,也没有定义如何处理null终止符。修订后的规范规定,在hash字符串时:

String必须是UTF-8编码

必须包含null终止符

因为包含了这些改动,所以bcrypt的版本号被修改成了$2a$。

但是在2011年6月,因为PHP对bcypt的实现crypt_blowfish中的一个bug,他们建议系统管理员更新他们现有的密码数据库,用$2x$代替$2a$,以表明这些哈希值是坏的(需要使用旧的算法)。他们还建议让crypt_blowfish对新算法生成的哈希值使用头$2y$。当然这个改动只限于PHP的crypt_blowfish。

然后在2014年2月,在OpenBSD的bcrypt实现中也发现了一个bug,他们将字符串的长度存储在无符号char中(即8位Byte)。如果密码的长度超过255个字符,就会溢出来。

因为bcrypt是为OpenBSD创建的。所以当他们的库中出现了一个bug时,他们决定将版本号升级到$2b$。

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:“程序那些事”,懂技术,更懂你!

2. Linux入门之sha256sum指令详解

在Linux系统中,文件的完整性和数据的安全性是用户和系统管理员非常关心的问题。为了验证文件的完整性,Linux提供了一个强大的工具——sha256sum命令。这个命令可以生成一个文件的SHA-256哈希值,从而帮助用户确认文件是否被篡改过。本文将详细介绍sha256sum命令的使用方法和一些实用的场景。

什么是SHA-256哈希函数?SHA-256(Secure Hash Algorithm 256-bit)是一种加密哈希函数,属于SHA-2家族。它将任何字符串转换成一个固定长度(256位)的哈希值。SHA-256的特点是,即使是微小的数据变化也会导致生成的哈希值发生巨大的变化,这使得它非常适合用于数据完整性校验。

如何使用sha256sum命令?sha256sum命令的基本语法如下:

这里,[options]是可选的参数,[file...]是要计算哈希值的一个或多个文件。

基本使用:要计算一个文件的SHA-256哈希值,可以使用以下命令:

将filename替换为你想要计算哈希值的文件名。例如,如果有一个名为example.txt的文件,可以使用以下命令:

执行后,系统会输出example.txt文件的SHA-256哈希值。

计算多个文件的哈希值:如果要同时计算多个文件的哈希值,可以将文件名依次列出:

输出哈希值到文件:有时,我们可能需要将哈希值保存到一个文件中,而不是直接显示在终端上。可以使用重定向操作符>>来实现:

这样,file1.txt和file2.txt的哈希值就会被写入hash_values.txt文件中。

校验哈希值:除了生成哈希值,sha256sum还可以用于校验文件的哈希值是否与已知的哈希值相匹配。这可以通过在命令后添加--check(或-c)选项来实现:

如果hash_values.txt中列出的哈希值与实际文件的哈希值相匹配,命令会显示OK;如果有不匹配的,会显示相应的错误信息。

从哈希值文件中校验文件:如果有一个包含哈希值的文件(通常称为哈希值清单),可以使用以下命令来校验文件:

--status选项会让sha256sum在每个文件校验后显示OK或ERROR,而不是在所有文件校验完成后一次性显示。

显示帮助信息:如果需要获取更多关于sha256sum命令的信息,可以使用--help选项:

常见问题解答:Q: 如何加快sha256sum命令的执行速度?答案:可以通过--parallel选项来指定同时运行的线程数,从而加快计算速度。例如:

这会让sha256sum使用4个线程来计算哈希值。

Q: 如果文件很大,sha256sum命令会消耗很多资源吗?答案:sha256sum命令在计算哈希值时,其资源消耗相对较小。但是,如果文件非常大,可能会占用较多的CPU和内存资源。可以通过调整--parallel选项来优化资源使用。

Q:sha256sum命令可以用于加密文件吗?答案:不可以。sha256sum命令用于生成文件的哈希值,而不是加密文件。哈希函数是单向的,不能用来解密或还原原始数据。

结语:sha256sum命令是Linux系统中一个非常实用的工具,它可以帮助用户验证文件的完整性和一致性。通过本文的介绍,初学者应该能够快速掌握这个命令的使用方法,并在实际工作中有效地利用它来保护数据安全。记住,数据的完整性和安全性是至关重要的,而sha256sum正是维护这一关键要素的强大工具。

阅读全文

与linuxhash算法相关的资料

热点内容
单片机蜂鸣器生日快乐 浏览:298
在sqlserver服务器内获取客户端的ip地址 浏览:995
数码管显示的单片机c程序 浏览:790
linux挂载文件系统 浏览:895
linux挂载windows磁盘 浏览:193
ctea算法 浏览:32
命令可读可写 浏览:303
圈梁立柱立方计算法 浏览:365
单片机测量频率 浏览:854
江苏扬州服务器云主机 浏览:877
自动发卡源码模版 浏览:457
怎样将pdf转换成jpg 浏览:615
pdf51 浏览:917
单片机最小系统的功能 浏览:354
ssa的简便算法 浏览:284
java1m 浏览:806
之江汇app英语怎么激活 浏览:639
在线查找服务器地址 浏览:305
成都加密线最高时速 浏览:172
程序员私活没完成 浏览:717